23 { |
23 { |
24 } |
24 } |
25 |
25 |
26 Terrain::Terrain (PixelDimension width, PixelDimension height, int seed) : |
26 Terrain::Terrain (PixelDimension width, PixelDimension height, int seed) : |
27 terrain_buf(NULL), |
27 terrain_buf(NULL), |
28 width(width), |
28 width(width), height(height) |
29 height(height) |
|
30 { |
29 { |
31 // allocate+generate random terrain |
30 // allocate+generate random terrain |
32 generateTerrain(seed); |
31 generateTerrain(seed); |
|
32 } |
|
33 |
|
34 Terrain::Terrain (PixelDimension width, PixelDimension height, TerrainPixel *terrain_buf) : |
|
35 terrain_buf(terrain_buf), |
|
36 width(width), height(height) |
|
37 { |
|
38 // just generate the pixel buffer |
|
39 generatePixelBuffer(); |
33 } |
40 } |
34 |
41 |
35 Terrain::~Terrain (void) { |
42 Terrain::~Terrain (void) { |
36 // free terrain data |
43 // free terrain data |
37 delete[] terrain_buf; |
44 delete[] terrain_buf; |
344 } |
351 } |
345 } |
352 } |
346 } |
353 } |
347 |
354 |
348 /** |
355 /** |
349 * Gets the index of the given coordinate direction |
356 * Gets the index of the given coordinate direction referring to the DIRECTIONS table in Physics.hh |
350 * referring to the DIRECTIONS table in Physics.hh |
357 * |
|
358 * XXX: ugly little "lookup table" |
351 */ |
359 */ |
352 static int getDirectionIndex (Vector direction) { |
360 static int getDirectionIndex (Vector direction) { |
353 Vector dir = direction.roundToInt(); |
361 Vector dir = direction.roundToInt(); |
354 |
362 |
355 if (dir.x == 0 && dir.y == -1) { |
363 if (dir.x == 0 && dir.y == -1) { |
373 Engine::log(DEBUG, "Terrain.getDirectionIndex ") << "invalid direction: " << direction; |
381 Engine::log(DEBUG, "Terrain.getDirectionIndex ") << "invalid direction: " << direction; |
374 return 0; |
382 return 0; |
375 } |
383 } |
376 |
384 |
377 Vector Terrain::getNormal(Vector point, Vector prevPoint) const { |
385 Vector Terrain::getNormal(Vector point, Vector prevPoint) const { |
378 // XXX: cleanup |
386 // convert location to coordinate |
379 PixelCoordinate p = getPixelCoordinate(point); |
387 PixelCoordinate p = getPixelCoordinate(point); |
380 |
388 |
|
389 // sanity check |
381 assert(point != prevPoint); |
390 assert(point != prevPoint); |
382 |
391 |
383 Vector normal(0, 0); |
392 // round and subtract to get an integer direction vector, and turn this into a direction index |
384 |
|
385 // These two must be rounded separately |
|
386 int dirIdx = getDirectionIndex(prevPoint.roundToInt() - point.roundToInt()); |
393 int dirIdx = getDirectionIndex(prevPoint.roundToInt() - point.roundToInt()); |
387 |
394 |
388 normal += DIRECTIONS[dirIdx]; |
395 // always add our own direction to normal |
389 |
396 Vector normal = DIRECTIONS[dirIdx]; |
|
397 |
|
398 // check the two pixels clockwise from the impact direction |
390 for (int i = 1; i <= 2; i++) { |
399 for (int i = 1; i <= 2; i++) { |
391 if (getType(point + DIRECTIONS[(dirIdx + i + 8) % 8]) == TERRAIN_EMPTY) { |
400 if (getType(point + DIRECTIONS[(dirIdx + i + 8) % 8]) == TERRAIN_EMPTY) { |
392 normal += DIRECTIONS[(dirIdx + i + 8) % 8]; |
401 normal += DIRECTIONS[(dirIdx + i + 8) % 8]; |
393 } |
402 } |
394 } |
403 } |
395 |
404 |
|
405 // check the two pixels counterclockwise from the impact direction |
396 for (int i = 1; i <= 2; i++) { |
406 for (int i = 1; i <= 2; i++) { |
397 if (getType(point + DIRECTIONS[(dirIdx - i + 8) % 8]) == TERRAIN_EMPTY) { |
407 if (getType(point + DIRECTIONS[(dirIdx - i + 8) % 8]) == TERRAIN_EMPTY) { |
398 normal += DIRECTIONS[(dirIdx - i + 8) % 8]; |
408 normal += DIRECTIONS[(dirIdx - i + 8) % 8]; |
399 } |
409 } |
400 } |
410 } |
401 |
411 |
|
412 // sanity check |
402 if (getType(point) == TERRAIN_EMPTY || getType(prevPoint) != TERRAIN_EMPTY) { |
413 if (getType(point) == TERRAIN_EMPTY || getType(prevPoint) != TERRAIN_EMPTY) { |
403 Engine::log(DEBUG, "Physics.getNormal ") << "logic ground error"; |
414 Engine::log(DEBUG, "Physics.getNormal ") << "silly collision"; |
404 } |
415 } |
405 |
416 |
406 return normal; |
417 return normal; |
407 } |
418 } |
408 |
419 |