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/Objects.hpp"
25 #include "Utils/Folders.hpp"
28 extern float viewdistance;
29 extern float fadestart;
30 extern int environment;
31 extern float texscale;
33 extern float multiplier;
34 extern FRUSTUM frustum;
35 extern float texdetail;
38 extern float blurness;
39 extern float targetblurness;
40 extern Objects objects;
41 extern bool visibleloading;
42 extern bool skyboxtexture;
43 extern int tutoriallevel;
47 int Terrain::lineTerrain(XYZ p1, XYZ p2, XYZ *p)
50 static float distance;
51 static float olddistance;
52 static int intersecting;
53 static int firstintersecting;
55 static int startx, starty;
56 static int endx, endy;
57 static float highest, lowest;
59 firstintersecting = -1;
93 for (i = startx; i <= endx; i++) {
94 for (j = starty; j <= endy; j++) {
97 for (k = 0; k < 2; k++) {
98 if (heightmap[i + k][j] > highest)
99 highest = heightmap[i + k][j];
100 if (heightmap[i + k][j] < lowest)
101 lowest = heightmap[i + k][j];
102 if (heightmap[i + k][j + 1] > highest)
103 highest = heightmap[i + k][j + 1];
104 if (heightmap[i + k][j + 1] < lowest)
105 lowest = heightmap[i + k][j + 1];
107 if ((p1.y <= highest || p2.y <= highest) && (p1.y >= lowest || p2.y >= lowest)) {
109 triangles[0].y = heightmap[i][j];
113 triangles[1].y = heightmap[i][j + 1];
114 triangles[1].z = j + 1;
116 triangles[2].x = i + 1;
117 triangles[2].y = heightmap[i + 1][j];
120 intersecting = LineFacet(p1, p2, triangles[0], triangles[1], triangles[2], &point);
121 distance = distsq(&p1, &point);
122 if ((distance < olddistance || firstintersecting == -1) && intersecting == 1) {
123 olddistance = distance;
124 firstintersecting = 1;
128 triangles[0].x = i + 1;
129 triangles[0].y = heightmap[i + 1][j];
133 triangles[1].y = heightmap[i][j + 1];
134 triangles[1].z = j + 1;
136 triangles[2].x = i + 1;
137 triangles[2].y = heightmap[i + 1][j + 1];
138 triangles[2].z = j + 1;
140 intersecting = LineFacet(p1, p2, triangles[0], triangles[1], triangles[2], &point);
141 distance = distsq(&p1, &point);
142 if ((distance < olddistance || firstintersecting == -1) && intersecting == 1) {
143 olddistance = distance;
144 firstintersecting = 1;
150 return firstintersecting;
153 void Terrain::UpdateTransparency(int whichx, int whichy)
156 static int i, j, a, b, c, d, patch_size, stepsize;
157 static float distance;
159 static float viewdistsquared;
161 viewdistsquared = viewdistance * viewdistance;
162 patch_size = size / subdivision;
165 c = whichx * patch_elements + whichy * patch_elements * subdivision;
167 for (i = patch_size * whichx; i < patch_size * (whichx + 1) + 1; i += stepsize) {
168 for (j = patch_size * whichy; j < patch_size * (whichy + 1) + 1; j += stepsize) {
169 if (i < size && j < size) {
170 vertex.x = i * scale;
171 vertex.z = j * scale;
172 vertex.y = heightmap[i][j] * scale;
173 distance = distsq(&viewer, &vertex);
174 if (distance > viewdistsquared)
175 distance = viewdistsquared;
176 colors[i][j][3] = (viewdistsquared - (distance - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
181 for (i = patch_size * whichx; i < patch_size * (whichx + 1); i += stepsize) {
182 for (j = patch_size * whichy; j < patch_size * (whichy + 1); j += stepsize) {
183 a = (i - (patch_size * whichx)) / stepsize;
184 b = (j - (patch_size * whichy)) / stepsize;
185 d = (a * 54) + (b * 54 * patch_size / stepsize);
186 vArray[d + c + 6] = colors[i][j][3];
188 vArray[d + c + 15] = colors[i][j + stepsize][3];
190 vArray[d + c + 24] = colors[i + stepsize][j][3];
192 vArray[d + c + 33] = colors[i + stepsize][j][3];
194 vArray[d + c + 42] = colors[i][j + stepsize][3];
196 vArray[d + c + 51] = colors[i + stepsize][j + stepsize][3];
201 void Terrain::UpdateTransparencyother(int whichx, int whichy)
203 static int i, j, a, b, c, d, patch_size, stepsize;
205 patch_size = size / subdivision;
208 c = whichx * patch_elements + whichy * patch_elements * subdivision;
210 for (i = patch_size * whichx; i < patch_size * (whichx + 1); i += stepsize) {
211 for (j = patch_size * whichy; j < patch_size * (whichy + 1); j += stepsize) {
212 a = (i - (patch_size * whichx)) / stepsize;
213 b = (j - (patch_size * whichy)) / stepsize;
214 d = (a * 54) + (b * 54 * patch_size / stepsize);
215 vArray[d + c + 6] = colors[i][j][3] * opacityother[i][j];
217 vArray[d + c + 15] = colors[i][j + stepsize][3] * opacityother[i][j + stepsize];
219 vArray[d + c + 24] = colors[i + stepsize][j][3] * opacityother[i + stepsize][j];
221 vArray[d + c + 33] = colors[i + stepsize][j][3] * opacityother[i + stepsize][j];
223 vArray[d + c + 42] = colors[i][j + stepsize][3] * opacityother[i][j + stepsize];
225 vArray[d + c + 51] = colors[i + stepsize][j + stepsize][3] * opacityother[i + stepsize][j + stepsize];
230 void Terrain::UpdateTransparencyotherother(int whichx, int whichy)
233 static int i, j, a, b, c, d, patch_size, stepsize;
234 static float distance;
236 static float viewdistsquared;
238 viewdistsquared = viewdistance * viewdistance;
239 patch_size = size / subdivision;
242 c = whichx * patch_elements + whichy * patch_elements * subdivision;
244 for (i = patch_size * whichx; i < patch_size * (whichx + 1) + 1; i += stepsize) {
245 for (j = patch_size * whichy; j < patch_size * (whichy + 1) + 1; j += stepsize) {
246 if (i < size && j < size) {
247 vertex.x = i * scale;
248 vertex.z = j * scale;
249 vertex.y = heightmap[i][j] * scale;
250 distance = distsq(&viewer, &vertex);
251 if (distance > viewdistsquared)
252 distance = viewdistsquared;
253 colors[i][j][3] = (viewdistsquared - (distance - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
258 for (i = patch_size * whichx; i < patch_size * (whichx + 1); i += stepsize) {
259 for (j = patch_size * whichy; j < patch_size * (whichy + 1); j += stepsize) {
260 a = (i - (patch_size * whichx)) / stepsize;
261 b = (j - (patch_size * whichy)) / stepsize;
262 d = (a * 54) + (b * 54 * patch_size / stepsize);
263 vArray[d + c + 6] = colors[i][j][3];
265 vArray[d + c + 15] = colors[i][j + stepsize][3];
267 vArray[d + c + 24] = colors[i + stepsize][j][3];
269 vArray[d + c + 33] = colors[i + stepsize][j][3];
271 vArray[d + c + 42] = colors[i][j + stepsize][3];
273 vArray[d + c + 51] = colors[i + stepsize][j + stepsize][3];
278 void Terrain::UpdateVertexArray(int whichx, int whichy)
280 static int i, j, a, b, c, patch_size, stepsize;
283 numtris[whichx][whichy] = 0;
285 patch_size = size / subdivision;
288 c = whichx * patch_elements + whichy * patch_elements * subdivision;
289 for (i = patch_size * whichx; i < patch_size * (whichx + 1); i += stepsize) {
290 for (j = patch_size * whichy; j < patch_size * (whichy + 1); j += stepsize) {
291 a = (i - ((float)size / subdivision * (float)whichx)) / stepsize;
292 b = (j - ((float)size / subdivision * (float)whichy)) / stepsize;
293 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 0] = i * scale;
294 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 1] = heightmap[i][j] * scale;
295 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 2] = j * scale;
296 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 3] = colors[i][j][0];
297 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 4] = colors[i][j][1];
298 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 5] = colors[i][j][2];
299 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 6] = colors[i][j][3];
300 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 7] = i * scale * texscale + texoffsetx[i][j];
301 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 8] = j * scale * texscale + texoffsety[i][j];
303 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 9] = i * scale;
304 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 10] = heightmap[i][j + stepsize] * scale;
305 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 11] = j * scale + stepsize * scale;
306 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 12] = colors[i][j + stepsize][0];
307 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 13] = colors[i][j + stepsize][1];
308 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 14] = colors[i][j + stepsize][2];
309 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 15] = colors[i][j + stepsize][3];
310 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 16] = i * scale * texscale + texoffsetx[i][j + stepsize];
311 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 17] = j * scale * texscale + stepsize * scale * texscale + texoffsety[i][j + stepsize];
313 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 18] = i * scale + stepsize * scale;
314 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 19] = heightmap[i + stepsize][j] * scale;
315 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 20] = j * scale;
316 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 21] = colors[i + stepsize][j][0];
317 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 22] = colors[i + stepsize][j][1];
318 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 23] = colors[i + stepsize][j][2];
319 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 24] = colors[i + stepsize][j][3];
320 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 25] = i * scale * texscale + stepsize * scale * texscale + texoffsetx[i + stepsize][j];
321 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 26] = j * scale * texscale + texoffsety[i + stepsize][j];
323 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 27] = i * scale + stepsize * scale;
324 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 28] = heightmap[i + stepsize][j] * scale;
325 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 29] = j * scale;
326 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 30] = colors[i + stepsize][j][0];
327 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 31] = colors[i + stepsize][j][1];
328 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 32] = colors[i + stepsize][j][2];
329 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 33] = colors[i + stepsize][j][3];
330 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 34] = i * scale * texscale + stepsize * scale * texscale + texoffsetx[i + stepsize][j];
331 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 35] = j * scale * texscale + texoffsety[i + stepsize][j];
333 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 36] = i * scale;
334 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 37] = heightmap[i][j + stepsize] * scale;
335 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 38] = j * scale + stepsize * scale;
336 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 39] = colors[i][j + stepsize][0];
337 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 40] = colors[i][j + stepsize][1];
338 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 41] = colors[i][j + stepsize][2];
339 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 42] = colors[i][j + stepsize][3];
340 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 43] = i * scale * texscale + texoffsetx[i][j + stepsize];
341 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 44] = j * scale * texscale + stepsize * scale * texscale + texoffsety[i][j + stepsize];
343 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 45] = i * scale + stepsize * scale;
344 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 46] = heightmap[i + stepsize][j + stepsize] * scale;
345 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 47] = j * scale + stepsize * scale;
346 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 48] = colors[i + stepsize][j + stepsize][0];
347 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 49] = colors[i + stepsize][j + stepsize][1];
348 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 50] = colors[i + stepsize][j + stepsize][2];
349 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 51] = colors[i + stepsize][j + stepsize][3];
350 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 52] = i * scale * texscale + stepsize * scale * texscale + texoffsetx[i + stepsize][j + stepsize];
351 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 53] = j * scale * texscale + stepsize * scale * texscale + texoffsety[i + stepsize][j + stepsize];
352 numtris[whichx][whichy] += 2;
356 maxypatch[whichx][whichy] = -10000;
357 minypatch[whichx][whichy] = 10000;
358 for (a = 0; a < size / subdivision; a++) {
359 for (b = 0; b < size / subdivision; b++) {
360 if (heightmap[(size / subdivision)*whichx + a][(size / subdivision)*whichy + b]*scale > maxypatch[whichx][whichy])
361 maxypatch[whichx][whichy] = heightmap[(size / subdivision) * whichx + a][(size / subdivision) * whichy + b] * scale;
362 if (heightmap[(size / subdivision)*whichx + a][(size / subdivision)*whichy + b]*scale < minypatch[whichx][whichy])
363 minypatch[whichx][whichy] = heightmap[(size / subdivision) * whichx + a][(size / subdivision) * whichy + b] * scale;
366 heightypatch[whichx][whichy] = (maxypatch[whichx][whichy] - minypatch[whichx][whichy]);
367 if (heightypatch[whichx][whichy] < size / subdivision * scale)
368 heightypatch[whichx][whichy] = size / subdivision * scale;
369 avgypatch[whichx][whichy] = (minypatch[whichx][whichy] + maxypatch[whichx][whichy]) / 2;
371 for (i = whichx * size / subdivision; i < (whichx + 1)*size / subdivision - 1; i++) {
372 for (j = whichy * size / subdivision; j < (whichy + 1)*size / subdivision - 1; j++) {
373 triangles[(i * (size - 1) * 2) + (j * 2)][0].x = i * scale;
374 triangles[(i * (size - 1) * 2) + (j * 2)][0].y = heightmap[i][j] * scale;
375 triangles[(i * (size - 1) * 2) + (j * 2)][0].z = j * scale;
377 triangles[(i * (size - 1) * 2) + (j * 2)][1].x = i * scale;
378 triangles[(i * (size - 1) * 2) + (j * 2)][1].y = heightmap[i][j + 1] * scale;
379 triangles[(i * (size - 1) * 2) + (j * 2)][1].z = j * scale + scale;
381 triangles[(i * (size - 1) * 2) + (j * 2)][2].x = i * scale + 1 * scale;
382 triangles[(i * (size - 1) * 2) + (j * 2)][2].y = heightmap[i + 1][j] * scale;
383 triangles[(i * (size - 1) * 2) + (j * 2)][2].z = j * scale;
385 triangles[(i * (size - 1) * 2) + (j * 2) + 1][0].x = i * scale + 1 * scale;
386 triangles[(i * (size - 1) * 2) + (j * 2) + 1][0].y = heightmap[i + 1][j] * scale;
387 triangles[(i * (size - 1) * 2) + (j * 2) + 1][0].z = j * scale;
389 triangles[(i * (size - 1) * 2) + (j * 2) + 1][1].x = i * scale;
390 triangles[(i * (size - 1) * 2) + (j * 2) + 1][1].y = heightmap[i][j + 1] * scale;
391 triangles[(i * (size - 1) * 2) + (j * 2) + 1][1].z = j * scale + 1 * scale;
393 triangles[(i * (size - 1) * 2) + (j * 2) + 1][2].x = i * scale + 1 * scale;
394 triangles[(i * (size - 1) * 2) + (j * 2) + 1][2].y = heightmap[i + 1][j + 1] * scale;
395 triangles[(i * (size - 1) * 2) + (j * 2) + 1][2].z = j * scale + 1 * scale;
402 bool Terrain::load(const std::string& fileName)
406 static float patch_size;
408 float temptexdetail = texdetail;
413 if (!load_image(Folders::getResourcePath(fileName).c_str(), texture)) {
418 if (texture.bpp > 24) {
419 int bytesPerPixel = texture.bpp / 8;
422 for (i = 0; i < (long)(texture.sizeY * texture.sizeX * bytesPerPixel); i++) {
424 texture.data[tempnum] = texture.data[i];
431 Game::LoadingScreen();
433 texdetail = temptexdetail;
435 size = texture.sizeX;
437 for (i = 0; i < size; i++) {
438 for (j = 0; j < size; j++) {
439 heightmap[size - 1 - i][j] = (float)((texture.data[(i + (j * size)) * texture.bpp / 8])) / 5;
444 Game::LoadingScreen();
448 for (i = 0; i < subdivision; i++) {
449 for (j = 0; j < subdivision; j++) {
450 textureness[i][j] = -1;
454 Game::LoadingScreen();
457 for (i = 0; i < size; i++) {
458 for (j = 0; j < size; j++) {
459 heightmap[i][j] *= .5;
461 texoffsetx[i][j] = (float)abs(Random() % 100) / 1200 / scale * 3;
462 texoffsety[i][j] = (float)abs(Random() % 100) / 1200 / scale * 3;
465 if (environment == snowyenvironment) {
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 == desertenvironment) {
475 if (j != 0 && heightmap[i][j] - heightmap[i][j - 1] > slopeness) {
476 slopeness = heightmap[i][j] - heightmap[i][j - 1];
478 opacityother[i][j] = slopeness * slopeness * 2;
479 if (opacityother[i][j] > 1)
480 opacityother[i][j] = 1;
481 opacityother[i][j] -= (float)abs(Random() % 100) / 300;
483 if (environment == grassyenvironment) {
484 if (i != 0 && heightmap[i][j] - heightmap[i - 1][j] > slopeness) {
485 slopeness = heightmap[i][j] - heightmap[i - 1][j];
487 if (j != 0 && heightmap[i][j] - heightmap[i][j - 1] > slopeness) {
488 slopeness = heightmap[i][j] - heightmap[i][j - 1];
490 if (i < size - 1 && heightmap[i][j] - heightmap[i + 1][j] > slopeness) {
491 slopeness = heightmap[i][j] - heightmap[i + 1][j];
493 if (j < size - 1 && heightmap[i][j] - heightmap[i][j + 1] > slopeness) {
494 slopeness = heightmap[i][j] - heightmap[i][j + 1];
496 opacityother[i][j] = slopeness * slopeness * 10;
497 if (opacityother[i][j] > 1)
498 opacityother[i][j] = 1;
499 opacityother[i][j] -= (float)abs(Random() % 100) / 100;
504 Game::LoadingScreen();
506 for (i = 0; i < size; i++) {
507 for (j = 0; j < size; j++) {
508 if (environment == snowyenvironment) {
509 heightmap[i][j] -= opacityother[i][j];
511 if (environment == desertenvironment) {
512 heightmap[i][j] -= opacityother[i][j];
517 Game::LoadingScreen();
519 for (i = 0; i < size; i++) {
520 for (j = 0; j < size; j++) {
521 if (opacityother[i][j] < .1)
522 opacityother[i][j] = 0;
523 if (textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == -1) {
524 if (!opacityother[i][j])
525 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = allfirst;
526 if (opacityother[i][j] == 1)
527 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = allsecond;
529 if (opacityother[i][j] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
530 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
531 if (opacityother[i][j] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
532 textureness[(int)(i * subdivision / size)][(int)(j * 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;
549 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
550 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
551 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
552 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
553 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
554 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
555 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
556 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
562 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
563 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
564 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
565 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
566 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
567 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
568 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
569 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;
588 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
589 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
590 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
591 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
592 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
593 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
594 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
595 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
601 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
602 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
603 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
604 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
605 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
606 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
607 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
608 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
616 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
617 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
618 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
619 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
620 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
621 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
622 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
623 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
629 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
630 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
631 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
632 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
633 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
634 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
635 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
636 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
643 Game::LoadingScreen();
645 patch_size = size / subdivision;
646 patch_elements = (patch_size) * (patch_size) * 54;
652 void Terrain::CalculateNormals()
655 static XYZ facenormal;
656 static XYZ p, q, a, b, c;
658 for (i = 0; i < size; i++) {
659 for (j = 0; j < size; j++) {
666 for (i = 0; i < size - 1; i++) {
667 for (j = 0; j < size - 1; j++) {
669 a.y = heightmap[i][j];
672 b.y = heightmap[i][j + 1];
675 c.y = heightmap[i + 1][j];
685 CrossProduct(&p, &q, &facenormal);
687 facenormals[i][j] = facenormal;
689 normals[i][j] = normals[i][j] + facenormal;
690 normals[i][j + 1] = normals[i][j + 1] + facenormal;
691 normals[i + 1][j] = normals[i + 1][j] + facenormal;
695 a.y = heightmap[i + 1][j];
698 b.y = heightmap[i][j + 1];
701 c.y = heightmap[i + 1][j + 1];
711 CrossProduct(&p, &q, &facenormal);
713 normals[i + 1][j + 1] = normals[i + 1][j + 1] + facenormal;
714 normals[i][j + 1] = normals[i][j + 1] + facenormal;
715 normals[i + 1][j] = normals[i + 1][j] + facenormal;
717 Normalise(&facenormals[i][j]);
721 for (i = 0; i < size; i++) {
722 for (j = 0; j < size; j++) {
723 Normalise(&normals[i][j]);
728 void Terrain::drawpatch(int whichx, int whichy, float opacity)
734 UpdateTransparency(whichx, whichy);
736 glColor4f(1, 1, 1, 1);
737 //Set up vertex array
738 glEnableClientState(GL_VERTEX_ARRAY);
739 glEnableClientState(GL_COLOR_ARRAY);
740 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
741 glVertexPointer(3, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[0 + whichx * patch_elements + whichy * patch_elements * subdivision]);
742 glColorPointer(4, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[3 + whichx * patch_elements + whichy * patch_elements * subdivision]);
743 glTexCoordPointer(2, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[7 + whichx * patch_elements + whichy * patch_elements * subdivision]);
746 glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy] * 3);
748 glDisableClientState(GL_VERTEX_ARRAY);
749 glDisableClientState(GL_COLOR_ARRAY);
750 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
753 void Terrain::drawpatchother(int whichx, int whichy, float opacity)
757 UpdateTransparency(whichx, whichy);
759 UpdateTransparencyother(whichx, whichy);
760 glColor4f(1, 1, 1, 1);
761 //Set up vertex array
762 glEnableClientState(GL_VERTEX_ARRAY);
763 glEnableClientState(GL_COLOR_ARRAY);
764 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
765 glVertexPointer(3, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[0 + whichx * patch_elements + whichy * patch_elements * subdivision]);
766 glColorPointer(4, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[3 + whichx * patch_elements + whichy * patch_elements * subdivision]);
767 glTexCoordPointer(2, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[7 + whichx * patch_elements + whichy * patch_elements * subdivision]);
770 glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy] * 3);
772 glDisableClientState(GL_VERTEX_ARRAY);
773 glDisableClientState(GL_COLOR_ARRAY);
774 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
777 void Terrain::drawpatchotherother(int whichx, int whichy, float opacity)
780 UpdateTransparencyotherother(whichx, whichy);
782 glMatrixMode(GL_TEXTURE);
786 glColor4f(1, 1, 1, 1);
788 //Set up vertex array
789 glEnableClientState(GL_VERTEX_ARRAY);
790 glEnableClientState(GL_COLOR_ARRAY);
791 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
792 glVertexPointer(3, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[0 + whichx * patch_elements + whichy * patch_elements * subdivision]);
793 glColorPointer(4, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[3 + whichx * patch_elements + whichy * patch_elements * subdivision]);
794 glTexCoordPointer(2, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[7 + whichx * patch_elements + whichy * patch_elements * subdivision]);
797 glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy] * 3);
799 glDisableClientState(GL_VERTEX_ARRAY);
800 glDisableClientState(GL_COLOR_ARRAY);
801 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
804 glMatrixMode(GL_MODELVIEW);
808 float Terrain::getHeight(float pointx, float pointz)
810 static int tilex, tiley;
811 static XYZ startpoint, endpoint, intersect, triangle[3];
816 if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0)
819 startpoint.x = pointx;
820 startpoint.y = -1000;
821 startpoint.z = pointz;
823 endpoint = startpoint;
829 triangle[0].x = tilex;
830 triangle[0].z = tiley;
831 triangle[0].y = heightmap[tilex][tiley];
833 triangle[1].x = tilex + 1;
834 triangle[1].z = tiley;
835 triangle[1].y = heightmap[tilex + 1][tiley];
837 triangle[2].x = tilex;
838 triangle[2].z = tiley + 1;
839 triangle[2].y = heightmap[tilex][tiley + 1];
841 if (!LineFacetd(&startpoint, &endpoint, &triangle[0], &triangle[1], &triangle[2], &intersect)) {
842 triangle[0].x = tilex + 1;
843 triangle[0].z = tiley;
844 triangle[0].y = heightmap[tilex + 1][tiley];
846 triangle[1].x = tilex + 1;
847 triangle[1].z = tiley + 1;
848 triangle[1].y = heightmap[tilex + 1][tiley + 1];
850 triangle[2].x = tilex;
851 triangle[2].z = tiley + 1;
852 triangle[2].y = heightmap[tilex][tiley + 1];
853 LineFacetd(&startpoint, &endpoint, &triangle[0], &triangle[1], &triangle[2], &intersect);
855 return intersect.y * scale + getOpacity(pointx * scale, pointz * scale) / 8;
858 float Terrain::getOpacity(float pointx, float pointz)
860 static float height1, height2;
861 static int tilex, tiley;
866 if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0)
872 height1 = opacityother[tilex][tiley] * (1 - (pointx - tilex)) + opacityother[tilex + 1][tiley] * (pointx - tilex);
873 height2 = opacityother[tilex][tiley + 1] * (1 - (pointx - tilex)) + opacityother[tilex + 1][tiley + 1] * (pointx - tilex);
875 return height1 * (1 - (pointz - tiley)) + height2 * (pointz - tiley);
878 XYZ Terrain::getNormal(float pointx, float pointz)
880 static XYZ height1, height2, total;
881 static int tilex, tiley;
887 if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0)
892 height1 = normals[tilex][tiley] * (1 - (pointx - tilex)) + normals[tilex + 1][tiley] * (pointx - tilex);
893 height2 = normals[tilex][tiley + 1] * (1 - (pointx - tilex)) + normals[tilex + 1][tiley + 1] * (pointx - tilex);
894 total = height1 * (1 - (pointz - tiley)) + height2 * (pointz - tiley);
899 XYZ Terrain::getLighting(float pointx, float pointz)
901 static XYZ height1, height2;
902 static int tilex, tiley;
908 if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0)
913 height1.x = colors[tilex][tiley][0] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley][0] * (pointx - tilex);
914 height1.y = colors[tilex][tiley][1] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley][1] * (pointx - tilex);
915 height1.z = colors[tilex][tiley][2] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley][2] * (pointx - tilex);
916 height2.x = colors[tilex][tiley + 1][0] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley + 1][0] * (pointx - tilex);
917 height2.y = colors[tilex][tiley + 1][1] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley + 1][1] * (pointx - tilex);
918 height2.z = colors[tilex][tiley + 1][2] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley + 1][2] * (pointx - tilex);
920 return height1 * (1 - (pointz - tiley)) + height2 * (pointz - tiley);
923 void Terrain::draw(int layer)
926 static float opacity;
927 static XYZ terrainpoint;
928 static float distance[subdivision][subdivision];
930 static int beginx, endx;
931 static int beginz, endz;
933 static float patch_size = size / subdivision * scale;
934 static float viewdistsquared;
936 viewdistsquared = viewdistance * viewdistance;
939 beginx = (viewer.x - viewdistance) / (patch_size) - 1;
942 beginz = (viewer.z - viewdistance) / (patch_size) - 1;
946 endx = (viewer.x + viewdistance) / (patch_size) + 1;
947 if (endx > subdivision)
949 endz = (viewer.z + viewdistance) / (patch_size) + 1;
950 if (endz > subdivision)
954 for (i = beginx; i < endx; i++) {
955 for (j = beginz; j < endz; j++) {
956 terrainpoint.x = i * patch_size + (patch_size) / 2;
957 terrainpoint.y = viewer.y; //heightmap[i][j]*scale;
958 terrainpoint.z = j * patch_size + (patch_size) / 2;
959 distance[i][j] = distsq(&viewer, &terrainpoint);
963 for (i = beginx; i < endx; i++) {
964 for (j = beginz; j < endz; j++) {
965 if (distance[i][j] < (viewdistance + patch_size) * (viewdistance + patch_size)) {
967 if (distance[i][j] > viewdistsquared * fadestart - viewdistsquared)
969 if (opacity == 1 && i != subdivision)
970 if (distance[i + 1][j] > viewdistsquared * fadestart - viewdistsquared)
972 if (opacity == 1 && j != subdivision)
973 if (distance[i][j + 1] > viewdistsquared * fadestart - viewdistsquared)
975 if (opacity == 1 && j != subdivision && i != subdivision)
976 if (distance[i + 1][j + 1] > viewdistsquared * fadestart - viewdistsquared)
978 glMatrixMode(GL_MODELVIEW);
980 if (frustum.CubeInFrustum(i * patch_size + patch_size * .5, avgypatch[i][j], j * patch_size + patch_size * .5, heightypatch[i][j] / 2)) {
981 if (environment == desertenvironment && distance[i][j] > viewdistsquared / 4)
982 glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, blurness);
983 else if (environment == desertenvironment)
984 glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
985 if (!layer && textureness[i][j] != allsecond)
986 drawpatch(i, j, opacity);
987 if (layer == 1 && textureness[i][j] != allfirst)
988 drawpatchother(i, j, opacity);
989 if (layer == 2 && textureness[i][j] != allfirst)
990 drawpatchotherother(i, j, opacity);
996 if (environment == desertenvironment)
997 glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
1000 void Terrain::drawdecals()
1004 static float distancemult;
1005 static int lasttype;
1007 static float viewdistsquared;
1010 viewdistsquared = viewdistance * viewdistance;
1015 glDisable(GL_LIGHTING);
1016 glDisable(GL_CULL_FACE);
1017 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1019 for (i = 0; i < numdecals; i++) {
1020 if (decaltype[i] == blooddecalfast && decalalivetime[i] < 2)
1021 decalalivetime[i] = 2;
1022 if ((decaltype[i] == shadowdecal || decaltype[i] == shadowdecalpermanent) && decaltype[i] != lasttype) {
1023 shadowtexture.bind();
1026 glAlphaFunc(GL_GREATER, 0.0001);
1027 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1030 if (decaltype[i] == footprintdecal && decaltype[i] != lasttype) {
1031 footprinttexture.bind();
1034 glAlphaFunc(GL_GREATER, 0.0001);
1035 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1038 if (decaltype[i] == bodyprintdecal && decaltype[i] != lasttype) {
1039 bodyprinttexture.bind();
1042 glAlphaFunc(GL_GREATER, 0.0001);
1043 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1046 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalslow) && decaltype[i] != lasttype) {
1047 bloodtexture.bind();
1050 glAlphaFunc(GL_GREATER, 0.15);
1051 glBlendFunc(GL_ONE, GL_ZERO);
1054 if ((decaltype[i] == blooddecalfast) && decaltype[i] != lasttype) {
1055 bloodtexture2.bind();
1058 glAlphaFunc(GL_GREATER, 0.15);
1059 glBlendFunc(GL_ONE, GL_ZERO);
1062 if (decaltype[i] == shadowdecal || decaltype[i] == shadowdecalpermanent) {
1063 distancemult = (viewdistsquared - (distsq(&viewer, &decalposition[i]) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
1064 if (distancemult >= 1)
1065 glColor4f(1, 1, 1, decalopacity[i]);
1066 if (distancemult < 1)
1067 glColor4f(1, 1, 1, decalopacity[i]*distancemult);
1069 if (decaltype[i] == footprintdecal || decaltype[i] == bodyprintdecal) {
1070 distancemult = (viewdistsquared - (distsq(&viewer, &decalposition[i]) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
1071 if (distancemult >= 1) {
1072 glColor4f(1, 1, 1, decalopacity[i]);
1073 if (decalalivetime[i] > 3)
1074 glColor4f(1, 1, 1, decalopacity[i] * (5 - decalalivetime[i]) / 2);
1076 if (distancemult < 1) {
1077 glColor4f(1, 1, 1, decalopacity[i]*distancemult);
1078 if (decalalivetime[i] > 3)
1079 glColor4f(1, 1, 1, decalopacity[i] * (5 - decalalivetime[i]) / 2 * distancemult);
1082 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow)) {
1083 distancemult = (viewdistsquared - (distsq(&viewer, &decalposition[i]) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
1084 if (distancemult >= 1) {
1085 glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]);
1086 if (decalalivetime[i] < 4)
1087 glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]*decalalivetime[i]*.25);
1088 if (decalalivetime[i] > 58)
1089 glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i] * (60 - decalalivetime[i]) / 2);
1091 if (distancemult < 1) {
1092 glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]*distancemult);
1093 if (decalalivetime[i] < 4)
1094 glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]*decalalivetime[i]*distancemult * .25);
1095 if (decalalivetime[i] > 58)
1096 glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i] * (60 - decalalivetime[i]) / 2 * distancemult);
1099 lasttype = decaltype[i];
1100 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1101 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1103 glMatrixMode(GL_MODELVIEW);
1105 glBegin(GL_TRIANGLES);
1106 for (int j = 0; j < 3; j++) {
1107 glTexCoord2f(decaltexcoords[i][j][0], decaltexcoords[i][j][1]);
1108 glVertex3f(decalvertex[i][j].x, decalvertex[i][j].y, decalvertex[i][j].z);
1113 for (i = numdecals - 1; i >= 0; i--) {
1114 decalalivetime[i] += multiplier;
1115 if (decaltype[i] == blooddecalslow)
1116 decalalivetime[i] -= multiplier * 2 / 3;
1117 if (decaltype[i] == blooddecalfast)
1118 decalalivetime[i] += multiplier * 4;
1119 if (decaltype[i] == shadowdecal)
1121 if (decaltype[i] == footprintdecal && decalalivetime[i] >= 5)
1123 if (decaltype[i] == bodyprintdecal && decalalivetime[i] >= 5)
1125 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow) && decalalivetime[i] >= 60)
1128 glAlphaFunc(GL_GREATER, 0.0001);
1132 void Terrain::AddObject(XYZ where, float radius, int id)
1137 if (id >= 0 && id < 10000)
1138 for (i = 0; i < subdivision; i++) {
1139 for (j = 0; j < subdivision; j++) {
1140 if (patchobjectnum[i][j] < 300 - 1) {
1142 points[0].x = (size / subdivision) * i;
1143 points[0].z = (size / subdivision) * j;
1144 points[0].y = heightmap[(int)points[0].x][(int)points[0].z];
1145 points[1].x = (size / subdivision) * (i + 1);
1146 points[1].z = (size / subdivision) * j;
1147 points[1].y = heightmap[(int)points[1].x][(int)points[1].z];
1148 points[2].x = (size / subdivision) * (i + 1);
1149 points[2].z = (size / subdivision) * (j + 1);
1150 points[2].y = heightmap[(int)points[2].x][(int)points[2].z];
1151 points[3].x = (size / subdivision) * i;
1152 points[3].z = (size / subdivision) * (j + 1);
1153 points[3].y = heightmap[(int)points[3].x][(int)points[3].z];
1158 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) {
1159 patchobjects[i][j][patchobjectnum[i][j]] = id;
1160 patchobjectnum[i][j]++;
1168 void Terrain::DeleteDecal(int which)
1171 decaltype[which] = decaltype[numdecals - 1];
1172 decalposition[which] = decalposition[numdecals - 1];
1173 for (int i = 0; i < 3; i++) {
1174 decalvertex[which][i] = decalvertex[numdecals - 1][i];
1175 decaltexcoords[which][i][0] = decaltexcoords[numdecals - 1][i][0];
1176 decaltexcoords[which][i][1] = decaltexcoords[numdecals - 1][i][1];
1178 decalrotation[which] = decalrotation[numdecals - 1];
1179 decalalivetime[which] = decalalivetime[numdecals - 1];
1180 decalopacity[which] = decalopacity[numdecals - 1];
1181 decalbrightness[which] = decalbrightness[numdecals - 1];
1186 void Terrain::MakeDecal(int type, XYZ where, float size, float opacity, float rotation)
1189 if (opacity > 0 && size > 0) {
1190 static int patchx[4];
1191 static int patchy[4];
1193 decaltexcoords[numdecals][0][0] = 1;
1194 decaltexcoords[numdecals][0][1] = 0;
1196 patchx[0] = (where.x + size) / scale;
1197 patchx[1] = (where.x - size) / scale;
1198 patchx[2] = (where.x - size) / scale;
1199 patchx[3] = (where.x + size) / scale;
1201 patchy[0] = (where.z - size) / scale;
1202 patchy[1] = (where.z - size) / scale;
1203 patchy[2] = (where.z + size) / scale;
1204 patchy[3] = (where.z + size) / scale;
1206 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])) {
1207 MakeDecalLock(type, where, patchx[0], patchy[0], size, opacity, rotation);
1210 if ((patchx[1] != patchx[2] || patchy[1] != patchy[2]) && (patchx[1] != patchx[3] || patchy[1] != patchy[3])) {
1211 MakeDecalLock(type, where, patchx[1], patchy[1], size, opacity, rotation);
1214 if ((patchx[2] != patchx[3] || patchy[2] != patchy[3])) {
1215 MakeDecalLock(type, where, patchx[2], patchy[2], size, opacity, rotation);
1217 MakeDecalLock(type, where, patchx[3], patchy[3], size, opacity, rotation);
1223 void Terrain::MakeDecalLock(int type, XYZ where, int whichx, int whichy, float size, float opacity, float rotation)
1226 static float placex, placez;
1231 rot = getLighting(where.x, where.z);
1232 decalbrightness[numdecals] = (rot.x + rot.y + rot.z) / 3;
1233 if (decalbrightness[numdecals] < .4)
1234 decalbrightness[numdecals] = .4;
1236 if (environment == grassyenvironment) {
1237 decalbrightness[numdecals] *= .6;
1240 if (decalbrightness[numdecals] > 1)
1241 decalbrightness[numdecals] = 1;
1242 decalbright = decalbrightness[numdecals];
1244 decalposition[numdecals] = where;
1245 decaltype[numdecals] = type;
1246 decalopacity[numdecals] = opacity;
1247 decalrotation[numdecals] = rotation;
1248 decalalivetime[numdecals] = 0;
1250 placex = (float)whichx * scale + scale;
1251 placez = (float)whichy * scale;
1253 decaltexcoords[numdecals][0][0] = (placex - where.x) / size / 2 + .5;
1254 decaltexcoords[numdecals][0][1] = (placez - where.z) / size / 2 + .5;
1256 decalvertex[numdecals][0].x = placex;
1257 decalvertex[numdecals][0].z = placez;
1258 decalvertex[numdecals][0].y = heightmap[whichx + 1][whichy] * scale + .01;
1261 placex = (float)whichx * scale + scale;
1262 placez = (float)whichy * scale + scale;
1264 decaltexcoords[numdecals][1][0] = (placex - where.x) / size / 2 + .5;
1265 decaltexcoords[numdecals][1][1] = (placez - where.z) / size / 2 + .5;
1267 decalvertex[numdecals][1].x = placex;
1268 decalvertex[numdecals][1].z = placez;
1269 decalvertex[numdecals][1].y = heightmap[whichx + 1][whichy + 1] * scale + .01;
1272 placex = (float)whichx * scale;
1273 placez = (float)whichy * scale + scale;
1275 decaltexcoords[numdecals][2][0] = (placex - where.x) / size / 2 + .5;
1276 decaltexcoords[numdecals][2][1] = (placez - where.z) / size / 2 + .5;
1278 decalvertex[numdecals][2].x = placex;
1279 decalvertex[numdecals][2].z = placez;
1280 decalvertex[numdecals][2].y = heightmap[whichx][whichy + 1] * scale + .01;
1282 if (decalrotation[numdecals]) {
1283 for (int i = 0; i < 3; i++) {
1285 rot.x = decaltexcoords[numdecals][i][0] - .5;
1286 rot.z = decaltexcoords[numdecals][i][1] - .5;
1287 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1288 decaltexcoords[numdecals][i][0] = rot.x + .5;
1289 decaltexcoords[numdecals][i][1] = rot.z + .5;
1293 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1294 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1295 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1296 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1))
1297 if (numdecals < max_decals - 1)
1300 decalbrightness[numdecals] = decalbright;
1302 decalposition[numdecals] = where;
1303 decaltype[numdecals] = type;
1304 decalopacity[numdecals] = opacity;
1305 decalrotation[numdecals] = rotation;
1306 decalalivetime[numdecals] = 0;
1308 placex = (float)whichx * scale + scale;
1309 placez = (float)whichy * scale;
1311 decaltexcoords[numdecals][0][0] = (placex - where.x) / size / 2 + .5;
1312 decaltexcoords[numdecals][0][1] = (placez - where.z) / size / 2 + .5;
1314 decalvertex[numdecals][0].x = placex;
1315 decalvertex[numdecals][0].z = placez;
1316 decalvertex[numdecals][0].y = heightmap[whichx + 1][whichy] * scale + .01;
1319 placex = (float)whichx * scale;
1320 placez = (float)whichy * scale;
1322 decaltexcoords[numdecals][1][0] = (placex - where.x) / size / 2 + .5;
1323 decaltexcoords[numdecals][1][1] = (placez - where.z) / size / 2 + .5;
1325 decalvertex[numdecals][1].x = placex;
1326 decalvertex[numdecals][1].z = placez;
1327 decalvertex[numdecals][1].y = heightmap[whichx][whichy] * scale + .01;
1330 placex = (float)whichx * scale;
1331 placez = (float)whichy * scale + scale;
1333 decaltexcoords[numdecals][2][0] = (placex - where.x) / size / 2 + .5;
1334 decaltexcoords[numdecals][2][1] = (placez - where.z) / size / 2 + .5;
1336 decalvertex[numdecals][2].x = placex;
1337 decalvertex[numdecals][2].z = placez;
1338 decalvertex[numdecals][2].y = heightmap[whichx][whichy + 1] * scale + .01;
1340 if (decalrotation[numdecals]) {
1341 for (int i = 0; i < 3; i++) {
1343 rot.x = decaltexcoords[numdecals][i][0] - .5;
1344 rot.z = decaltexcoords[numdecals][i][1] - .5;
1345 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1346 decaltexcoords[numdecals][i][0] = rot.x + .5;
1347 decaltexcoords[numdecals][i][1] = rot.z + .5;
1351 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1352 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1353 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1354 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1))
1355 if (numdecals < max_decals - 1)
1360 void Terrain::DoShadows()
1362 static int i, j, k, l, todivide;
1363 static float brightness, total;
1364 static XYZ testpoint, testpoint2, terrainpoint, lightloc, col;
1365 lightloc = light.location;
1366 if (!skyboxtexture) {
1370 if (skyboxtexture && tutoriallevel) {
1376 Normalise(&lightloc);
1378 for (i = 0; i < size; i++) {
1379 for (j = 0; j < size; j++) {
1380 terrainpoint.x = (float)(i) * scale;
1381 terrainpoint.z = (float)(j) * scale;
1382 terrainpoint.y = heightmap[i][j] * scale;
1385 patchx = (float)(i) * subdivision / size;
1386 patchz = (float)(j) * subdivision / size;
1387 if (patchobjectnum[patchx][patchz]) {
1388 for (k = 0; k < patchobjectnum[patchx][patchz]; k++) {
1389 l = patchobjects[patchx][patchz][k];
1390 if (objects.type[l] != treetrunktype) {
1391 testpoint = terrainpoint;
1392 testpoint2 = terrainpoint + lightloc * 50 * (1 - shadowed);
1393 if (objects.model[l].LineCheck(&testpoint, &testpoint2, &col, &objects.position[l], &objects.yaw[l]) != -1) {
1394 shadowed = 1 - (findDistance(&terrainpoint, &col) / 50);
1399 Game::LoadingScreen();
1401 brightness = dotproduct(&lightloc, &normals[i][j]);
1403 brightness *= 1 - shadowed;
1410 colors[i][j][0] = light.color[0] * brightness + light.ambient[0];
1411 colors[i][j][1] = light.color[1] * brightness + light.ambient[1];
1412 colors[i][j][2] = light.color[2] * brightness + light.ambient[2];
1414 if (colors[i][j][0] > 1) colors[i][j][0] = 1;
1415 if (colors[i][j][1] > 1) colors[i][j][1] = 1;
1416 if (colors[i][j][2] > 1) colors[i][j][2] = 1;
1417 if (colors[i][j][0] < 0) colors[i][j][0] = 0;
1418 if (colors[i][j][1] < 0) colors[i][j][1] = 0;
1419 if (colors[i][j][2] < 0) colors[i][j][2] = 0;
1424 Game::LoadingScreen();
1427 for (i = 0; i < size; i++) {
1428 for (j = 0; j < size; j++) {
1429 for (k = 0; k < 3; k++) {
1433 total += colors[j][i - 1][k];
1436 if (i != size - 1) {
1437 total += colors[j][i + 1][k];
1441 total += colors[j - 1][i][k];
1444 if (j != size - 1) {
1445 total += colors[j + 1][i][k];
1448 if (i != 0 && j != 0) {
1449 total += colors[j - 1][i - 1][k];
1452 if (i != size - 1 && j != 0) {
1453 total += colors[j - 1][i + 1][k];
1456 if (j != size - 1 && i != size - 1) {
1457 total += colors[j + 1][i + 1][k];
1460 if (j != size - 1 && i != 0) {
1461 total += colors[j + 1][i - 1][k];
1464 total += colors[j][i][k];
1467 colors[j][i][k] = total / todivide;
1472 for (i = 0; i < subdivision; i++) {
1473 for (j = 0; j < subdivision; j++) {
1474 UpdateVertexArray(i, j);
1483 memset(patchobjectnum, 0, sizeof(patchobjectnum));
1484 memset(patchobjects, 0, sizeof(patchobjects));
1488 memset(heightmap, 0, sizeof(heightmap));
1489 memset(normals, 0, sizeof(normals));
1490 memset(facenormals, 0, sizeof(facenormals));
1491 memset(triangles, 0, sizeof(triangles));
1492 memset(colors, 0, sizeof(colors));
1493 memset(opacityother, 0, sizeof(opacityother));
1494 memset(texoffsetx, 0, sizeof(texoffsetx));
1495 memset(texoffsety, 0, sizeof(texoffsety));
1496 memset(numtris, 0, sizeof(numtris));
1497 memset(textureness, 0, sizeof(textureness));
1499 memset(vArray, 0, sizeof(vArray));
1501 memset(visible, 0, sizeof(visible));
1502 memset(avgypatch, 0, sizeof(avgypatch));
1503 memset(maxypatch, 0, sizeof(maxypatch));
1504 memset(minypatch, 0, sizeof(minypatch));
1505 memset(heightypatch, 0, sizeof(heightypatch));
1509 memset(decaltexcoords, 0, sizeof(decaltexcoords));
1510 memset(decalvertex, 0, sizeof(decalvertex));
1511 memset(decaltype, 0, sizeof(decaltype));
1512 memset(decalopacity, 0, sizeof(decalopacity));
1513 memset(decalrotation, 0, sizeof(decalrotation));
1514 memset(decalalivetime, 0, sizeof(decalalivetime));
1515 memset(decalbrightness, 0, sizeof(decalbrightness));
1516 memset(decalposition, 0, sizeof(decalposition));
1521 terraintexture.destroy();
1522 shadowtexture.destroy();
1523 bodyprinttexture.destroy();
1524 footprinttexture.destroy();
1525 bloodtexture.destroy();
1526 bloodtexture2.destroy();
1527 breaktexture.destroy();