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::LineCheckSlide(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 for (j = 0; j < TriangleNum; j++) {
87 intersecting = LineFacetd(p1, p2, &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]], &facenormals[j], &point);
88 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);
89 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
90 olddistance = distance;
91 firstintersecting = j;
95 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)));
96 *p2 -= facenormals[firstintersecting] * distance;
99 *p2 = DoRotation(*p2, 0, *rotate, 0);
101 return firstintersecting;
104 int Model::LineCheckPossible(XYZ *p1, XYZ *p2, XYZ *p, XYZ *move, float *rotate)
107 static float distance;
108 static float olddistance;
109 static int intersecting;
110 static int firstintersecting;
115 if (!sphere_line_intersection(p1, p2, &boundingspherecenter, &boundingsphereradius))
117 firstintersecting = -1;
119 *p1 = DoRotation(*p1, 0, -*rotate, 0);
121 *p2 = DoRotation(*p2, 0, -*rotate, 0);
123 if (numpossible > 0 && numpossible < TriangleNum)
124 for (j = 0; j < numpossible; j++) {
125 if (possible[j] >= 0 && possible[j] < TriangleNum) {
126 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);
127 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);
128 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
129 olddistance = distance;
130 firstintersecting = possible[j];
137 *p = DoRotation(*p, 0, *rotate, 0);
139 return firstintersecting;
142 int Model::LineCheckSlidePossible(XYZ *p1, XYZ *p2, XYZ *p, XYZ *move, float *rotate)
145 static float distance;
146 static float olddistance;
147 static int intersecting;
148 static int firstintersecting;
153 if (!sphere_line_intersection(p1, p2, &boundingspherecenter, &boundingsphereradius))
155 firstintersecting = -1;
157 *p1 = DoRotation(*p1, 0, -*rotate, 0);
159 *p2 = DoRotation(*p2, 0, -*rotate, 0);
162 for (j = 0; j < numpossible; j++) {
163 if (possible[j] >= 0 && possible[j] < TriangleNum) {
164 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);
165 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);
166 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
167 olddistance = distance;
168 firstintersecting = possible[j];
173 if (firstintersecting > 0) {
174 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)));
175 *p2 -= facenormals[firstintersecting] * distance;
179 *p2 = DoRotation(*p2, 0, *rotate, 0);
181 return firstintersecting;
184 int Model::SphereCheck(XYZ *p1, float radius, XYZ *p, XYZ *move, float *rotate)
187 static float distance;
188 static float olddistance;
189 static int intersecting;
190 static int firstintersecting;
193 static XYZ start, end;
195 firstintersecting = -1;
200 *p1 = DoRotation(*p1, 0, -*rotate, 0);
201 if (distsq(p1, &boundingspherecenter) > radius * radius + boundingsphereradius * boundingsphereradius)
204 for (i = 0; i < 4; i++) {
205 for (j = 0; j < TriangleNum; j++) {
207 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)));
208 if (distance < radius) {
209 point = *p1 - facenormals[j] * distance;
210 if (PointInTriangle( &point, facenormals[j], &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]]))
213 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], p1, &radius);
215 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]], p1, &radius);
217 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[2]], p1, &radius);
219 *p1 += facenormals[j] * (distance - radius);
223 if(LineFacetd(&start,&end,&vertex[Triangles[j].vertex[0]],&vertex[Triangles[j].vertex[1]],&vertex[Triangles[j].vertex[2]],&facenormals[j],&point)){
224 p1->y=point.y+radius;
228 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
229 olddistance = distance;
230 firstintersecting = j;
236 *p = DoRotation(*p, 0, *rotate, 0);
239 *p1 = DoRotation(*p1, 0, *rotate, 0);
241 return firstintersecting;
244 int Model::SphereCheckPossible(XYZ *p1, float radius, XYZ *move, float *rotate)
247 static float distance;
248 static float olddistance;
249 static int intersecting;
250 static int firstintersecting;
253 static XYZ start, end;
255 firstintersecting = -1;
263 *p1 = DoRotation(*p1, 0, -*rotate, 0);
264 if (distsq(p1, &boundingspherecenter) > radius * radius + boundingsphereradius * boundingsphereradius) {
269 for (j = 0; j < TriangleNum; j++) {
271 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)));
272 if (distance < radius) {
273 point = *p1 - facenormals[j] * distance;
274 if (PointInTriangle( &point, facenormals[j], &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]]))
277 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], p1, &radius);
279 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]], p1, &radius);
281 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[2]], p1, &radius);
283 //if(j>=0&&j<TriangleNum)
284 possible[numpossible] = j;
288 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
289 olddistance = distance;
290 firstintersecting = j;
294 *p1 = DoRotation(*p1, 0, *rotate, 0);
296 return firstintersecting;
300 void Model::UpdateVertexArray()
302 if (type != normaltype && type != decalstype)
307 for (i = 0; i < TriangleNum; i++) {
309 vArray[j + 0] = Triangles[i].gx[0];
310 vArray[j + 1] = Triangles[i].gy[0];
311 vArray[j + 2] = normals[Triangles[i].vertex[0]].x;
312 vArray[j + 3] = normals[Triangles[i].vertex[0]].y;
313 vArray[j + 4] = normals[Triangles[i].vertex[0]].z;
314 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
315 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
316 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
318 vArray[j + 8] = Triangles[i].gx[1];
319 vArray[j + 9] = Triangles[i].gy[1];
320 vArray[j + 10] = normals[Triangles[i].vertex[1]].x;
321 vArray[j + 11] = normals[Triangles[i].vertex[1]].y;
322 vArray[j + 12] = normals[Triangles[i].vertex[1]].z;
323 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
324 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
325 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
327 vArray[j + 16] = Triangles[i].gx[2];
328 vArray[j + 17] = Triangles[i].gy[2];
329 vArray[j + 18] = normals[Triangles[i].vertex[2]].x;
330 vArray[j + 19] = normals[Triangles[i].vertex[2]].y;
331 vArray[j + 20] = normals[Triangles[i].vertex[2]].z;
332 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
333 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
334 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
337 for (i = 0; i < TriangleNum; i++) {
339 vArray[j + 0] = Triangles[i].gx[0];
340 vArray[j + 1] = Triangles[i].gy[0];
341 vArray[j + 2] = facenormals[i].x * -1;
342 vArray[j + 3] = facenormals[i].y * -1;
343 vArray[j + 4] = facenormals[i].z * -1;
344 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
345 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
346 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
348 vArray[j + 8] = Triangles[i].gx[1];
349 vArray[j + 9] = Triangles[i].gy[1];
350 vArray[j + 10] = facenormals[i].x * -1;
351 vArray[j + 11] = facenormals[i].y * -1;
352 vArray[j + 12] = facenormals[i].z * -1;
353 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
354 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
355 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
357 vArray[j + 16] = Triangles[i].gx[2];
358 vArray[j + 17] = Triangles[i].gy[2];
359 vArray[j + 18] = facenormals[i].x * -1;
360 vArray[j + 19] = facenormals[i].y * -1;
361 vArray[j + 20] = facenormals[i].z * -1;
362 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
363 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
364 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
369 void Model::UpdateVertexArrayNoTex()
371 if (type != normaltype && type != decalstype)
376 for (i = 0; i < TriangleNum; i++) {
378 vArray[j + 2] = normals[Triangles[i].vertex[0]].x;
379 vArray[j + 3] = normals[Triangles[i].vertex[0]].y;
380 vArray[j + 4] = normals[Triangles[i].vertex[0]].z;
381 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
382 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
383 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
385 vArray[j + 10] = normals[Triangles[i].vertex[1]].x;
386 vArray[j + 11] = normals[Triangles[i].vertex[1]].y;
387 vArray[j + 12] = normals[Triangles[i].vertex[1]].z;
388 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
389 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
390 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
392 vArray[j + 18] = normals[Triangles[i].vertex[2]].x;
393 vArray[j + 19] = normals[Triangles[i].vertex[2]].y;
394 vArray[j + 20] = normals[Triangles[i].vertex[2]].z;
395 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
396 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
397 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
400 for (i = 0; i < TriangleNum; i++) {
402 vArray[j + 2] = facenormals[i].x * -1;
403 vArray[j + 3] = facenormals[i].y * -1;
404 vArray[j + 4] = facenormals[i].z * -1;
405 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
406 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
407 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
409 vArray[j + 10] = facenormals[i].x * -1;
410 vArray[j + 11] = facenormals[i].y * -1;
411 vArray[j + 12] = facenormals[i].z * -1;
412 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
413 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
414 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
416 vArray[j + 18] = facenormals[i].x * -1;
417 vArray[j + 19] = facenormals[i].y * -1;
418 vArray[j + 20] = facenormals[i].z * -1;
419 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
420 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
421 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
425 void Model::UpdateVertexArrayNoTexNoNorm()
427 if (type != normaltype && type != decalstype)
431 for (i = 0; i < TriangleNum; i++) {
433 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
434 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
435 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
437 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
438 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
439 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
441 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
442 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
443 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
447 bool Model::loadnotex(const char *filename )
452 //~ int oldvertexNum, oldTriangleNum;
453 //~ oldvertexNum = vertexNum;
454 //~ oldTriangleNum = TriangleNum;
459 tfile = fopen( ConvertFileName(filename), "rb" );
460 // read model settings
462 fseek(tfile, 0, SEEK_SET);
463 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
465 // read the model data
470 owner = (int*)malloc(sizeof(int) * vertexNum);
471 possible = (int*)malloc(sizeof(int) * TriangleNum);
472 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
473 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
474 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
476 for (i = 0; i < vertexNum; i++) {
477 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
480 for (i = 0; i < TriangleNum; i++) {
481 //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
483 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
484 Triangles[i].vertex[ 0] = vertex[ 0];
485 Triangles[i].vertex[ 1] = vertex[ 2];
486 Triangles[i].vertex[ 2] = vertex[ 4];
487 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
488 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
495 for (i = 0; i < vertexNum; i++) {
500 boundingsphereradius = 0;
501 for (i = 0; i < vertexNum; i++) {
502 for (j = 0; j < vertexNum; j++) {
503 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
504 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
505 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
509 boundingsphereradius = fast_sqrt(boundingsphereradius);
515 bool Model::load(const char *filename, bool texture )
522 LOG(std::string("Loading model...") + filename);
525 Game::LoadingScreen();
527 //~ int oldvertexNum, oldTriangleNum;
528 //~ oldvertexNum = vertexNum;
529 //~ oldTriangleNum = TriangleNum;
534 tfile = fopen( ConvertFileName(filename), "rb" );
535 // read model settings
538 fseek(tfile, 0, SEEK_SET);
539 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
541 // read the model data
546 owner = (int*)malloc(sizeof(int) * vertexNum);
547 possible = (int*)malloc(sizeof(int) * TriangleNum);
548 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
549 normals = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
550 facenormals = (XYZ*)malloc(sizeof(XYZ) * TriangleNum);
551 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
552 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
554 for (i = 0; i < vertexNum; i++) {
555 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
558 for (i = 0; i < TriangleNum; i++) {
559 //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
561 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
562 Triangles[i].vertex[ 0] = vertex[ 0];
563 Triangles[i].vertex[ 1] = vertex[ 2];
564 Triangles[i].vertex[ 2] = vertex[ 4];
565 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
566 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
569 modelTexture.xsz = 0;
575 for (i = 0; i < vertexNum; i++) {
580 boundingsphereradius = 0;
581 for (i = 0; i < vertexNum; i++) {
582 for (j = 0; j < vertexNum; j++) {
583 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
584 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
585 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
589 boundingsphereradius = fast_sqrt(boundingsphereradius);
594 bool Model::loaddecal(const char *filename, bool texture )
601 // Changing the filename so that its more os specific
602 char * FixedFN = ConvertFileName(filename);
604 LOG(std::string("Loading decal...") + FixedFN);
606 //~ int oldvertexNum, oldTriangleNum;
607 //~ oldvertexNum = vertexNum;
608 //~ oldTriangleNum = TriangleNum;
614 tfile = fopen( FixedFN, "rb" );
615 // read model settings
618 fseek(tfile, 0, SEEK_SET);
619 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
621 // read the model data
627 owner = (int*)malloc(sizeof(int) * vertexNum);
628 possible = (int*)malloc(sizeof(int) * TriangleNum);
629 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
630 normals = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
631 facenormals = (XYZ*)malloc(sizeof(XYZ) * TriangleNum);
632 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
633 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
636 for (i = 0; i < vertexNum; i++) {
637 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
640 for (i = 0; i < TriangleNum; i++) {
641 //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
643 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
644 Triangles[i].vertex[ 0] = vertex[ 0];
645 Triangles[i].vertex[ 1] = vertex[ 2];
646 Triangles[i].vertex[ 2] = vertex[ 4];
647 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
648 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
652 modelTexture.xsz = 0;
658 for (i = 0; i < vertexNum; i++) {
662 boundingsphereradius = 0;
663 for (i = 0; i < vertexNum; i++) {
664 for (j = 0; j < vertexNum; j++) {
665 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
666 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
667 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
671 boundingsphereradius = fast_sqrt(boundingsphereradius);
674 if (!decaltexcoords) {
675 decaltexcoords = (float***)malloc(sizeof(float**)*max_model_decals);
676 for (i = 0; i < max_model_decals; i++) {
677 decaltexcoords[i] = (float**)malloc(sizeof(float*) * 3);
678 for (j = 0; j < 3; j++) {
679 decaltexcoords[i][j] = (float*)malloc(sizeof(float) * 2);
682 //if(decalvertex)free(decalvertex);
683 decalvertex = (XYZ**)malloc(sizeof(XYZ*)*max_model_decals);
684 for (i = 0; i < max_model_decals; i++) {
685 decalvertex[i] = (XYZ*)malloc(sizeof(XYZ) * 3);
688 decaltype = (int*)malloc(sizeof(int) * max_model_decals);
689 decalopacity = (float*)malloc(sizeof(float) * max_model_decals);
690 decalrotation = (float*)malloc(sizeof(float) * max_model_decals);
691 decalalivetime = (float*)malloc(sizeof(float) * max_model_decals);
692 decalposition = (XYZ*)malloc(sizeof(XYZ) * max_model_decals);
698 bool Model::loadraw(char *filename )
705 LOG(std::string("Loading raw...") + filename);
707 //~ int oldvertexNum, oldTriangleNum;
708 //~ oldvertexNum = vertexNum;
709 //~ oldTriangleNum = TriangleNum;
714 tfile = fopen( ConvertFileName(filename), "rb" );
715 // read model settings
718 fseek(tfile, 0, SEEK_SET);
719 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
721 // read the model data
726 owner = (int*)malloc(sizeof(int) * vertexNum);
727 possible = (int*)malloc(sizeof(int) * TriangleNum);
728 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
729 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
730 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
733 for (i = 0; i < vertexNum; i++) {
734 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
737 for (i = 0; i < TriangleNum; i++) {
738 //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
740 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
741 Triangles[i].vertex[ 0] = vertex[ 0];
742 Triangles[i].vertex[ 1] = vertex[ 2];
743 Triangles[i].vertex[ 2] = vertex[ 4];
744 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
745 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
751 for (i = 0; i < vertexNum; i++) {
759 void Model::UniformTexCoords()
762 for (i = 0; i < TriangleNum; i++) {
763 Triangles[i].gy[0] = vertex[Triangles[i].vertex[0]].y;
764 Triangles[i].gy[1] = vertex[Triangles[i].vertex[1]].y;
765 Triangles[i].gy[2] = vertex[Triangles[i].vertex[2]].y;
766 Triangles[i].gx[0] = vertex[Triangles[i].vertex[0]].x;
767 Triangles[i].gx[1] = vertex[Triangles[i].vertex[1]].x;
768 Triangles[i].gx[2] = vertex[Triangles[i].vertex[2]].x;
774 void Model::FlipTexCoords()
777 for (i = 0; i < TriangleNum; i++) {
778 Triangles[i].gy[0] = -Triangles[i].gy[0];
779 Triangles[i].gy[1] = -Triangles[i].gy[1];
780 Triangles[i].gy[2] = -Triangles[i].gy[2];
785 void Model::ScaleTexCoords(float howmuch)
788 for (i = 0; i < TriangleNum; i++) {
789 Triangles[i].gx[0] *= howmuch;
790 Triangles[i].gx[1] *= howmuch;
791 Triangles[i].gx[2] *= howmuch;
792 Triangles[i].gy[0] *= howmuch;
793 Triangles[i].gy[1] *= howmuch;
794 Triangles[i].gy[2] *= howmuch;
799 void Model::Scale(float xscale, float yscale, float zscale)
802 for (i = 0; i < vertexNum; i++) {
803 vertex[i].x *= xscale;
804 vertex[i].y *= yscale;
805 vertex[i].z *= zscale;
811 boundingsphereradius = 0;
812 for (i = 0; i < vertexNum; i++) {
813 for (j = 0; j < vertexNum; j++) {
814 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
815 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
816 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
820 boundingsphereradius = fast_sqrt(boundingsphereradius);
823 void Model::ScaleNormals(float xscale, float yscale, float zscale)
825 if (type != normaltype && type != decalstype)
828 for (i = 0; i < vertexNum; i++) {
829 normals[i].x *= xscale;
830 normals[i].y *= yscale;
831 normals[i].z *= zscale;
833 for (i = 0; i < TriangleNum; i++) {
834 facenormals[i].x *= xscale;
835 facenormals[i].y *= yscale;
836 facenormals[i].z *= zscale;
841 void Model::Translate(float xtrans, float ytrans, float ztrans)
844 for (i = 0; i < vertexNum; i++) {
845 vertex[i].x += xtrans;
846 vertex[i].y += ytrans;
847 vertex[i].z += ztrans;
852 boundingsphereradius = 0;
853 for (i = 0; i < vertexNum; i++) {
854 for (j = 0; j < vertexNum; j++) {
855 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
856 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
857 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
861 boundingsphereradius = fast_sqrt(boundingsphereradius);
864 void Model::Rotate(float xang, float yang, float zang)
867 for (i = 0; i < vertexNum; i++) {
868 vertex[i] = DoRotation(vertex[i], xang, yang, zang);
873 boundingsphereradius = 0;
874 for (i = 0; i < vertexNum; i++) {
875 for (j = 0; j < vertexNum; j++) {
876 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
877 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
878 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
882 boundingsphereradius = fast_sqrt(boundingsphereradius);
886 void Model::CalculateNormals(bool facenormalise)
889 Game::LoadingScreen();
891 if (type != normaltype && type != decalstype)
894 for (i = 0; i < vertexNum; i++) {
900 for (i = 0; i < TriangleNum; i++) {
901 CrossProduct(vertex[Triangles[i].vertex[1]] - vertex[Triangles[i].vertex[0]], vertex[Triangles[i].vertex[2]] - vertex[Triangles[i].vertex[0]], &facenormals[i]);
903 normals[Triangles[i].vertex[0]].x += facenormals[i].x;
904 normals[Triangles[i].vertex[0]].y += facenormals[i].y;
905 normals[Triangles[i].vertex[0]].z += facenormals[i].z;
907 normals[Triangles[i].vertex[1]].x += facenormals[i].x;
908 normals[Triangles[i].vertex[1]].y += facenormals[i].y;
909 normals[Triangles[i].vertex[1]].z += facenormals[i].z;
911 normals[Triangles[i].vertex[2]].x += facenormals[i].x;
912 normals[Triangles[i].vertex[2]].y += facenormals[i].y;
913 normals[Triangles[i].vertex[2]].z += facenormals[i].z;
915 Normalise(&facenormals[i]);
917 for (i = 0; i < vertexNum; i++) {
918 Normalise(&normals[i]);
921 UpdateVertexArrayNoTex();
924 void Model::drawimmediate()
927 glBegin(GL_TRIANGLES);
928 for (int i = 0; i < TriangleNum; i++) {
929 /*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){
930 if(isnormal(vertex[Triangles[i].vertex[0]].x)&&isnormal(vertex[Triangles[i].vertex[0]].y)&&isnormal(vertex[Triangles[i].vertex[0]].z)
931 &&isnormal(vertex[Triangles[i].vertex[1]].x)&&isnormal(vertex[Triangles[i].vertex[1]].y)&&isnormal(vertex[Triangles[i].vertex[1]].z)
932 &&isnormal(vertex[Triangles[i].vertex[2]].x)&&isnormal(vertex[Triangles[i].vertex[2]].y)&&isnormal(vertex[Triangles[i].vertex[2]].z)){
934 glTexCoord2f(Triangles[i].gx[0], Triangles[i].gy[0]);
936 glColor3f(normals[Triangles[i].vertex[0]].x, normals[Triangles[i].vertex[0]].y, normals[Triangles[i].vertex[0]].z);
938 glNormal3f(normals[Triangles[i].vertex[0]].x, normals[Triangles[i].vertex[0]].y, normals[Triangles[i].vertex[0]].z);
940 glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
941 glVertex3f(vertex[Triangles[i].vertex[0]].x, vertex[Triangles[i].vertex[0]].y, vertex[Triangles[i].vertex[0]].z);
943 glTexCoord2f(Triangles[i].gx[1], Triangles[i].gy[1]);
945 glColor3f(normals[Triangles[i].vertex[1]].x, normals[Triangles[i].vertex[1]].y, normals[Triangles[i].vertex[1]].z);
947 glNormal3f(normals[Triangles[i].vertex[1]].x, normals[Triangles[i].vertex[1]].y, normals[Triangles[i].vertex[1]].z);
949 glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
950 glVertex3f(vertex[Triangles[i].vertex[1]].x, vertex[Triangles[i].vertex[1]].y, vertex[Triangles[i].vertex[1]].z);
952 glTexCoord2f(Triangles[i].gx[2], Triangles[i].gy[2]);
954 glColor3f(normals[Triangles[i].vertex[2]].x, normals[Triangles[i].vertex[2]].y, normals[Triangles[i].vertex[2]].z);
956 glNormal3f(normals[Triangles[i].vertex[2]].x, normals[Triangles[i].vertex[2]].y, normals[Triangles[i].vertex[2]].z);
958 glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
959 glVertex3f(vertex[Triangles[i].vertex[2]].x, vertex[Triangles[i].vertex[2]].y, vertex[Triangles[i].vertex[2]].z);
968 if (type != normaltype && type != decalstype)
971 glEnableClientState(GL_NORMAL_ARRAY);
972 glEnableClientState(GL_VERTEX_ARRAY);
973 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
976 glInterleavedArrays( GL_T2F_N3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
978 glInterleavedArrays( GL_T2F_C3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
982 glLockArraysEXT( 0, TriangleNum * 3);
984 glDrawArrays(GL_TRIANGLES, 0, TriangleNum * 3);
991 glDisableClientState(GL_NORMAL_ARRAY);
993 glDisableClientState(GL_COLOR_ARRAY);
994 glDisableClientState(GL_VERTEX_ARRAY);
995 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
999 //TODO: phase out in favor of Texture
1000 void Model::drawdifftex(GLuint texture)
1002 glEnableClientState(GL_NORMAL_ARRAY);
1003 glEnableClientState(GL_VERTEX_ARRAY);
1004 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1006 glInterleavedArrays( GL_T2F_N3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
1008 glInterleavedArrays( GL_T2F_C3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
1010 glBindTexture(GL_TEXTURE_2D, (unsigned long)texture);
1011 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
1012 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
1016 glLockArraysEXT( 0, TriangleNum * 3);
1018 glDrawArrays(GL_TRIANGLES, 0, TriangleNum * 3);
1020 glUnlockArraysEXT();
1025 glDisableClientState(GL_NORMAL_ARRAY);
1027 glDisableClientState(GL_COLOR_ARRAY);
1028 glDisableClientState(GL_VERTEX_ARRAY);
1029 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1030 //drawdiffteximmediate(texture);
1033 void Model::drawdifftex(Texture texture)
1035 glEnableClientState(GL_NORMAL_ARRAY);
1036 glEnableClientState(GL_VERTEX_ARRAY);
1037 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1039 glInterleavedArrays( GL_T2F_N3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
1041 glInterleavedArrays( GL_T2F_C3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
1044 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
1045 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
1049 glLockArraysEXT( 0, TriangleNum * 3);
1051 glDrawArrays(GL_TRIANGLES, 0, TriangleNum * 3);
1053 glUnlockArraysEXT();
1058 glDisableClientState(GL_NORMAL_ARRAY);
1060 glDisableClientState(GL_COLOR_ARRAY);
1061 glDisableClientState(GL_VERTEX_ARRAY);
1062 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1063 //drawdiffteximmediate(texture);
1066 void Model::drawdiffteximmediate(GLuint texture)
1068 glBindTexture(GL_TEXTURE_2D, (unsigned long)texture);
1070 glBegin(GL_TRIANGLES);
1071 for (int i = 0; i < TriangleNum; i++) {
1072 /*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){
1073 if(isnormal(vertex[Triangles[i].vertex[0]].x)&&isnormal(vertex[Triangles[i].vertex[0]].y)&&isnormal(vertex[Triangles[i].vertex[0]].z)
1074 &&isnormal(vertex[Triangles[i].vertex[1]].x)&&isnormal(vertex[Triangles[i].vertex[1]].y)&&isnormal(vertex[Triangles[i].vertex[1]].z)
1075 &&isnormal(vertex[Triangles[i].vertex[2]].x)&&isnormal(vertex[Triangles[i].vertex[2]].y)&&isnormal(vertex[Triangles[i].vertex[2]].z)){
1076 */glTexCoord2f(Triangles[i].gx[0], Triangles[i].gy[0]);
1078 glColor3f(normals[Triangles[i].vertex[0]].x, normals[Triangles[i].vertex[0]].y, normals[Triangles[i].vertex[0]].z);
1079 if (!color && !flat)
1080 glNormal3f(normals[Triangles[i].vertex[0]].x, normals[Triangles[i].vertex[0]].y, normals[Triangles[i].vertex[0]].z);
1082 glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
1083 glVertex3f(vertex[Triangles[i].vertex[0]].x, vertex[Triangles[i].vertex[0]].y, vertex[Triangles[i].vertex[0]].z);
1085 glTexCoord2f(Triangles[i].gx[1], Triangles[i].gy[1]);
1087 glColor3f(normals[Triangles[i].vertex[1]].x, normals[Triangles[i].vertex[1]].y, normals[Triangles[i].vertex[1]].z);
1088 if (!color && !flat)
1089 glNormal3f(normals[Triangles[i].vertex[1]].x, normals[Triangles[i].vertex[1]].y, normals[Triangles[i].vertex[1]].z);
1091 glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
1092 glVertex3f(vertex[Triangles[i].vertex[1]].x, vertex[Triangles[i].vertex[1]].y, vertex[Triangles[i].vertex[1]].z);
1094 glTexCoord2f(Triangles[i].gx[2], Triangles[i].gy[2]);
1096 glColor3f(normals[Triangles[i].vertex[2]].x, normals[Triangles[i].vertex[2]].y, normals[Triangles[i].vertex[2]].z);
1097 if (!color && !flat)
1098 glNormal3f(normals[Triangles[i].vertex[2]].x, normals[Triangles[i].vertex[2]].y, normals[Triangles[i].vertex[2]].z);
1100 glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
1101 glVertex3f(vertex[Triangles[i].vertex[2]].x, vertex[Triangles[i].vertex[2]].y, vertex[Triangles[i].vertex[2]].z);
1108 void Model::drawdecals(Texture shadowtexture, Texture bloodtexture, Texture bloodtexture2, Texture breaktexture)
1111 if (type != decalstype)
1114 //~ static float distancemult;
1115 static int lasttype;
1116 //~ static float viewdistsquared;
1119 //~ viewdistsquared = viewdistance * viewdistance;
1124 glDisable(GL_LIGHTING);
1125 glDisable(GL_CULL_FACE);
1126 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1128 if (numdecals > max_model_decals)
1129 numdecals = max_model_decals;
1130 for (i = 0; i < numdecals; i++) {
1131 if (decaltype[i] == blooddecalfast && decalalivetime[i] < 2)
1132 decalalivetime[i] = 2;
1134 if (decaltype[i] == shadowdecal && decaltype[i] != lasttype) {
1135 shadowtexture.bind();
1138 glAlphaFunc(GL_GREATER, 0.0001);
1139 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1142 if (decaltype[i] == breakdecal && decaltype[i] != lasttype) {
1143 breaktexture.bind();
1146 glAlphaFunc(GL_GREATER, 0.0001);
1147 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1150 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalslow) && decaltype[i] != lasttype) {
1151 bloodtexture.bind();
1154 glAlphaFunc(GL_GREATER, 0.15);
1155 glBlendFunc(GL_ONE, GL_ZERO);
1158 if ((decaltype[i] == blooddecalfast) && decaltype[i] != lasttype) {
1159 bloodtexture2.bind();
1162 glAlphaFunc(GL_GREATER, 0.15);
1163 glBlendFunc(GL_ONE, GL_ZERO);
1166 if (decaltype[i] == shadowdecal) {
1167 glColor4f(1, 1, 1, decalopacity[i]);
1169 if (decaltype[i] == breakdecal) {
1170 glColor4f(1, 1, 1, decalopacity[i]);
1171 if (decalalivetime[i] > 58)
1172 glColor4f(1, 1, 1, decalopacity[i] * (60 - decalalivetime[i]) / 2);
1174 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow)) {
1175 glColor4f(1, 1, 1, decalopacity[i]);
1176 if (decalalivetime[i] < 4)
1177 glColor4f(1, 1, 1, decalopacity[i]*decalalivetime[i]*.25);
1178 if (decalalivetime[i] > 58)
1179 glColor4f(1, 1, 1, decalopacity[i] * (60 - decalalivetime[i]) / 2);
1181 lasttype = decaltype[i];
1182 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1183 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1185 glMatrixMode(GL_MODELVIEW);
1187 glBegin(GL_TRIANGLES);
1188 for (int j = 0; j < 3; j++) {
1189 glTexCoord2f(decaltexcoords[i][j][0], decaltexcoords[i][j][1]);
1190 glVertex3f(decalvertex[i][j].x, decalvertex[i][j].y, decalvertex[i][j].z);
1195 for (i = numdecals - 1; i >= 0; i--) {
1196 decalalivetime[i] += multiplier;
1197 if (decaltype[i] == blooddecalslow)
1198 decalalivetime[i] -= multiplier * 2 / 3;
1199 if (decaltype[i] == blooddecalfast)
1200 decalalivetime[i] += multiplier * 4;
1201 if (decaltype[i] == shadowdecal)
1203 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow) && decalalivetime[i] >= 60)
1206 glAlphaFunc(GL_GREATER, 0.0001);
1207 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1211 void Model::DeleteDecal(int which)
1214 if (type != decalstype)
1216 decaltype[which] = decaltype[numdecals - 1];
1217 decalposition[which] = decalposition[numdecals - 1];
1218 for (int i = 0; i < 3; i++) {
1219 decalvertex[which][i] = decalvertex[numdecals - 1][i];
1220 decaltexcoords[which][i][0] = decaltexcoords[numdecals - 1][i][0];
1221 decaltexcoords[which][i][1] = decaltexcoords[numdecals - 1][i][1];
1223 decalrotation[which] = decalrotation[numdecals - 1];
1224 decalalivetime[which] = decalalivetime[numdecals - 1];
1225 decalopacity[which] = decalopacity[numdecals - 1];
1230 void Model::MakeDecal(int atype, XYZ *where, float *size, float *opacity, float *rotation)
1233 if (type != decalstype)
1236 static float placex, placez;
1238 //static XYZ point,point1,point2;
1239 static float distance;
1243 if (distsq(where, &boundingspherecenter) < (boundingsphereradius + *size) * (boundingsphereradius + *size))
1244 for (i = 0; i < TriangleNum; i++) {
1245 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)) {
1246 decalposition[numdecals] = *where;
1247 decaltype[numdecals] = atype;
1248 decalrotation[numdecals] = *rotation;
1249 decalalivetime[numdecals] = 0;
1250 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);
1251 decalopacity[numdecals] = *opacity - distance / 10;
1253 if (decalopacity[numdecals > 0]) {
1254 placex = vertex[Triangles[i].vertex[0]].x;
1255 placez = vertex[Triangles[i].vertex[0]].z;
1257 decaltexcoords[numdecals][0][0] = (placex - where->x) / (*size) / 2 + .5;
1258 decaltexcoords[numdecals][0][1] = (placez - where->z) / (*size) / 2 + .5;
1260 decalvertex[numdecals][0].x = placex;
1261 decalvertex[numdecals][0].z = placez;
1262 decalvertex[numdecals][0].y = vertex[Triangles[i].vertex[0]].y;
1265 placex = vertex[Triangles[i].vertex[1]].x;
1266 placez = vertex[Triangles[i].vertex[1]].z;
1268 decaltexcoords[numdecals][1][0] = (placex - where->x) / (*size) / 2 + .5;
1269 decaltexcoords[numdecals][1][1] = (placez - where->z) / (*size) / 2 + .5;
1271 decalvertex[numdecals][1].x = placex;
1272 decalvertex[numdecals][1].z = placez;
1273 decalvertex[numdecals][1].y = vertex[Triangles[i].vertex[1]].y;
1276 placex = vertex[Triangles[i].vertex[2]].x;
1277 placez = vertex[Triangles[i].vertex[2]].z;
1279 decaltexcoords[numdecals][2][0] = (placex - where->x) / (*size) / 2 + .5;
1280 decaltexcoords[numdecals][2][1] = (placez - where->z) / (*size) / 2 + .5;
1282 decalvertex[numdecals][2].x = placex;
1283 decalvertex[numdecals][2].z = placez;
1284 decalvertex[numdecals][2].y = vertex[Triangles[i].vertex[2]].y;
1286 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1287 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1288 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1289 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1290 if (decalrotation[numdecals]) {
1291 for (j = 0; j < 3; j++) {
1293 rot.x = decaltexcoords[numdecals][j][0] - .5;
1294 rot.z = decaltexcoords[numdecals][j][1] - .5;
1295 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1296 decaltexcoords[numdecals][j][0] = rot.x + .5;
1297 decaltexcoords[numdecals][j][1] = rot.z + .5;
1300 if (numdecals < max_model_decals - 1)
1309 void Model::MakeDecal(int atype, XYZ where, float size, float opacity, float rotation)
1312 if (type != decalstype)
1315 static float placex, placez;
1317 //static XYZ point,point1,point2;
1318 static float distance;
1322 if (distsq(&where, &boundingspherecenter) < (boundingsphereradius + size) * (boundingsphereradius + size))
1323 for (i = 0; i < TriangleNum; i++) {
1324 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))));
1325 if (distance < .02 && abs(facenormals[i].y) > abs(facenormals[i].x) && abs(facenormals[i].y) > abs(facenormals[i].z)) {
1326 decalposition[numdecals] = where;
1327 decaltype[numdecals] = atype;
1328 decalrotation[numdecals] = rotation;
1329 decalalivetime[numdecals] = 0;
1330 decalopacity[numdecals] = opacity - distance / 10;
1332 if (decalopacity[numdecals > 0]) {
1333 placex = vertex[Triangles[i].vertex[0]].x;
1334 placez = vertex[Triangles[i].vertex[0]].z;
1336 decaltexcoords[numdecals][0][0] = (placex - where.x) / (size) / 2 + .5;
1337 decaltexcoords[numdecals][0][1] = (placez - where.z) / (size) / 2 + .5;
1339 decalvertex[numdecals][0].x = placex;
1340 decalvertex[numdecals][0].z = placez;
1341 decalvertex[numdecals][0].y = vertex[Triangles[i].vertex[0]].y;
1344 placex = vertex[Triangles[i].vertex[1]].x;
1345 placez = vertex[Triangles[i].vertex[1]].z;
1347 decaltexcoords[numdecals][1][0] = (placex - where.x) / (size) / 2 + .5;
1348 decaltexcoords[numdecals][1][1] = (placez - where.z) / (size) / 2 + .5;
1350 decalvertex[numdecals][1].x = placex;
1351 decalvertex[numdecals][1].z = placez;
1352 decalvertex[numdecals][1].y = vertex[Triangles[i].vertex[1]].y;
1355 placex = vertex[Triangles[i].vertex[2]].x;
1356 placez = vertex[Triangles[i].vertex[2]].z;
1358 decaltexcoords[numdecals][2][0] = (placex - where.x) / (size) / 2 + .5;
1359 decaltexcoords[numdecals][2][1] = (placez - where.z) / (size) / 2 + .5;
1361 decalvertex[numdecals][2].x = placex;
1362 decalvertex[numdecals][2].z = placez;
1363 decalvertex[numdecals][2].y = vertex[Triangles[i].vertex[2]].y;
1365 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1366 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1367 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1368 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1369 if (decalrotation[numdecals]) {
1370 for (j = 0; j < 3; j++) {
1372 rot.x = decaltexcoords[numdecals][j][0] - .5;
1373 rot.z = decaltexcoords[numdecals][j][1] - .5;
1374 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1375 decaltexcoords[numdecals][j][0] = rot.x + .5;
1376 decaltexcoords[numdecals][j][1] = rot.z + .5;
1379 if (numdecals < max_model_decals - 1)
1383 } else if (distance < .02 && abs(facenormals[i].x) > abs(facenormals[i].y) && abs(facenormals[i].x) > abs(facenormals[i].z)) {
1384 decalposition[numdecals] = where;
1385 decaltype[numdecals] = atype;
1386 decalrotation[numdecals] = rotation;
1387 decalalivetime[numdecals] = 0;
1388 decalopacity[numdecals] = opacity - distance / 10;
1390 if (decalopacity[numdecals > 0]) {
1391 placex = vertex[Triangles[i].vertex[0]].y;
1392 placez = vertex[Triangles[i].vertex[0]].z;
1394 decaltexcoords[numdecals][0][0] = (placex - where.y) / (size) / 2 + .5;
1395 decaltexcoords[numdecals][0][1] = (placez - where.z) / (size) / 2 + .5;
1397 decalvertex[numdecals][0].x = vertex[Triangles[i].vertex[0]].x;
1398 decalvertex[numdecals][0].z = placez;
1399 decalvertex[numdecals][0].y = placex;
1402 placex = vertex[Triangles[i].vertex[1]].y;
1403 placez = vertex[Triangles[i].vertex[1]].z;
1405 decaltexcoords[numdecals][1][0] = (placex - where.y) / (size) / 2 + .5;
1406 decaltexcoords[numdecals][1][1] = (placez - where.z) / (size) / 2 + .5;
1408 decalvertex[numdecals][1].x = vertex[Triangles[i].vertex[1]].x;
1409 decalvertex[numdecals][1].z = placez;
1410 decalvertex[numdecals][1].y = placex;
1413 placex = vertex[Triangles[i].vertex[2]].y;
1414 placez = vertex[Triangles[i].vertex[2]].z;
1416 decaltexcoords[numdecals][2][0] = (placex - where.y) / (size) / 2 + .5;
1417 decaltexcoords[numdecals][2][1] = (placez - where.z) / (size) / 2 + .5;
1419 decalvertex[numdecals][2].x = vertex[Triangles[i].vertex[2]].x;
1420 decalvertex[numdecals][2].z = placez;
1421 decalvertex[numdecals][2].y = placex;
1423 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1424 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1425 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1426 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1427 if (decalrotation[numdecals]) {
1428 for (j = 0; j < 3; j++) {
1430 rot.x = decaltexcoords[numdecals][j][0] - .5;
1431 rot.z = decaltexcoords[numdecals][j][1] - .5;
1432 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1433 decaltexcoords[numdecals][j][0] = rot.x + .5;
1434 decaltexcoords[numdecals][j][1] = rot.z + .5;
1437 if (numdecals < max_model_decals - 1)
1441 } else if (distance < .02 && abs(facenormals[i].z) > abs(facenormals[i].y) && abs(facenormals[i].z) > abs(facenormals[i].x)) {
1442 decalposition[numdecals] = where;
1443 decaltype[numdecals] = atype;
1444 decalrotation[numdecals] = rotation;
1445 decalalivetime[numdecals] = 0;
1446 decalopacity[numdecals] = opacity - distance / 10;
1448 if (decalopacity[numdecals > 0]) {
1449 placex = vertex[Triangles[i].vertex[0]].x;
1450 placez = vertex[Triangles[i].vertex[0]].y;
1452 decaltexcoords[numdecals][0][0] = (placex - where.x) / (size) / 2 + .5;
1453 decaltexcoords[numdecals][0][1] = (placez - where.y) / (size) / 2 + .5;
1455 decalvertex[numdecals][0].x = placex;
1456 decalvertex[numdecals][0].z = vertex[Triangles[i].vertex[0]].z;
1457 decalvertex[numdecals][0].y = placez;
1460 placex = vertex[Triangles[i].vertex[1]].x;
1461 placez = vertex[Triangles[i].vertex[1]].y;
1463 decaltexcoords[numdecals][1][0] = (placex - where.x) / (size) / 2 + .5;
1464 decaltexcoords[numdecals][1][1] = (placez - where.y) / (size) / 2 + .5;
1466 decalvertex[numdecals][1].x = placex;
1467 decalvertex[numdecals][1].z = vertex[Triangles[i].vertex[1]].z;
1468 decalvertex[numdecals][1].y = placez;
1471 placex = vertex[Triangles[i].vertex[2]].x;
1472 placez = vertex[Triangles[i].vertex[2]].y;
1474 decaltexcoords[numdecals][2][0] = (placex - where.x) / (size) / 2 + .5;
1475 decaltexcoords[numdecals][2][1] = (placez - where.y) / (size) / 2 + .5;
1477 decalvertex[numdecals][2].x = placex;
1478 decalvertex[numdecals][2].z = vertex[Triangles[i].vertex[2]].z;
1479 decalvertex[numdecals][2].y = placez;
1481 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1482 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1483 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1484 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1485 if (decalrotation[numdecals]) {
1486 for (j = 0; j < 3; j++) {
1488 rot.x = decaltexcoords[numdecals][j][0] - .5;
1489 rot.z = decaltexcoords[numdecals][j][1] - .5;
1490 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1491 decaltexcoords[numdecals][j][0] = rot.x + .5;
1492 decaltexcoords[numdecals][j][1] = rot.z + .5;
1495 if (numdecals < max_model_decals - 1)
1507 textureptr.destroy();
1510 void Model::deallocate()
1544 if (decaltexcoords) {
1545 for (i = 0; i < max_model_decals; i++) {
1546 for (j = 0; j < 3; j++) {
1547 free(decaltexcoords[i][j]);
1549 free(decaltexcoords[i]);
1551 free(decaltexcoords);
1557 for (i = 0; i < max_model_decals; i++) {
1558 free(decalvertex[i]);
1571 free(decalrotation);
1574 free(decalalivetime);
1577 free(decalposition);
1584 vertexNum = 0, TriangleNum = 0;
1587 type = 0, oldtype = 0;
1597 memset(&modelTexture, 0, sizeof(modelTexture));
1601 boundingspherecenter = 0;
1602 boundingsphereradius = 0;