src/Terrain.cc
changeset 408 e6cfc44266af
parent 406 a2e35ca66c74
child 409 1a03ff151abc
equal deleted inserted replaced
407:443f6f7abcfb 408:e6cfc44266af
    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