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/>.
21 #include "Environment/Terrain.hpp"
24 #include "Objects/Object.hpp"
25 #include "Tutorial.hpp"
26 #include "Utils/Folders.hpp"
29 extern float viewdistance;
30 extern float fadestart;
31 extern int environment;
32 extern float texscale;
34 extern float multiplier;
35 extern FRUSTUM frustum;
36 extern float texdetail;
38 extern bool decalstoggle;
39 extern float blurness;
40 extern float targetblurness;
41 extern bool skyboxtexture;
45 int Terrain::lineTerrain(XYZ p1, XYZ p2, XYZ* p)
48 static float distance;
49 static float olddistance;
50 static int intersecting;
51 static int firstintersecting;
53 static int startx, starty;
54 static int endx, endy;
55 static float highest, lowest;
57 firstintersecting = -1;
91 for (i = startx; i <= endx; i++) {
92 for (j = starty; j <= endy; j++) {
95 for (k = 0; k < 2; k++) {
96 if (heightmap[i + k][j] > highest)
97 highest = heightmap[i + k][j];
98 if (heightmap[i + k][j] < lowest)
99 lowest = heightmap[i + k][j];
100 if (heightmap[i + k][j + 1] > highest)
101 highest = heightmap[i + k][j + 1];
102 if (heightmap[i + k][j + 1] < lowest)
103 lowest = heightmap[i + k][j + 1];
105 if ((p1.y <= highest || p2.y <= highest) && (p1.y >= lowest || p2.y >= lowest)) {
107 triangles[0].y = heightmap[i][j];
111 triangles[1].y = heightmap[i][j + 1];
112 triangles[1].z = j + 1;
114 triangles[2].x = i + 1;
115 triangles[2].y = heightmap[i + 1][j];
118 intersecting = LineFacet(p1, p2, triangles[0], triangles[1], triangles[2], &point);
119 distance = distsq(&p1, &point);
120 if ((distance < olddistance || firstintersecting == -1) && intersecting == 1) {
121 olddistance = distance;
122 firstintersecting = 1;
126 triangles[0].x = i + 1;
127 triangles[0].y = heightmap[i + 1][j];
131 triangles[1].y = heightmap[i][j + 1];
132 triangles[1].z = j + 1;
134 triangles[2].x = i + 1;
135 triangles[2].y = heightmap[i + 1][j + 1];
136 triangles[2].z = j + 1;
138 intersecting = LineFacet(p1, p2, triangles[0], triangles[1], triangles[2], &point);
139 distance = distsq(&p1, &point);
140 if ((distance < olddistance || firstintersecting == -1) && intersecting == 1) {
141 olddistance = distance;
142 firstintersecting = 1;
148 return firstintersecting;
151 void Terrain::UpdateTransparency(int whichx, int whichy)
154 static int i, j, a, b, c, d, patch_size, stepsize;
155 static float distance;
157 static float viewdistsquared;
159 viewdistsquared = viewdistance * viewdistance;
160 patch_size = size / subdivision;
163 c = whichx * patch_elements + whichy * patch_elements * subdivision;
165 for (i = patch_size * whichx; i < patch_size * (whichx + 1) + 1; i += stepsize) {
166 for (j = patch_size * whichy; j < patch_size * (whichy + 1) + 1; j += stepsize) {
167 if (i < size && j < size) {
168 vertex.x = i * scale;
169 vertex.z = j * scale;
170 vertex.y = heightmap[i][j] * scale;
171 distance = distsq(&viewer, &vertex);
172 if (distance > viewdistsquared)
173 distance = viewdistsquared;
174 colors[i][j][3] = (viewdistsquared - (distance - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
179 for (i = patch_size * whichx; i < patch_size * (whichx + 1); i += stepsize) {
180 for (j = patch_size * whichy; j < patch_size * (whichy + 1); j += stepsize) {
181 a = (i - (patch_size * whichx)) / stepsize;
182 b = (j - (patch_size * whichy)) / stepsize;
183 d = (a * 54) + (b * 54 * patch_size / stepsize);
184 vArray[d + c + 6] = colors[i][j][3];
186 vArray[d + c + 15] = colors[i][j + stepsize][3];
188 vArray[d + c + 24] = colors[i + stepsize][j][3];
190 vArray[d + c + 33] = colors[i + stepsize][j][3];
192 vArray[d + c + 42] = colors[i][j + stepsize][3];
194 vArray[d + c + 51] = colors[i + stepsize][j + stepsize][3];
199 void Terrain::UpdateTransparencyother(int whichx, int whichy)
201 static int i, j, a, b, c, d, patch_size, stepsize;
203 patch_size = size / subdivision;
206 c = whichx * patch_elements + whichy * patch_elements * subdivision;
208 for (i = patch_size * whichx; i < patch_size * (whichx + 1); i += stepsize) {
209 for (j = patch_size * whichy; j < patch_size * (whichy + 1); j += stepsize) {
210 a = (i - (patch_size * whichx)) / stepsize;
211 b = (j - (patch_size * whichy)) / stepsize;
212 d = (a * 54) + (b * 54 * patch_size / stepsize);
213 vArray[d + c + 6] = colors[i][j][3] * opacityother[i][j];
215 vArray[d + c + 15] = colors[i][j + stepsize][3] * opacityother[i][j + stepsize];
217 vArray[d + c + 24] = colors[i + stepsize][j][3] * opacityother[i + stepsize][j];
219 vArray[d + c + 33] = colors[i + stepsize][j][3] * opacityother[i + stepsize][j];
221 vArray[d + c + 42] = colors[i][j + stepsize][3] * opacityother[i][j + stepsize];
223 vArray[d + c + 51] = colors[i + stepsize][j + stepsize][3] * opacityother[i + stepsize][j + stepsize];
228 void Terrain::UpdateTransparencyotherother(int whichx, int whichy)
231 static int i, j, a, b, c, d, patch_size, stepsize;
232 static float distance;
234 static float viewdistsquared;
236 viewdistsquared = viewdistance * viewdistance;
237 patch_size = size / subdivision;
240 c = whichx * patch_elements + whichy * patch_elements * subdivision;
242 for (i = patch_size * whichx; i < patch_size * (whichx + 1) + 1; i += stepsize) {
243 for (j = patch_size * whichy; j < patch_size * (whichy + 1) + 1; j += stepsize) {
244 if (i < size && j < size) {
245 vertex.x = i * scale;
246 vertex.z = j * scale;
247 vertex.y = heightmap[i][j] * scale;
248 distance = distsq(&viewer, &vertex);
249 if (distance > viewdistsquared)
250 distance = viewdistsquared;
251 colors[i][j][3] = (viewdistsquared - (distance - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
256 for (i = patch_size * whichx; i < patch_size * (whichx + 1); i += stepsize) {
257 for (j = patch_size * whichy; j < patch_size * (whichy + 1); j += stepsize) {
258 a = (i - (patch_size * whichx)) / stepsize;
259 b = (j - (patch_size * whichy)) / stepsize;
260 d = (a * 54) + (b * 54 * patch_size / stepsize);
261 vArray[d + c + 6] = colors[i][j][3];
263 vArray[d + c + 15] = colors[i][j + stepsize][3];
265 vArray[d + c + 24] = colors[i + stepsize][j][3];
267 vArray[d + c + 33] = colors[i + stepsize][j][3];
269 vArray[d + c + 42] = colors[i][j + stepsize][3];
271 vArray[d + c + 51] = colors[i + stepsize][j + stepsize][3];
276 void Terrain::UpdateVertexArray(int whichx, int whichy)
278 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;
397 bool Terrain::load(const std::string& fileName)
401 static float patch_size;
403 float temptexdetail = texdetail;
408 if (!load_image(Folders::getResourcePath(fileName).c_str(), 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];
425 Game::LoadingScreen();
427 texdetail = temptexdetail;
429 size = texture.sizeX;
431 for (i = 0; i < size; i++) {
432 for (j = 0; j < size; j++) {
433 heightmap[size - 1 - i][j] = (float)((texture.data[(i + (j * size)) * texture.bpp / 8])) / 5;
437 Game::LoadingScreen();
441 for (i = 0; i < subdivision; i++) {
442 for (j = 0; j < subdivision; j++) {
443 textureness[i][j] = -1;
446 Game::LoadingScreen();
448 for (i = 0; i < size; i++) {
449 for (j = 0; j < size; j++) {
450 heightmap[i][j] *= .5;
452 texoffsetx[i][j] = (float)abs(Random() % 100) / 1200 / scale * 3;
453 texoffsety[i][j] = (float)abs(Random() % 100) / 1200 / scale * 3;
456 if (environment == snowyenvironment) {
457 if (j != 0 && heightmap[i][j] - heightmap[i][j - 1] > slopeness) {
458 slopeness = heightmap[i][j] - heightmap[i][j - 1];
460 opacityother[i][j] = slopeness * slopeness * 2;
461 if (opacityother[i][j] > 1)
462 opacityother[i][j] = 1;
463 opacityother[i][j] -= (float)abs(Random() % 100) / 300;
465 if (environment == desertenvironment) {
466 if (j != 0 && heightmap[i][j] - heightmap[i][j - 1] > slopeness) {
467 slopeness = heightmap[i][j] - heightmap[i][j - 1];
469 opacityother[i][j] = slopeness * slopeness * 2;
470 if (opacityother[i][j] > 1)
471 opacityother[i][j] = 1;
472 opacityother[i][j] -= (float)abs(Random() % 100) / 300;
474 if (environment == grassyenvironment) {
475 if (i != 0 && heightmap[i][j] - heightmap[i - 1][j] > slopeness) {
476 slopeness = heightmap[i][j] - heightmap[i - 1][j];
478 if (j != 0 && heightmap[i][j] - heightmap[i][j - 1] > slopeness) {
479 slopeness = heightmap[i][j] - heightmap[i][j - 1];
481 if (i < size - 1 && heightmap[i][j] - heightmap[i + 1][j] > slopeness) {
482 slopeness = heightmap[i][j] - heightmap[i + 1][j];
484 if (j < size - 1 && heightmap[i][j] - heightmap[i][j + 1] > slopeness) {
485 slopeness = heightmap[i][j] - heightmap[i][j + 1];
487 opacityother[i][j] = slopeness * slopeness * 10;
488 if (opacityother[i][j] > 1)
489 opacityother[i][j] = 1;
490 opacityother[i][j] -= (float)abs(Random() % 100) / 100;
494 Game::LoadingScreen();
496 for (i = 0; i < size; i++) {
497 for (j = 0; j < size; j++) {
498 if (environment == snowyenvironment) {
499 heightmap[i][j] -= opacityother[i][j];
501 if (environment == desertenvironment) {
502 heightmap[i][j] -= opacityother[i][j];
506 Game::LoadingScreen();
508 for (i = 0; i < size; i++) {
509 for (j = 0; j < size; j++) {
510 if (opacityother[i][j] < .1)
511 opacityother[i][j] = 0;
512 if (textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == -1) {
513 if (!opacityother[i][j])
514 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = allfirst;
515 if (opacityother[i][j] == 1)
516 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = allsecond;
518 if (opacityother[i][j] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
519 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
520 if (opacityother[i][j] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
521 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
527 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
528 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
529 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
530 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
531 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
532 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
533 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
534 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
538 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
539 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
540 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
541 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
542 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
543 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
544 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
545 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
551 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
552 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
553 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
554 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
555 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
556 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
557 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
558 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
566 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
567 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
568 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
569 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
570 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
571 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
572 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
573 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
577 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
578 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
579 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
580 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
581 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
582 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
583 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
584 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
590 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
591 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
592 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
593 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
594 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
595 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
596 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
597 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
605 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
606 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
607 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
608 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
609 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
610 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
611 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
612 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
618 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
619 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
620 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
621 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
622 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
623 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
624 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
625 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
630 Game::LoadingScreen();
632 patch_size = size / subdivision;
633 patch_elements = patch_size * patch_size * 54;
639 void Terrain::CalculateNormals()
642 static XYZ facenormal;
643 static XYZ p, q, a, b, c;
645 for (i = 0; i < size; i++) {
646 for (j = 0; j < size; j++) {
653 for (i = 0; i < size - 1; i++) {
654 for (j = 0; j < size - 1; j++) {
656 a.y = heightmap[i][j];
659 b.y = heightmap[i][j + 1];
662 c.y = heightmap[i + 1][j];
672 CrossProduct(&p, &q, &facenormal);
674 facenormals[i][j] = facenormal;
676 normals[i][j] = normals[i][j] + facenormal;
677 normals[i][j + 1] = normals[i][j + 1] + facenormal;
678 normals[i + 1][j] = normals[i + 1][j] + facenormal;
681 a.y = heightmap[i + 1][j];
684 b.y = heightmap[i][j + 1];
687 c.y = heightmap[i + 1][j + 1];
697 CrossProduct(&p, &q, &facenormal);
699 normals[i + 1][j + 1] = normals[i + 1][j + 1] + facenormal;
700 normals[i][j + 1] = normals[i][j + 1] + facenormal;
701 normals[i + 1][j] = normals[i + 1][j] + facenormal;
703 Normalise(&facenormals[i][j]);
707 for (i = 0; i < size; i++) {
708 for (j = 0; j < size; j++) {
709 Normalise(&normals[i][j]);
714 void Terrain::drawpatch(int whichx, int whichy, float opacity)
720 UpdateTransparency(whichx, whichy);
723 glColor4f(1, 1, 1, 1);
725 //Set up vertex array
726 glEnableClientState(GL_VERTEX_ARRAY);
727 glEnableClientState(GL_COLOR_ARRAY);
728 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
729 glVertexPointer(3, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[0 + whichx * patch_elements + whichy * patch_elements * subdivision]);
730 glColorPointer(4, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[3 + whichx * patch_elements + whichy * patch_elements * subdivision]);
731 glTexCoordPointer(2, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[7 + whichx * patch_elements + whichy * patch_elements * subdivision]);
734 glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy] * 3);
736 glDisableClientState(GL_VERTEX_ARRAY);
737 glDisableClientState(GL_COLOR_ARRAY);
738 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
741 void Terrain::drawpatchother(int whichx, int whichy, float opacity)
745 UpdateTransparency(whichx, whichy);
747 UpdateTransparencyother(whichx, whichy);
749 glColor4f(1, 1, 1, 1);
751 //Set up vertex array
752 glEnableClientState(GL_VERTEX_ARRAY);
753 glEnableClientState(GL_COLOR_ARRAY);
754 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
755 glVertexPointer(3, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[0 + whichx * patch_elements + whichy * patch_elements * subdivision]);
756 glColorPointer(4, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[3 + whichx * patch_elements + whichy * patch_elements * subdivision]);
757 glTexCoordPointer(2, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[7 + whichx * patch_elements + whichy * patch_elements * subdivision]);
760 glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy] * 3);
762 glDisableClientState(GL_VERTEX_ARRAY);
763 glDisableClientState(GL_COLOR_ARRAY);
764 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
767 void Terrain::drawpatchotherother(int whichx, int whichy)
770 UpdateTransparencyotherother(whichx, whichy);
772 glMatrixMode(GL_TEXTURE);
776 glColor4f(1, 1, 1, 1);
778 //Set up vertex array
779 glEnableClientState(GL_VERTEX_ARRAY);
780 glEnableClientState(GL_COLOR_ARRAY);
781 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
782 glVertexPointer(3, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[0 + whichx * patch_elements + whichy * patch_elements * subdivision]);
783 glColorPointer(4, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[3 + whichx * patch_elements + whichy * patch_elements * subdivision]);
784 glTexCoordPointer(2, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[7 + whichx * patch_elements + whichy * patch_elements * subdivision]);
787 glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy] * 3);
789 glDisableClientState(GL_VERTEX_ARRAY);
790 glDisableClientState(GL_COLOR_ARRAY);
791 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
794 glMatrixMode(GL_MODELVIEW);
797 float Terrain::getHeight(float pointx, float pointz)
799 static int tilex, tiley;
800 static XYZ startpoint, endpoint, intersect, triangle[3];
805 if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0)
808 startpoint.x = pointx;
809 startpoint.y = -1000;
810 startpoint.z = pointz;
812 endpoint = startpoint;
818 triangle[0].x = tilex;
819 triangle[0].z = tiley;
820 triangle[0].y = heightmap[tilex][tiley];
822 triangle[1].x = tilex + 1;
823 triangle[1].z = tiley;
824 triangle[1].y = heightmap[tilex + 1][tiley];
826 triangle[2].x = tilex;
827 triangle[2].z = tiley + 1;
828 triangle[2].y = heightmap[tilex][tiley + 1];
830 if (!LineFacetd(&startpoint, &endpoint, &triangle[0], &triangle[1], &triangle[2], &intersect)) {
831 triangle[0].x = tilex + 1;
832 triangle[0].z = tiley;
833 triangle[0].y = heightmap[tilex + 1][tiley];
835 triangle[1].x = tilex + 1;
836 triangle[1].z = tiley + 1;
837 triangle[1].y = heightmap[tilex + 1][tiley + 1];
839 triangle[2].x = tilex;
840 triangle[2].z = tiley + 1;
841 triangle[2].y = heightmap[tilex][tiley + 1];
842 LineFacetd(&startpoint, &endpoint, &triangle[0], &triangle[1], &triangle[2], &intersect);
844 return intersect.y * scale + getOpacity(pointx * scale, pointz * scale) / 8;
847 float Terrain::getOpacity(float pointx, float pointz)
849 static float height1, height2;
850 static int tilex, tiley;
855 if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0)
861 height1 = opacityother[tilex][tiley] * (1 - (pointx - tilex)) + opacityother[tilex + 1][tiley] * (pointx - tilex);
862 height2 = opacityother[tilex][tiley + 1] * (1 - (pointx - tilex)) + opacityother[tilex + 1][tiley + 1] * (pointx - tilex);
864 return height1 * (1 - (pointz - tiley)) + height2 * (pointz - tiley);
867 XYZ Terrain::getNormal(float pointx, float pointz)
869 static XYZ height1, height2, total;
870 static int tilex, tiley;
876 if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0)
881 height1 = normals[tilex][tiley] * (1 - (pointx - tilex)) + normals[tilex + 1][tiley] * (pointx - tilex);
882 height2 = normals[tilex][tiley + 1] * (1 - (pointx - tilex)) + normals[tilex + 1][tiley + 1] * (pointx - tilex);
883 total = height1 * (1 - (pointz - tiley)) + height2 * (pointz - tiley);
888 XYZ Terrain::getLighting(float pointx, float pointz)
890 static XYZ height1, height2;
891 static int tilex, tiley;
897 if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0)
902 height1.x = colors[tilex][tiley][0] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley][0] * (pointx - tilex);
903 height1.y = colors[tilex][tiley][1] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley][1] * (pointx - tilex);
904 height1.z = colors[tilex][tiley][2] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley][2] * (pointx - tilex);
905 height2.x = colors[tilex][tiley + 1][0] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley + 1][0] * (pointx - tilex);
906 height2.y = colors[tilex][tiley + 1][1] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley + 1][1] * (pointx - tilex);
907 height2.z = colors[tilex][tiley + 1][2] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley + 1][2] * (pointx - tilex);
909 return height1 * (1 - (pointz - tiley)) + height2 * (pointz - tiley);
912 void Terrain::draw(int layer)
915 static float opacity;
916 static XYZ terrainpoint;
917 static float distance[subdivision][subdivision];
919 static int beginx, endx;
920 static int beginz, endz;
922 static float patch_size = size / subdivision * scale;
923 static float viewdistsquared;
925 viewdistsquared = viewdistance * viewdistance;
928 beginx = ((viewer.x - viewdistance) / patch_size) - 1;
931 beginz = ((viewer.z - viewdistance) / patch_size) - 1;
935 endx = ((viewer.x + viewdistance) / patch_size) + 1;
936 if (endx > subdivision)
938 endz = ((viewer.z + viewdistance) / patch_size) + 1;
939 if (endz > subdivision)
943 for (i = beginx; i < endx; i++) {
944 for (j = beginz; j < endz; j++) {
945 terrainpoint.x = i * patch_size + (patch_size) / 2;
946 terrainpoint.y = viewer.y; //heightmap[i][j]*scale;
947 terrainpoint.z = j * patch_size + (patch_size) / 2;
948 distance[i][j] = distsq(&viewer, &terrainpoint);
952 for (i = beginx; i < endx; i++) {
953 for (j = beginz; j < endz; j++) {
954 if (distance[i][j] < (viewdistance + patch_size) * (viewdistance + patch_size)) {
956 if (distance[i][j] > viewdistsquared * fadestart - viewdistsquared)
958 if (opacity == 1 && i != subdivision)
959 if (distance[i + 1][j] > viewdistsquared * fadestart - viewdistsquared)
961 if (opacity == 1 && j != subdivision)
962 if (distance[i][j + 1] > viewdistsquared * fadestart - viewdistsquared)
964 if (opacity == 1 && j != subdivision && i != subdivision)
965 if (distance[i + 1][j + 1] > viewdistsquared * fadestart - viewdistsquared)
967 glMatrixMode(GL_MODELVIEW);
969 if (frustum.CubeInFrustum(i * patch_size + patch_size * .5, avgypatch[i][j], j * patch_size + patch_size * .5, heightypatch[i][j] / 2)) {
970 if (environment == desertenvironment && distance[i][j] > viewdistsquared / 4)
971 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, blurness);
972 else if (environment == desertenvironment)
973 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0);
974 if (!layer && textureness[i][j] != allsecond)
975 drawpatch(i, j, opacity);
976 if (layer == 1 && textureness[i][j] != allfirst)
977 drawpatchother(i, j, opacity);
978 if (layer == 2 && textureness[i][j] != allfirst)
979 drawpatchotherother(i, j);
985 if (environment == desertenvironment)
986 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0);
989 void Terrain::drawdecals()
992 static float distancemult;
995 static float viewdistsquared;
998 viewdistsquared = viewdistance * viewdistance;
1003 glDisable(GL_LIGHTING);
1004 glDisable(GL_CULL_FACE);
1005 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1007 for (unsigned int i = 0; i < decals.size(); i++) {
1008 if (decals[i].type == blooddecalfast && decals[i].alivetime < 2)
1009 decals[i].alivetime = 2;
1010 if (decals[i].type != lasttype) {
1011 if (decals[i].type == shadowdecal || decals[i].type == shadowdecalpermanent) {
1012 shadowtexture.bind();
1015 glAlphaFunc(GL_GREATER, 0.0001);
1016 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1019 if (decals[i].type == footprintdecal) {
1020 footprinttexture.bind();
1023 glAlphaFunc(GL_GREATER, 0.0001);
1024 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1027 if (decals[i].type == bodyprintdecal) {
1028 bodyprinttexture.bind();
1031 glAlphaFunc(GL_GREATER, 0.0001);
1032 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1035 if (decals[i].type == blooddecal || decals[i].type == blooddecalslow) {
1036 bloodtexture.bind();
1039 glAlphaFunc(GL_GREATER, 0.15);
1040 glBlendFunc(GL_ONE, GL_ZERO);
1043 if (decals[i].type == blooddecalfast) {
1044 bloodtexture2.bind();
1047 glAlphaFunc(GL_GREATER, 0.15);
1048 glBlendFunc(GL_ONE, GL_ZERO);
1052 if (decals[i].type == shadowdecal || decals[i].type == shadowdecalpermanent) {
1053 distancemult = (viewdistsquared - (distsq(&viewer, &decals[i].position) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
1054 if (distancemult >= 1)
1055 glColor4f(1, 1, 1, decals[i].opacity);
1056 if (distancemult < 1)
1057 glColor4f(1, 1, 1, decals[i].opacity * distancemult);
1059 if (decals[i].type == footprintdecal || decals[i].type == bodyprintdecal) {
1060 distancemult = (viewdistsquared - (distsq(&viewer, &decals[i].position) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
1061 if (distancemult >= 1) {
1062 glColor4f(1, 1, 1, decals[i].opacity);
1063 if (decals[i].alivetime > 3)
1064 glColor4f(1, 1, 1, decals[i].opacity * (5 - decals[i].alivetime) / 2);
1066 if (distancemult < 1) {
1067 glColor4f(1, 1, 1, decals[i].opacity * distancemult);
1068 if (decals[i].alivetime > 3)
1069 glColor4f(1, 1, 1, decals[i].opacity * (5 - decals[i].alivetime) / 2 * distancemult);
1072 if ((decals[i].type == blooddecal || decals[i].type == blooddecalfast || decals[i].type == blooddecalslow)) {
1073 distancemult = (viewdistsquared - (distsq(&viewer, &decals[i].position) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
1074 if (distancemult >= 1) {
1075 glColor4f(decals[i].brightness, decals[i].brightness, decals[i].brightness, decals[i].opacity);
1076 if (decals[i].alivetime < 4)
1077 glColor4f(decals[i].brightness, decals[i].brightness, decals[i].brightness, decals[i].opacity * decals[i].alivetime * .25);
1078 if (decals[i].alivetime > 58)
1079 glColor4f(decals[i].brightness, decals[i].brightness, decals[i].brightness, decals[i].opacity * (60 - decals[i].alivetime) / 2);
1081 if (distancemult < 1) {
1082 glColor4f(decals[i].brightness, decals[i].brightness, decals[i].brightness, decals[i].opacity * distancemult);
1083 if (decals[i].alivetime < 4)
1084 glColor4f(decals[i].brightness, decals[i].brightness, decals[i].brightness, decals[i].opacity * decals[i].alivetime * distancemult * .25);
1085 if (decals[i].alivetime > 58)
1086 glColor4f(decals[i].brightness, decals[i].brightness, decals[i].brightness, decals[i].opacity * (60 - decals[i].alivetime) / 2 * distancemult);
1089 lasttype = decals[i].type;
1090 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1091 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1093 glMatrixMode(GL_MODELVIEW);
1095 glBegin(GL_TRIANGLES);
1096 for (int j = 0; j < 3; j++) {
1097 glTexCoord2f(decals[i].texcoords[j][0], decals[i].texcoords[j][1]);
1098 glVertex3f(decals[i].vertex[j].x, decals[i].vertex[j].y, decals[i].vertex[j].z);
1103 for (int i = decals.size() - 1; i >= 0; i--) {
1104 decals[i].alivetime += multiplier;
1105 if (decals[i].type == blooddecalslow)
1106 decals[i].alivetime -= multiplier * 2 / 3;
1107 if (decals[i].type == blooddecalfast)
1108 decals[i].alivetime += multiplier * 4;
1109 if (decals[i].type == shadowdecal)
1111 if (decals[i].type == footprintdecal && decals[i].alivetime >= 5)
1113 if (decals[i].type == bodyprintdecal && decals[i].alivetime >= 5)
1115 if ((decals[i].type == blooddecal || decals[i].type == blooddecalfast || decals[i].type == blooddecalslow) && decals[i].alivetime >= 60)
1118 glAlphaFunc(GL_GREATER, 0.0001);
1122 void Terrain::deleteDeadDecals()
1124 for (int i = decals.size() - 1; i >= 0; i--) {
1125 if ((decals[i].type == blooddecal || decals[i].type == blooddecalslow) && decals[i].alivetime < 2) {
1131 void Terrain::AddObject(XYZ where, float radius, int id)
1134 if (id >= 0 && id < 10000) {
1135 for (int i = 0; i < subdivision; i++) {
1136 for (int j = 0; j < subdivision; j++) {
1137 if (patchobjects[i][j].size() < 300 - 1) {
1138 points[0].x = (size / subdivision) * i;
1139 points[0].z = (size / subdivision) * j;
1140 points[0].y = heightmap[(int)points[0].x][(int)points[0].z];
1141 points[1].x = (size / subdivision) * (i + 1);
1142 points[1].z = (size / subdivision) * (j + 1);
1143 points[1].y = heightmap[(int)points[1].x][(int)points[1].z];
1146 if (where.x + radius > points[0].x && where.x - radius < points[1].x && where.z + radius > points[0].z && where.z - radius < points[1].z) {
1147 patchobjects[i][j].push_back(id);
1155 void Terrain::DeleteDecal(int which)
1158 decals.erase(decals.begin() + which);
1162 void Terrain::MakeDecal(decal_type type, XYZ where, float size, float opacity, float rotation)
1165 if (opacity > 0 && size > 0) {
1166 static int patchx[4];
1167 static int patchy[4];
1169 patchx[0] = (where.x + size) / scale;
1170 patchx[1] = (where.x - size) / scale;
1171 patchx[2] = (where.x - size) / scale;
1172 patchx[3] = (where.x + size) / scale;
1174 patchy[0] = (where.z - size) / scale;
1175 patchy[1] = (where.z - size) / scale;
1176 patchy[2] = (where.z + size) / scale;
1177 patchy[3] = (where.z + size) / scale;
1179 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])) {
1180 MakeDecalLock(type, where, patchx[0], patchy[0], size, opacity, rotation);
1183 if ((patchx[1] != patchx[2] || patchy[1] != patchy[2]) && (patchx[1] != patchx[3] || patchy[1] != patchy[3])) {
1184 MakeDecalLock(type, where, patchx[1], patchy[1], size, opacity, rotation);
1187 if ((patchx[2] != patchx[3] || patchy[2] != patchy[3])) {
1188 MakeDecalLock(type, where, patchx[2], patchy[2], size, opacity, rotation);
1191 MakeDecalLock(type, where, patchx[3], patchy[3], size, opacity, rotation);
1196 void Terrain::MakeDecalLock(decal_type type, XYZ where, int whichx, int whichy, float size, float opacity, float rotation)
1199 XYZ rot = getLighting(where.x, where.z);
1200 float decalbright = (rot.x + rot.y + rot.z) / 3;
1202 if (decalbright < .4)
1205 if (environment == grassyenvironment) {
1209 if (decalbright > 1) {
1213 Decal decal(where, type, opacity, rotation, decalbright, whichx, whichy, size, *this, true);
1215 if (!(decal.texcoords[0][0] < 0 && decal.texcoords[1][0] < 0 && decal.texcoords[2][0] < 0))
1216 if (!(decal.texcoords[0][1] < 0 && decal.texcoords[1][1] < 0 && decal.texcoords[2][1] < 0))
1217 if (!(decal.texcoords[0][0] > 1 && decal.texcoords[1][0] > 1 && decal.texcoords[2][0] > 1))
1218 if (!(decal.texcoords[0][1] > 1 && decal.texcoords[1][1] > 1 && decal.texcoords[2][1] > 1))
1219 if (decals.size() < max_decals - 1)
1220 decals.push_back(decal);
1222 Decal decal2(where, type, opacity, rotation, decalbright, whichx, whichy, size, *this, false);
1224 if (!(decal2.texcoords[0][0] < 0 && decal2.texcoords[1][0] < 0 && decal2.texcoords[2][0] < 0))
1225 if (!(decal2.texcoords[0][1] < 0 && decal2.texcoords[1][1] < 0 && decal2.texcoords[2][1] < 0))
1226 if (!(decal2.texcoords[0][0] > 1 && decal2.texcoords[1][0] > 1 && decal2.texcoords[2][0] > 1))
1227 if (!(decal2.texcoords[0][1] > 1 && decal2.texcoords[1][1] > 1 && decal2.texcoords[2][1] > 1))
1228 if (decals.size() < max_decals - 1)
1229 decals.push_back(decal2);
1233 void Terrain::DoShadows()
1235 static XYZ testpoint, testpoint2, terrainpoint, lightloc, col;
1236 lightloc = light.location;
1237 if (!skyboxtexture) {
1241 if (skyboxtexture && Tutorial::active) {
1247 Normalise(&lightloc);
1249 for (short int i = 0; i < size; i++) {
1250 for (short int j = 0; j < size; j++) {
1251 terrainpoint.x = (float)i * scale;
1252 terrainpoint.z = (float)j * scale;
1253 terrainpoint.y = heightmap[i][j] * scale;
1256 patchx = (float)i * subdivision / size;
1257 patchz = (float)j * subdivision / size;
1258 if (patchobjects[patchx][patchz].size()) {
1259 for (unsigned int k = 0; k < patchobjects[patchx][patchz].size(); k++) {
1260 unsigned int l = patchobjects[patchx][patchz][k];
1261 if (Object::objects[l]->type != treetrunktype) {
1262 testpoint = terrainpoint;
1263 testpoint2 = terrainpoint + lightloc * 50 * (1 - shadowed);
1264 if (Object::objects[l]->model.LineCheck(&testpoint, &testpoint2, &col, &Object::objects[l]->position, &Object::objects[l]->yaw) != -1) {
1265 shadowed = 1 - (findDistance(&terrainpoint, &col) / 50);
1269 Game::LoadingScreen();
1271 float brightness = dotproduct(&lightloc, &normals[i][j]);
1273 brightness *= 1 - shadowed;
1280 colors[i][j][0] = light.color[0] * brightness + light.ambient[0];
1281 colors[i][j][1] = light.color[1] * brightness + light.ambient[1];
1282 colors[i][j][2] = light.color[2] * brightness + light.ambient[2];
1284 if (colors[i][j][0] > 1)
1285 colors[i][j][0] = 1;
1286 if (colors[i][j][1] > 1)
1287 colors[i][j][1] = 1;
1288 if (colors[i][j][2] > 1)
1289 colors[i][j][2] = 1;
1290 if (colors[i][j][0] < 0)
1291 colors[i][j][0] = 0;
1292 if (colors[i][j][1] < 0)
1293 colors[i][j][1] = 0;
1294 if (colors[i][j][2] < 0)
1295 colors[i][j][2] = 0;
1299 Game::LoadingScreen();
1302 for (short int i = 0; i < size; i++) {
1303 for (short int j = 0; j < size; j++) {
1304 for (short int k = 0; k < 3; k++) {
1306 unsigned int todivide = 0;
1308 total += colors[j][i - 1][k];
1311 if (i != size - 1) {
1312 total += colors[j][i + 1][k];
1316 total += colors[j - 1][i][k];
1319 if (j != size - 1) {
1320 total += colors[j + 1][i][k];
1323 if (i != 0 && j != 0) {
1324 total += colors[j - 1][i - 1][k];
1327 if (i != size - 1 && j != 0) {
1328 total += colors[j - 1][i + 1][k];
1331 if (j != size - 1 && i != size - 1) {
1332 total += colors[j + 1][i + 1][k];
1335 if (j != size - 1 && i != 0) {
1336 total += colors[j + 1][i - 1][k];
1339 total += colors[j][i][k];
1342 colors[j][i][k] = total / todivide;
1347 for (unsigned int i = 0; i < subdivision; i++) {
1348 for (unsigned int j = 0; j < subdivision; j++) {
1349 UpdateVertexArray(i, j);
1360 memset(heightmap, 0, sizeof(heightmap));
1361 memset(normals, 0, sizeof(normals));
1362 memset(facenormals, 0, sizeof(facenormals));
1363 memset(triangles, 0, sizeof(triangles));
1364 memset(colors, 0, sizeof(colors));
1365 memset(opacityother, 0, sizeof(opacityother));
1366 memset(texoffsetx, 0, sizeof(texoffsetx));
1367 memset(texoffsety, 0, sizeof(texoffsety));
1368 memset(numtris, 0, sizeof(numtris));
1369 memset(textureness, 0, sizeof(textureness));
1371 memset(vArray, 0, sizeof(vArray));
1373 memset(visible, 0, sizeof(visible));
1374 memset(avgypatch, 0, sizeof(avgypatch));
1375 memset(maxypatch, 0, sizeof(maxypatch));
1376 memset(minypatch, 0, sizeof(minypatch));
1377 memset(heightypatch, 0, sizeof(heightypatch));