2 Copyright (C) 2003, 2010 - Wolfire Games
3 Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file)
5 This file is part of Lugaru.
7 Lugaru is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 Lugaru is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Lugaru. If not, see <http://www.gnu.org/licenses/>.
25 extern float viewdistance;
26 extern float fadestart;
27 extern int environment;
28 extern float texscale;
30 extern float multiplier;
31 extern FRUSTUM frustum;
32 extern float texdetail;
35 extern float blurness;
36 extern float targetblurness;
37 extern Objects objects;
38 extern bool visibleloading;
39 extern bool skyboxtexture;
40 extern int tutoriallevel;
44 int Terrain::lineTerrain(XYZ p1, XYZ p2, XYZ *p)
47 static float distance;
48 static float olddistance;
49 static int intersecting;
50 static int firstintersecting;
52 static int startx, starty;
53 static int endx, endy;
54 static float highest, lowest;
56 firstintersecting = -1;
90 for (i = startx; i <= endx; i++) {
91 for (j = starty; j <= endy; j++) {
94 for (k = 0; k < 2; k++) {
95 if (heightmap[i + k][j] > highest)
96 highest = heightmap[i + k][j];
97 if (heightmap[i + k][j] < lowest)
98 lowest = heightmap[i + k][j];
99 if (heightmap[i + k][j + 1] > highest)
100 highest = heightmap[i + k][j + 1];
101 if (heightmap[i + k][j + 1] < lowest)
102 lowest = heightmap[i + k][j + 1];
104 if ((p1.y <= highest || p2.y <= highest) && (p1.y >= lowest || p2.y >= lowest)) {
106 triangles[0].y = heightmap[i][j];
110 triangles[1].y = heightmap[i][j + 1];
111 triangles[1].z = j + 1;
113 triangles[2].x = i + 1;
114 triangles[2].y = heightmap[i + 1][j];
117 intersecting = LineFacet(p1, p2, triangles[0], triangles[1], triangles[2], &point);
118 distance = distsq(&p1, &point);
119 if ((distance < olddistance || firstintersecting == -1) && intersecting == 1) {
120 olddistance = distance;
121 firstintersecting = 1;
125 triangles[0].x = i + 1;
126 triangles[0].y = heightmap[i + 1][j];
130 triangles[1].y = heightmap[i][j + 1];
131 triangles[1].z = j + 1;
133 triangles[2].x = i + 1;
134 triangles[2].y = heightmap[i + 1][j + 1];
135 triangles[2].z = j + 1;
137 intersecting = LineFacet(p1, p2, triangles[0], triangles[1], triangles[2], &point);
138 distance = distsq(&p1, &point);
139 if ((distance < olddistance || firstintersecting == -1) && intersecting == 1) {
140 olddistance = distance;
141 firstintersecting = 1;
147 return firstintersecting;
150 void Terrain::UpdateTransparency(int whichx, int whichy)
153 static int i, j, a, b, c, d, patch_size, stepsize;
154 static float distance;
156 static float viewdistsquared;
158 viewdistsquared = viewdistance * viewdistance;
159 patch_size = size / subdivision;
162 c = whichx * patch_elements + whichy * patch_elements * subdivision;
164 for (i = patch_size * whichx; i < patch_size * (whichx + 1) + 1; i += stepsize) {
165 for (j = patch_size * whichy; j < patch_size * (whichy + 1) + 1; j += stepsize) {
166 if (i < size && j < size) {
167 vertex.x = i * scale;
168 vertex.z = j * scale;
169 vertex.y = heightmap[i][j] * scale;
170 distance = distsq(&viewer, &vertex);
171 if (distance > viewdistsquared)
172 distance = viewdistsquared;
173 colors[i][j][3] = (viewdistsquared - (distance - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
178 for (i = patch_size * whichx; i < patch_size * (whichx + 1); i += stepsize) {
179 for (j = patch_size * whichy; j < patch_size * (whichy + 1); j += stepsize) {
180 a = (i - (patch_size * whichx)) / stepsize;
181 b = (j - (patch_size * whichy)) / stepsize;
182 d = (a * 54) + (b * 54 * patch_size / stepsize);
183 vArray[d + c + 6] = colors[i][j][3];
185 vArray[d + c + 15] = colors[i][j + stepsize][3];
187 vArray[d + c + 24] = colors[i + stepsize][j][3];
189 vArray[d + c + 33] = colors[i + stepsize][j][3];
191 vArray[d + c + 42] = colors[i][j + stepsize][3];
193 vArray[d + c + 51] = colors[i + stepsize][j + stepsize][3];
198 void Terrain::UpdateTransparencyother(int whichx, int whichy)
200 static int i, j, a, b, c, d, patch_size, stepsize;
202 patch_size = size / subdivision;
205 c = whichx * patch_elements + whichy * patch_elements * subdivision;
207 for (i = patch_size * whichx; i < patch_size * (whichx + 1); i += stepsize) {
208 for (j = patch_size * whichy; j < patch_size * (whichy + 1); j += stepsize) {
209 a = (i - (patch_size * whichx)) / stepsize;
210 b = (j - (patch_size * whichy)) / stepsize;
211 d = (a * 54) + (b * 54 * patch_size / stepsize);
212 vArray[d + c + 6] = colors[i][j][3] * opacityother[i][j];
214 vArray[d + c + 15] = colors[i][j + stepsize][3] * opacityother[i][j + stepsize];
216 vArray[d + c + 24] = colors[i + stepsize][j][3] * opacityother[i + stepsize][j];
218 vArray[d + c + 33] = colors[i + stepsize][j][3] * opacityother[i + stepsize][j];
220 vArray[d + c + 42] = colors[i][j + stepsize][3] * opacityother[i][j + stepsize];
222 vArray[d + c + 51] = colors[i + stepsize][j + stepsize][3] * opacityother[i + stepsize][j + stepsize];
227 void Terrain::UpdateTransparencyotherother(int whichx, int whichy)
230 static int i, j, a, b, c, d, patch_size, stepsize;
231 static float distance;
233 static float viewdistsquared;
235 viewdistsquared = viewdistance * viewdistance;
236 patch_size = size / subdivision;
239 c = whichx * patch_elements + whichy * patch_elements * subdivision;
241 for (i = patch_size * whichx; i < patch_size * (whichx + 1) + 1; i += stepsize) {
242 for (j = patch_size * whichy; j < patch_size * (whichy + 1) + 1; j += stepsize) {
243 if (i < size && j < size) {
244 vertex.x = i * scale;
245 vertex.z = j * scale;
246 vertex.y = heightmap[i][j] * scale;
247 distance = distsq(&viewer, &vertex);
248 if (distance > viewdistsquared)
249 distance = viewdistsquared;
250 colors[i][j][3] = (viewdistsquared - (distance - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
255 for (i = patch_size * whichx; i < patch_size * (whichx + 1); i += stepsize) {
256 for (j = patch_size * whichy; j < patch_size * (whichy + 1); j += stepsize) {
257 a = (i - (patch_size * whichx)) / stepsize;
258 b = (j - (patch_size * whichy)) / stepsize;
259 d = (a * 54) + (b * 54 * patch_size / stepsize);
260 vArray[d + c + 6] = colors[i][j][3];
262 vArray[d + c + 15] = colors[i][j + stepsize][3];
264 vArray[d + c + 24] = colors[i + stepsize][j][3];
266 vArray[d + c + 33] = colors[i + stepsize][j][3];
268 vArray[d + c + 42] = colors[i][j + stepsize][3];
270 vArray[d + c + 51] = colors[i + stepsize][j + stepsize][3];
275 void Terrain::UpdateVertexArray(int whichx, int whichy)
277 static int i, j, a, b, c, patch_size, stepsize;
280 numtris[whichx][whichy] = 0;
282 patch_size = size / subdivision;
285 c = whichx * patch_elements + whichy * patch_elements * subdivision;
286 for (i = patch_size * whichx; i < patch_size * (whichx + 1); i += stepsize) {
287 for (j = patch_size * whichy; j < patch_size * (whichy + 1); j += stepsize) {
288 a = (i - ((float)size / subdivision * (float)whichx)) / stepsize;
289 b = (j - ((float)size / subdivision * (float)whichy)) / stepsize;
290 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 0] = i * scale;
291 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 1] = heightmap[i][j] * scale;
292 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 2] = j * scale;
293 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 3] = colors[i][j][0];
294 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 4] = colors[i][j][1];
295 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 5] = colors[i][j][2];
296 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 6] = colors[i][j][3];
297 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 7] = i * scale * texscale + texoffsetx[i][j];
298 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 8] = j * scale * texscale + texoffsety[i][j];
300 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 9] = i * scale;
301 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 10] = heightmap[i][j + stepsize] * scale;
302 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 11] = j * scale + stepsize * scale;
303 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 12] = colors[i][j + stepsize][0];
304 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 13] = colors[i][j + stepsize][1];
305 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 14] = colors[i][j + stepsize][2];
306 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 15] = colors[i][j + stepsize][3];
307 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 16] = i * scale * texscale + texoffsetx[i][j + stepsize];
308 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 17] = j * scale * texscale + stepsize * scale * texscale + texoffsety[i][j + stepsize];
310 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 18] = i * scale + stepsize * scale;
311 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 19] = heightmap[i + stepsize][j] * scale;
312 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 20] = j * scale;
313 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 21] = colors[i + stepsize][j][0];
314 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 22] = colors[i + stepsize][j][1];
315 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 23] = colors[i + stepsize][j][2];
316 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 24] = colors[i + stepsize][j][3];
317 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 25] = i * scale * texscale + stepsize * scale * texscale + texoffsetx[i + stepsize][j];
318 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 26] = j * scale * texscale + texoffsety[i + stepsize][j];
320 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 27] = i * scale + stepsize * scale;
321 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 28] = heightmap[i + stepsize][j] * scale;
322 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 29] = j * scale;
323 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 30] = colors[i + stepsize][j][0];
324 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 31] = colors[i + stepsize][j][1];
325 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 32] = colors[i + stepsize][j][2];
326 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 33] = colors[i + stepsize][j][3];
327 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 34] = i * scale * texscale + stepsize * scale * texscale + texoffsetx[i + stepsize][j];
328 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 35] = j * scale * texscale + texoffsety[i + stepsize][j];
330 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 36] = i * scale;
331 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 37] = heightmap[i][j + stepsize] * scale;
332 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 38] = j * scale + stepsize * scale;
333 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 39] = colors[i][j + stepsize][0];
334 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 40] = colors[i][j + stepsize][1];
335 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 41] = colors[i][j + stepsize][2];
336 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 42] = colors[i][j + stepsize][3];
337 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 43] = i * scale * texscale + texoffsetx[i][j + stepsize];
338 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 44] = j * scale * texscale + stepsize * scale * texscale + texoffsety[i][j + stepsize];
340 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 45] = i * scale + stepsize * scale;
341 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 46] = heightmap[i + stepsize][j + stepsize] * scale;
342 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 47] = j * scale + stepsize * scale;
343 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 48] = colors[i + stepsize][j + stepsize][0];
344 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 49] = colors[i + stepsize][j + stepsize][1];
345 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 50] = colors[i + stepsize][j + stepsize][2];
346 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 51] = colors[i + stepsize][j + stepsize][3];
347 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 52] = i * scale * texscale + stepsize * scale * texscale + texoffsetx[i + stepsize][j + stepsize];
348 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 53] = j * scale * texscale + stepsize * scale * texscale + texoffsety[i + stepsize][j + stepsize];
349 numtris[whichx][whichy] += 2;
353 maxypatch[whichx][whichy] = -10000;
354 minypatch[whichx][whichy] = 10000;
355 for (a = 0; a < size / subdivision; a++) {
356 for (b = 0; b < size / subdivision; b++) {
357 if (heightmap[(size / subdivision)*whichx + a][(size / subdivision)*whichy + b]*scale > maxypatch[whichx][whichy])
358 maxypatch[whichx][whichy] = heightmap[(size / subdivision) * whichx + a][(size / subdivision) * whichy + b] * scale;
359 if (heightmap[(size / subdivision)*whichx + a][(size / subdivision)*whichy + b]*scale < minypatch[whichx][whichy])
360 minypatch[whichx][whichy] = heightmap[(size / subdivision) * whichx + a][(size / subdivision) * whichy + b] * scale;
363 heightypatch[whichx][whichy] = (maxypatch[whichx][whichy] - minypatch[whichx][whichy]);
364 if (heightypatch[whichx][whichy] < size / subdivision * scale)
365 heightypatch[whichx][whichy] = size / subdivision * scale;
366 avgypatch[whichx][whichy] = (minypatch[whichx][whichy] + maxypatch[whichx][whichy]) / 2;
368 for (i = whichx * size / subdivision; i < (whichx + 1)*size / subdivision - 1; i++) {
369 for (j = whichy * size / subdivision; j < (whichy + 1)*size / subdivision - 1; j++) {
370 triangles[(i * (size - 1) * 2) + (j * 2)][0].x = i * scale;
371 triangles[(i * (size - 1) * 2) + (j * 2)][0].y = heightmap[i][j] * scale;
372 triangles[(i * (size - 1) * 2) + (j * 2)][0].z = j * scale;
374 triangles[(i * (size - 1) * 2) + (j * 2)][1].x = i * scale;
375 triangles[(i * (size - 1) * 2) + (j * 2)][1].y = heightmap[i][j + 1] * scale;
376 triangles[(i * (size - 1) * 2) + (j * 2)][1].z = j * scale + scale;
378 triangles[(i * (size - 1) * 2) + (j * 2)][2].x = i * scale + 1 * scale;
379 triangles[(i * (size - 1) * 2) + (j * 2)][2].y = heightmap[i + 1][j] * scale;
380 triangles[(i * (size - 1) * 2) + (j * 2)][2].z = j * scale;
382 triangles[(i * (size - 1) * 2) + (j * 2) + 1][0].x = i * scale + 1 * scale;
383 triangles[(i * (size - 1) * 2) + (j * 2) + 1][0].y = heightmap[i + 1][j] * scale;
384 triangles[(i * (size - 1) * 2) + (j * 2) + 1][0].z = j * scale;
386 triangles[(i * (size - 1) * 2) + (j * 2) + 1][1].x = i * scale;
387 triangles[(i * (size - 1) * 2) + (j * 2) + 1][1].y = heightmap[i][j + 1] * scale;
388 triangles[(i * (size - 1) * 2) + (j * 2) + 1][1].z = j * scale + 1 * scale;
390 triangles[(i * (size - 1) * 2) + (j * 2) + 1][2].x = i * scale + 1 * scale;
391 triangles[(i * (size - 1) * 2) + (j * 2) + 1][2].y = heightmap[i + 1][j + 1] * scale;
392 triangles[(i * (size - 1) * 2) + (j * 2) + 1][2].z = j * scale + 1 * scale;
399 bool Terrain::load(const char *fileName)
403 static float patch_size;
405 float temptexdetail = texdetail;
410 load_image(ConvertFileName(fileName), texture);
413 if (texture.bpp > 24) {
414 int bytesPerPixel = texture.bpp / 8;
417 for (i = 0; i < (long)(texture.sizeY * texture.sizeX * bytesPerPixel); i++) {
419 texture.data[tempnum] = texture.data[i];
426 Game::LoadingScreen();
428 texdetail = temptexdetail;
430 size = texture.sizeX;
432 for (i = 0; i < size; i++) {
433 for (j = 0; j < size; j++) {
434 heightmap[size - 1 - i][j] = (float)((texture.data[(i + (j * size)) * texture.bpp / 8])) / 5;
439 Game::LoadingScreen();
443 for (i = 0; i < subdivision; i++) {
444 for (j = 0; j < subdivision; j++) {
445 textureness[i][j] = -1;
449 Game::LoadingScreen();
452 for (i = 0; i < size; i++) {
453 for (j = 0; j < size; j++) {
454 heightmap[i][j] *= .5;
456 texoffsetx[i][j] = (float)abs(Random() % 100) / 1200 / scale * 3;
457 texoffsety[i][j] = (float)abs(Random() % 100) / 1200 / scale * 3;
460 if (environment == snowyenvironment) {
461 if (j != 0 && heightmap[i][j] - heightmap[i][j - 1] > slopeness) {
462 slopeness = heightmap[i][j] - heightmap[i][j - 1];
464 opacityother[i][j] = slopeness * slopeness * 2;
465 if (opacityother[i][j] > 1)
466 opacityother[i][j] = 1;
467 opacityother[i][j] -= (float)abs(Random() % 100) / 300;
469 if (environment == desertenvironment) {
470 if (j != 0 && heightmap[i][j] - heightmap[i][j - 1] > slopeness) {
471 slopeness = heightmap[i][j] - heightmap[i][j - 1];
473 opacityother[i][j] = slopeness * slopeness * 2;
474 if (opacityother[i][j] > 1)
475 opacityother[i][j] = 1;
476 opacityother[i][j] -= (float)abs(Random() % 100) / 300;
478 if (environment == grassyenvironment) {
479 if (i != 0 && heightmap[i][j] - heightmap[i - 1][j] > slopeness) {
480 slopeness = heightmap[i][j] - heightmap[i - 1][j];
482 if (j != 0 && heightmap[i][j] - heightmap[i][j - 1] > slopeness) {
483 slopeness = heightmap[i][j] - heightmap[i][j - 1];
485 if (i < size - 1 && heightmap[i][j] - heightmap[i + 1][j] > slopeness) {
486 slopeness = heightmap[i][j] - heightmap[i + 1][j];
488 if (j < size - 1 && heightmap[i][j] - heightmap[i][j + 1] > slopeness) {
489 slopeness = heightmap[i][j] - heightmap[i][j + 1];
491 opacityother[i][j] = slopeness * slopeness * 10;
492 if (opacityother[i][j] > 1)
493 opacityother[i][j] = 1;
494 opacityother[i][j] -= (float)abs(Random() % 100) / 100;
499 Game::LoadingScreen();
501 for (i = 0; i < size; i++) {
502 for (j = 0; j < size; j++) {
503 if (environment == snowyenvironment) {
504 heightmap[i][j] -= opacityother[i][j];
506 if (environment == desertenvironment) {
507 heightmap[i][j] -= opacityother[i][j];
512 Game::LoadingScreen();
514 for (i = 0; i < size; i++) {
515 for (j = 0; j < size; j++) {
516 if (opacityother[i][j] < .1)
517 opacityother[i][j] = 0;
518 if (textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == -1) {
519 if (!opacityother[i][j])
520 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = allfirst;
521 if (opacityother[i][j] == 1)
522 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = allsecond;
524 if (opacityother[i][j] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
525 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
526 if (opacityother[i][j] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
527 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
533 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
534 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
535 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
536 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
537 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
538 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
539 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
540 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
544 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
545 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
546 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
547 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
548 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
549 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
550 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
551 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
557 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
558 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
559 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
560 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
561 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
562 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
563 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
564 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
572 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
573 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
574 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
575 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
576 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
577 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
578 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
579 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
583 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
584 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
585 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
586 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
587 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
588 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
589 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
590 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
596 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
597 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
598 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
599 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
600 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
601 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
602 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
603 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
611 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
612 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
613 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
614 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
615 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
616 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
617 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
618 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
624 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
625 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
626 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
627 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
628 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
629 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
630 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
631 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
638 Game::LoadingScreen();
640 patch_size = size / subdivision;
641 patch_elements = (patch_size) * (patch_size) * 54;
647 void Terrain::CalculateNormals()
650 static XYZ facenormal;
651 static XYZ p, q, a, b, c;
653 for (i = 0; i < size; i++) {
654 for (j = 0; j < size; j++) {
661 for (i = 0; i < size - 1; i++) {
662 for (j = 0; j < size - 1; j++) {
664 a.y = heightmap[i][j];
667 b.y = heightmap[i][j + 1];
670 c.y = heightmap[i + 1][j];
680 CrossProduct(&p, &q, &facenormal);
682 facenormals[i][j] = facenormal;
684 normals[i][j] = normals[i][j] + facenormal;
685 normals[i][j + 1] = normals[i][j + 1] + facenormal;
686 normals[i + 1][j] = normals[i + 1][j] + facenormal;
690 a.y = heightmap[i + 1][j];
693 b.y = heightmap[i][j + 1];
696 c.y = heightmap[i + 1][j + 1];
706 CrossProduct(&p, &q, &facenormal);
708 normals[i + 1][j + 1] = normals[i + 1][j + 1] + facenormal;
709 normals[i][j + 1] = normals[i][j + 1] + facenormal;
710 normals[i + 1][j] = normals[i + 1][j] + facenormal;
712 Normalise(&facenormals[i][j]);
716 for (i = 0; i < size; i++) {
717 for (j = 0; j < size; j++) {
718 Normalise(&normals[i][j]);
723 void Terrain::drawpatch(int whichx, int whichy, float opacity)
729 UpdateTransparency(whichx, whichy);
731 glColor4f(1, 1, 1, 1);
732 //Set up vertex array
733 glEnableClientState(GL_VERTEX_ARRAY);
734 glEnableClientState(GL_COLOR_ARRAY);
735 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
736 glVertexPointer(3, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[0 + whichx * patch_elements + whichy * patch_elements * subdivision]);
737 glColorPointer(4, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[3 + whichx * patch_elements + whichy * patch_elements * subdivision]);
738 glTexCoordPointer(2, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[7 + whichx * patch_elements + whichy * patch_elements * subdivision]);
741 glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy] * 3);
743 glDisableClientState(GL_VERTEX_ARRAY);
744 glDisableClientState(GL_COLOR_ARRAY);
745 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
748 void Terrain::drawpatchother(int whichx, int whichy, float opacity)
752 UpdateTransparency(whichx, whichy);
754 UpdateTransparencyother(whichx, whichy);
755 glColor4f(1, 1, 1, 1);
756 //Set up vertex array
757 glEnableClientState(GL_VERTEX_ARRAY);
758 glEnableClientState(GL_COLOR_ARRAY);
759 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
760 glVertexPointer(3, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[0 + whichx * patch_elements + whichy * patch_elements * subdivision]);
761 glColorPointer(4, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[3 + whichx * patch_elements + whichy * patch_elements * subdivision]);
762 glTexCoordPointer(2, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[7 + whichx * patch_elements + whichy * patch_elements * subdivision]);
765 glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy] * 3);
767 glDisableClientState(GL_VERTEX_ARRAY);
768 glDisableClientState(GL_COLOR_ARRAY);
769 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
772 void Terrain::drawpatchotherother(int whichx, int whichy, float opacity)
775 UpdateTransparencyotherother(whichx, whichy);
777 glMatrixMode(GL_TEXTURE);
781 glColor4f(1, 1, 1, 1);
783 //Set up vertex array
784 glEnableClientState(GL_VERTEX_ARRAY);
785 glEnableClientState(GL_COLOR_ARRAY);
786 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
787 glVertexPointer(3, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[0 + whichx * patch_elements + whichy * patch_elements * subdivision]);
788 glColorPointer(4, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[3 + whichx * patch_elements + whichy * patch_elements * subdivision]);
789 glTexCoordPointer(2, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[7 + whichx * patch_elements + whichy * patch_elements * subdivision]);
792 glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy] * 3);
794 glDisableClientState(GL_VERTEX_ARRAY);
795 glDisableClientState(GL_COLOR_ARRAY);
796 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
799 glMatrixMode(GL_MODELVIEW);
803 float Terrain::getHeight(float pointx, float pointz)
805 static int tilex, tiley;
806 static XYZ startpoint, endpoint, intersect, triangle[3];
811 if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0)
814 startpoint.x = pointx;
815 startpoint.y = -1000;
816 startpoint.z = pointz;
818 endpoint = startpoint;
824 triangle[0].x = tilex;
825 triangle[0].z = tiley;
826 triangle[0].y = heightmap[tilex][tiley];
828 triangle[1].x = tilex + 1;
829 triangle[1].z = tiley;
830 triangle[1].y = heightmap[tilex + 1][tiley];
832 triangle[2].x = tilex;
833 triangle[2].z = tiley + 1;
834 triangle[2].y = heightmap[tilex][tiley + 1];
836 if (!LineFacetd(&startpoint, &endpoint, &triangle[0], &triangle[1], &triangle[2], &intersect)) {
837 triangle[0].x = tilex + 1;
838 triangle[0].z = tiley;
839 triangle[0].y = heightmap[tilex + 1][tiley];
841 triangle[1].x = tilex + 1;
842 triangle[1].z = tiley + 1;
843 triangle[1].y = heightmap[tilex + 1][tiley + 1];
845 triangle[2].x = tilex;
846 triangle[2].z = tiley + 1;
847 triangle[2].y = heightmap[tilex][tiley + 1];
848 LineFacetd(&startpoint, &endpoint, &triangle[0], &triangle[1], &triangle[2], &intersect);
850 return intersect.y * scale + getOpacity(pointx * scale, pointz * scale) / 8;
853 float Terrain::getOpacity(float pointx, float pointz)
855 static float height1, height2;
856 static int tilex, tiley;
861 if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0)
867 height1 = opacityother[tilex][tiley] * (1 - (pointx - tilex)) + opacityother[tilex + 1][tiley] * (pointx - tilex);
868 height2 = opacityother[tilex][tiley + 1] * (1 - (pointx - tilex)) + opacityother[tilex + 1][tiley + 1] * (pointx - tilex);
870 return height1 * (1 - (pointz - tiley)) + height2 * (pointz - tiley);
873 XYZ Terrain::getNormal(float pointx, float pointz)
875 static XYZ height1, height2, total;
876 static int tilex, tiley;
882 if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0)
887 height1 = normals[tilex][tiley] * (1 - (pointx - tilex)) + normals[tilex + 1][tiley] * (pointx - tilex);
888 height2 = normals[tilex][tiley + 1] * (1 - (pointx - tilex)) + normals[tilex + 1][tiley + 1] * (pointx - tilex);
889 total = height1 * (1 - (pointz - tiley)) + height2 * (pointz - tiley);
894 XYZ Terrain::getLighting(float pointx, float pointz)
896 static XYZ height1, height2;
897 static int tilex, tiley;
903 if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0)
908 height1.x = colors[tilex][tiley][0] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley][0] * (pointx - tilex);
909 height1.y = colors[tilex][tiley][1] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley][1] * (pointx - tilex);
910 height1.z = colors[tilex][tiley][2] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley][2] * (pointx - tilex);
911 height2.x = colors[tilex][tiley + 1][0] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley + 1][0] * (pointx - tilex);
912 height2.y = colors[tilex][tiley + 1][1] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley + 1][1] * (pointx - tilex);
913 height2.z = colors[tilex][tiley + 1][2] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley + 1][2] * (pointx - tilex);
915 return height1 * (1 - (pointz - tiley)) + height2 * (pointz - tiley);
918 void Terrain::draw(int layer)
921 static float opacity;
922 static XYZ terrainpoint;
923 static float distance[subdivision][subdivision];
925 static int beginx, endx;
926 static int beginz, endz;
928 static float patch_size = size / subdivision * scale;
929 static float viewdistsquared;
931 viewdistsquared = viewdistance * viewdistance;
934 beginx = (viewer.x - viewdistance) / (patch_size) - 1;
937 beginz = (viewer.z - viewdistance) / (patch_size) - 1;
941 endx = (viewer.x + viewdistance) / (patch_size) + 1;
942 if (endx > subdivision)
944 endz = (viewer.z + viewdistance) / (patch_size) + 1;
945 if (endz > subdivision)
949 for (i = beginx; i < endx; i++) {
950 for (j = beginz; j < endz; j++) {
951 terrainpoint.x = i * patch_size + (patch_size) / 2;
952 terrainpoint.y = viewer.y; //heightmap[i][j]*scale;
953 terrainpoint.z = j * patch_size + (patch_size) / 2;
954 distance[i][j] = distsq(&viewer, &terrainpoint);
958 for (i = beginx; i < endx; i++) {
959 for (j = beginz; j < endz; j++) {
960 if (distance[i][j] < (viewdistance + patch_size) * (viewdistance + patch_size)) {
962 if (distance[i][j] > viewdistsquared * fadestart - viewdistsquared)
964 if (opacity == 1 && i != subdivision)
965 if (distance[i + 1][j] > viewdistsquared * fadestart - viewdistsquared)
967 if (opacity == 1 && j != subdivision)
968 if (distance[i][j + 1] > viewdistsquared * fadestart - viewdistsquared)
970 if (opacity == 1 && j != subdivision && i != subdivision)
971 if (distance[i + 1][j + 1] > viewdistsquared * fadestart - viewdistsquared)
973 glMatrixMode(GL_MODELVIEW);
975 if (frustum.CubeInFrustum(i * patch_size + patch_size * .5, avgypatch[i][j], j * patch_size + patch_size * .5, heightypatch[i][j] / 2)) {
976 if (environment == desertenvironment && distance[i][j] > viewdistsquared / 4)
977 glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, blurness);
978 else if (environment == desertenvironment)
979 glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
980 if (!layer && textureness[i][j] != allsecond)
981 drawpatch(i, j, opacity);
982 if (layer == 1 && textureness[i][j] != allfirst)
983 drawpatchother(i, j, opacity);
984 if (layer == 2 && textureness[i][j] != allfirst)
985 drawpatchotherother(i, j, opacity);
991 if (environment == desertenvironment)
992 glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
995 void Terrain::drawdecals()
999 static float distancemult;
1000 static int lasttype;
1002 static float viewdistsquared;
1005 viewdistsquared = viewdistance * viewdistance;
1010 glDisable(GL_LIGHTING);
1011 glDisable(GL_CULL_FACE);
1012 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1014 for (i = 0; i < numdecals; i++) {
1015 if (decaltype[i] == blooddecalfast && decalalivetime[i] < 2)
1016 decalalivetime[i] = 2;
1017 if ((decaltype[i] == shadowdecal || decaltype[i] == shadowdecalpermanent) && decaltype[i] != lasttype) {
1018 shadowtexture.bind();
1021 glAlphaFunc(GL_GREATER, 0.0001);
1022 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1025 if (decaltype[i] == footprintdecal && decaltype[i] != lasttype) {
1026 footprinttexture.bind();
1029 glAlphaFunc(GL_GREATER, 0.0001);
1030 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1033 if (decaltype[i] == bodyprintdecal && decaltype[i] != lasttype) {
1034 bodyprinttexture.bind();
1037 glAlphaFunc(GL_GREATER, 0.0001);
1038 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1041 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalslow) && decaltype[i] != lasttype) {
1042 bloodtexture.bind();
1045 glAlphaFunc(GL_GREATER, 0.15);
1046 glBlendFunc(GL_ONE, GL_ZERO);
1049 if ((decaltype[i] == blooddecalfast) && decaltype[i] != lasttype) {
1050 bloodtexture2.bind();
1053 glAlphaFunc(GL_GREATER, 0.15);
1054 glBlendFunc(GL_ONE, GL_ZERO);
1057 if (decaltype[i] == shadowdecal || decaltype[i] == shadowdecalpermanent) {
1058 distancemult = (viewdistsquared - (distsq(&viewer, &decalposition[i]) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
1059 if (distancemult >= 1)
1060 glColor4f(1, 1, 1, decalopacity[i]);
1061 if (distancemult < 1)
1062 glColor4f(1, 1, 1, decalopacity[i]*distancemult);
1064 if (decaltype[i] == footprintdecal || decaltype[i] == bodyprintdecal) {
1065 distancemult = (viewdistsquared - (distsq(&viewer, &decalposition[i]) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
1066 if (distancemult >= 1) {
1067 glColor4f(1, 1, 1, decalopacity[i]);
1068 if (decalalivetime[i] > 3)
1069 glColor4f(1, 1, 1, decalopacity[i] * (5 - decalalivetime[i]) / 2);
1071 if (distancemult < 1) {
1072 glColor4f(1, 1, 1, decalopacity[i]*distancemult);
1073 if (decalalivetime[i] > 3)
1074 glColor4f(1, 1, 1, decalopacity[i] * (5 - decalalivetime[i]) / 2 * distancemult);
1077 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow)) {
1078 distancemult = (viewdistsquared - (distsq(&viewer, &decalposition[i]) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
1079 if (distancemult >= 1) {
1080 glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]);
1081 if (decalalivetime[i] < 4)
1082 glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]*decalalivetime[i]*.25);
1083 if (decalalivetime[i] > 58)
1084 glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i] * (60 - decalalivetime[i]) / 2);
1086 if (distancemult < 1) {
1087 glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]*distancemult);
1088 if (decalalivetime[i] < 4)
1089 glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]*decalalivetime[i]*distancemult * .25);
1090 if (decalalivetime[i] > 58)
1091 glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i] * (60 - decalalivetime[i]) / 2 * distancemult);
1094 lasttype = decaltype[i];
1095 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1096 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1098 glMatrixMode(GL_MODELVIEW);
1100 glBegin(GL_TRIANGLES);
1101 for (int j = 0; j < 3; j++) {
1102 glTexCoord2f(decaltexcoords[i][j][0], decaltexcoords[i][j][1]);
1103 glVertex3f(decalvertex[i][j].x, decalvertex[i][j].y, decalvertex[i][j].z);
1108 for (i = numdecals - 1; i >= 0; i--) {
1109 decalalivetime[i] += multiplier;
1110 if (decaltype[i] == blooddecalslow)
1111 decalalivetime[i] -= multiplier * 2 / 3;
1112 if (decaltype[i] == blooddecalfast)
1113 decalalivetime[i] += multiplier * 4;
1114 if (decaltype[i] == shadowdecal)
1116 if (decaltype[i] == footprintdecal && decalalivetime[i] >= 5)
1118 if (decaltype[i] == bodyprintdecal && decalalivetime[i] >= 5)
1120 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow) && decalalivetime[i] >= 60)
1123 glAlphaFunc(GL_GREATER, 0.0001);
1127 void Terrain::AddObject(XYZ where, float radius, int id)
1132 if (id >= 0 && id < 10000)
1133 for (i = 0; i < subdivision; i++) {
1134 for (j = 0; j < subdivision; j++) {
1135 if (patchobjectnum[i][j] < 300 - 1) {
1137 points[0].x = (size / subdivision) * i;
1138 points[0].z = (size / subdivision) * j;
1139 points[0].y = heightmap[(int)points[0].x][(int)points[0].z];
1140 points[1].x = (size / subdivision) * (i + 1);
1141 points[1].z = (size / subdivision) * j;
1142 points[1].y = heightmap[(int)points[1].x][(int)points[1].z];
1143 points[2].x = (size / subdivision) * (i + 1);
1144 points[2].z = (size / subdivision) * (j + 1);
1145 points[2].y = heightmap[(int)points[2].x][(int)points[2].z];
1146 points[3].x = (size / subdivision) * i;
1147 points[3].z = (size / subdivision) * (j + 1);
1148 points[3].y = heightmap[(int)points[3].x][(int)points[3].z];
1153 if (!done && where.x + radius > points[0].x && where.x - radius < points[2].x && where.z + radius > points[0].z && where.z - radius < points[2].z) {
1154 patchobjects[i][j][patchobjectnum[i][j]] = id;
1155 patchobjectnum[i][j]++;
1163 void Terrain::DeleteDecal(int which)
1166 decaltype[which] = decaltype[numdecals - 1];
1167 decalposition[which] = decalposition[numdecals - 1];
1168 for (int i = 0; i < 3; i++) {
1169 decalvertex[which][i] = decalvertex[numdecals - 1][i];
1170 decaltexcoords[which][i][0] = decaltexcoords[numdecals - 1][i][0];
1171 decaltexcoords[which][i][1] = decaltexcoords[numdecals - 1][i][1];
1173 decalrotation[which] = decalrotation[numdecals - 1];
1174 decalalivetime[which] = decalalivetime[numdecals - 1];
1175 decalopacity[which] = decalopacity[numdecals - 1];
1176 decalbrightness[which] = decalbrightness[numdecals - 1];
1181 void Terrain::MakeDecal(int type, XYZ where, float size, float opacity, float rotation)
1184 if (opacity > 0 && size > 0) {
1185 static int patchx[4];
1186 static int patchy[4];
1188 decaltexcoords[numdecals][0][0] = 1;
1189 decaltexcoords[numdecals][0][1] = 0;
1191 patchx[0] = (where.x + size) / scale;
1192 patchx[1] = (where.x - size) / scale;
1193 patchx[2] = (where.x - size) / scale;
1194 patchx[3] = (where.x + size) / scale;
1196 patchy[0] = (where.z - size) / scale;
1197 patchy[1] = (where.z - size) / scale;
1198 patchy[2] = (where.z + size) / scale;
1199 patchy[3] = (where.z + size) / scale;
1201 if ((patchx[0] != patchx[1] || patchy[0] != patchy[1]) && (patchx[0] != patchx[2] || patchy[0] != patchy[2]) && (patchx[0] != patchx[3] || patchy[0] != patchy[3])) {
1202 MakeDecalLock(type, where, patchx[0], patchy[0], size, opacity, rotation);
1205 if ((patchx[1] != patchx[2] || patchy[1] != patchy[2]) && (patchx[1] != patchx[3] || patchy[1] != patchy[3])) {
1206 MakeDecalLock(type, where, patchx[1], patchy[1], size, opacity, rotation);
1209 if ((patchx[2] != patchx[3] || patchy[2] != patchy[3])) {
1210 MakeDecalLock(type, where, patchx[2], patchy[2], size, opacity, rotation);
1212 MakeDecalLock(type, where, patchx[3], patchy[3], size, opacity, rotation);
1218 void Terrain::MakeDecalLock(int type, XYZ where, int whichx, int whichy, float size, float opacity, float rotation)
1221 static float placex, placez;
1226 rot = getLighting(where.x, where.z);
1227 decalbrightness[numdecals] = (rot.x + rot.y + rot.z) / 3;
1228 if (decalbrightness[numdecals] < .4)
1229 decalbrightness[numdecals] = .4;
1231 if (environment == grassyenvironment) {
1232 decalbrightness[numdecals] *= .6;
1235 if (decalbrightness[numdecals] > 1)
1236 decalbrightness[numdecals] = 1;
1237 decalbright = decalbrightness[numdecals];
1239 decalposition[numdecals] = where;
1240 decaltype[numdecals] = type;
1241 decalopacity[numdecals] = opacity;
1242 decalrotation[numdecals] = rotation;
1243 decalalivetime[numdecals] = 0;
1245 placex = (float)whichx * scale + scale;
1246 placez = (float)whichy * scale;
1248 decaltexcoords[numdecals][0][0] = (placex - where.x) / size / 2 + .5;
1249 decaltexcoords[numdecals][0][1] = (placez - where.z) / size / 2 + .5;
1251 decalvertex[numdecals][0].x = placex;
1252 decalvertex[numdecals][0].z = placez;
1253 decalvertex[numdecals][0].y = heightmap[whichx + 1][whichy] * scale + .01;
1256 placex = (float)whichx * scale + scale;
1257 placez = (float)whichy * scale + scale;
1259 decaltexcoords[numdecals][1][0] = (placex - where.x) / size / 2 + .5;
1260 decaltexcoords[numdecals][1][1] = (placez - where.z) / size / 2 + .5;
1262 decalvertex[numdecals][1].x = placex;
1263 decalvertex[numdecals][1].z = placez;
1264 decalvertex[numdecals][1].y = heightmap[whichx + 1][whichy + 1] * scale + .01;
1267 placex = (float)whichx * scale;
1268 placez = (float)whichy * scale + scale;
1270 decaltexcoords[numdecals][2][0] = (placex - where.x) / size / 2 + .5;
1271 decaltexcoords[numdecals][2][1] = (placez - where.z) / size / 2 + .5;
1273 decalvertex[numdecals][2].x = placex;
1274 decalvertex[numdecals][2].z = placez;
1275 decalvertex[numdecals][2].y = heightmap[whichx][whichy + 1] * scale + .01;
1277 if (decalrotation[numdecals]) {
1278 for (int i = 0; i < 3; i++) {
1280 rot.x = decaltexcoords[numdecals][i][0] - .5;
1281 rot.z = decaltexcoords[numdecals][i][1] - .5;
1282 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1283 decaltexcoords[numdecals][i][0] = rot.x + .5;
1284 decaltexcoords[numdecals][i][1] = rot.z + .5;
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 (numdecals < max_decals - 1)
1295 decalbrightness[numdecals] = decalbright;
1297 decalposition[numdecals] = where;
1298 decaltype[numdecals] = type;
1299 decalopacity[numdecals] = opacity;
1300 decalrotation[numdecals] = rotation;
1301 decalalivetime[numdecals] = 0;
1303 placex = (float)whichx * scale + scale;
1304 placez = (float)whichy * scale;
1306 decaltexcoords[numdecals][0][0] = (placex - where.x) / size / 2 + .5;
1307 decaltexcoords[numdecals][0][1] = (placez - where.z) / size / 2 + .5;
1309 decalvertex[numdecals][0].x = placex;
1310 decalvertex[numdecals][0].z = placez;
1311 decalvertex[numdecals][0].y = heightmap[whichx + 1][whichy] * scale + .01;
1314 placex = (float)whichx * scale;
1315 placez = (float)whichy * scale;
1317 decaltexcoords[numdecals][1][0] = (placex - where.x) / size / 2 + .5;
1318 decaltexcoords[numdecals][1][1] = (placez - where.z) / size / 2 + .5;
1320 decalvertex[numdecals][1].x = placex;
1321 decalvertex[numdecals][1].z = placez;
1322 decalvertex[numdecals][1].y = heightmap[whichx][whichy] * scale + .01;
1325 placex = (float)whichx * scale;
1326 placez = (float)whichy * scale + scale;
1328 decaltexcoords[numdecals][2][0] = (placex - where.x) / size / 2 + .5;
1329 decaltexcoords[numdecals][2][1] = (placez - where.z) / size / 2 + .5;
1331 decalvertex[numdecals][2].x = placex;
1332 decalvertex[numdecals][2].z = placez;
1333 decalvertex[numdecals][2].y = heightmap[whichx][whichy + 1] * scale + .01;
1335 if (decalrotation[numdecals]) {
1336 for (int i = 0; i < 3; i++) {
1338 rot.x = decaltexcoords[numdecals][i][0] - .5;
1339 rot.z = decaltexcoords[numdecals][i][1] - .5;
1340 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1341 decaltexcoords[numdecals][i][0] = rot.x + .5;
1342 decaltexcoords[numdecals][i][1] = rot.z + .5;
1346 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1347 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1348 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1349 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1))
1350 if (numdecals < max_decals - 1)
1355 void Terrain::DoShadows()
1357 static int i, j, k, l, todivide;
1358 static float brightness, total;
1359 static XYZ testpoint, testpoint2, terrainpoint, lightloc, col;
1360 lightloc = light.location;
1361 if (!skyboxtexture) {
1365 if (skyboxtexture && tutoriallevel) {
1371 Normalise(&lightloc);
1373 for (i = 0; i < size; i++) {
1374 for (j = 0; j < size; j++) {
1375 terrainpoint.x = (float)(i) * scale;
1376 terrainpoint.z = (float)(j) * scale;
1377 terrainpoint.y = heightmap[i][j] * scale;
1380 patchx = (float)(i) * subdivision / size;
1381 patchz = (float)(j) * subdivision / size;
1382 if (patchobjectnum[patchx][patchz]) {
1383 for (k = 0; k < patchobjectnum[patchx][patchz]; k++) {
1384 l = patchobjects[patchx][patchz][k];
1385 if (objects.type[l] != treetrunktype) {
1386 testpoint = terrainpoint;
1387 testpoint2 = terrainpoint + lightloc * 50 * (1 - shadowed);
1388 if (objects.model[l].LineCheck(&testpoint, &testpoint2, &col, &objects.position[l], &objects.yaw[l]) != -1) {
1389 shadowed = 1 - (findDistance(&terrainpoint, &col) / 50);
1394 Game::LoadingScreen();
1396 brightness = dotproduct(&lightloc, &normals[i][j]);
1398 brightness *= 1 - shadowed;
1405 colors[i][j][0] = light.color[0] * brightness + light.ambient[0];
1406 colors[i][j][1] = light.color[1] * brightness + light.ambient[1];
1407 colors[i][j][2] = light.color[2] * brightness + light.ambient[2];
1409 if (colors[i][j][0] > 1) colors[i][j][0] = 1;
1410 if (colors[i][j][1] > 1) colors[i][j][1] = 1;
1411 if (colors[i][j][2] > 1) colors[i][j][2] = 1;
1412 if (colors[i][j][0] < 0) colors[i][j][0] = 0;
1413 if (colors[i][j][1] < 0) colors[i][j][1] = 0;
1414 if (colors[i][j][2] < 0) colors[i][j][2] = 0;
1419 Game::LoadingScreen();
1422 for (i = 0; i < size; i++) {
1423 for (j = 0; j < size; j++) {
1424 for (k = 0; k < 3; k++) {
1428 total += colors[j][i - 1][k];
1431 if (i != size - 1) {
1432 total += colors[j][i + 1][k];
1436 total += colors[j - 1][i][k];
1439 if (j != size - 1) {
1440 total += colors[j + 1][i][k];
1443 if (i != 0 && j != 0) {
1444 total += colors[j - 1][i - 1][k];
1447 if (i != size - 1 && j != 0) {
1448 total += colors[j - 1][i + 1][k];
1451 if (j != size - 1 && i != size - 1) {
1452 total += colors[j + 1][i + 1][k];
1455 if (j != size - 1 && i != 0) {
1456 total += colors[j + 1][i - 1][k];
1459 total += colors[j][i][k];
1462 colors[j][i][k] = total / todivide;
1467 for (i = 0; i < subdivision; i++) {
1468 for (j = 0; j < subdivision; j++) {
1469 UpdateVertexArray(i, j);
1478 memset(patchobjectnum, 0, sizeof(patchobjectnum));
1479 memset(patchobjects, 0, sizeof(patchobjects));
1483 memset(heightmap, 0, sizeof(heightmap));
1484 memset(normals, 0, sizeof(normals));
1485 memset(facenormals, 0, sizeof(facenormals));
1486 memset(triangles, 0, sizeof(triangles));
1487 memset(colors, 0, sizeof(colors));
1488 memset(opacityother, 0, sizeof(opacityother));
1489 memset(texoffsetx, 0, sizeof(texoffsetx));
1490 memset(texoffsety, 0, sizeof(texoffsety));
1491 memset(numtris, 0, sizeof(numtris));
1492 memset(textureness, 0, sizeof(textureness));
1494 memset(vArray, 0, sizeof(vArray));
1496 memset(visible, 0, sizeof(visible));
1497 memset(avgypatch, 0, sizeof(avgypatch));
1498 memset(maxypatch, 0, sizeof(maxypatch));
1499 memset(minypatch, 0, sizeof(minypatch));
1500 memset(heightypatch, 0, sizeof(heightypatch));
1504 memset(decaltexcoords, 0, sizeof(decaltexcoords));
1505 memset(decalvertex, 0, sizeof(decalvertex));
1506 memset(decaltype, 0, sizeof(decaltype));
1507 memset(decalopacity, 0, sizeof(decalopacity));
1508 memset(decalrotation, 0, sizeof(decalrotation));
1509 memset(decalalivetime, 0, sizeof(decalalivetime));
1510 memset(decalbrightness, 0, sizeof(decalbrightness));
1511 memset(decalposition, 0, sizeof(decalposition));
1516 terraintexture.destroy();
1517 shadowtexture.destroy();
1518 bodyprinttexture.destroy();
1519 footprinttexture.destroy();
1520 bloodtexture.destroy();
1521 bloodtexture2.destroy();
1522 breaktexture.destroy();