Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Maps engines #1

Merged
merged 3 commits into from
May 10, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions copying.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ _the openage authors_ are:
| Niklas Fiekas | niklasf | niklas.fiekas@tu-clausthal.de |
| Charles Gould | charlesrgould | charles.r.gould@gmail.com |
| Wilco Kusee | detrumi | wilcokusee@gmail.com |
| Timo Haas | alue-42 | haastimo@gmx.de |

If you're a first-time commiter, add yourself to the above list. This is not
just for legal reasons, but also to keep an overview of all those nicknames.
Expand Down
1 change: 1 addition & 0 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ add_subdirectory("coord")
add_subdirectory("crossplatform")
add_subdirectory("datastructure")
add_subdirectory("log")
add_subdirectory("mapgen")
add_subdirectory("job")
add_subdirectory("keybinds")
add_subdirectory("pathfinding")
Expand Down
30 changes: 5 additions & 25 deletions cpp/game_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "game_save.h"
#include "keybinds/keybind_manager.h"
#include "log/log.h"
#include "mapgen/mapgen.h"
#include "terrain/terrain.h"
#include "unit/action.h"
#include "unit/command.h"
Expand All @@ -41,30 +42,6 @@ namespace openage {
* Please try to move out anything located in here and create engine features instead.
*/

// size of the initial terrain
constexpr coord::tile_delta terrain_data_size = {16, 16};

// terrain ids for the initial terrain
constexpr int terrain_data[16 * 16] = {
0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 2, 1, 15, 15, 15, 1,
0, 18, 18, 18, 18, 18, 0, 0, 16, 0, 2, 1, 15, 14, 15, 1,
18, 18, 0, 0, 18, 18, 0, 0, 16, 0, 2, 1, 15, 15, 15, 1,
18, 18, 0, 0, 18, 18, 0, 0, 16, 0, 2, 1, 1, 1, 2, 2,
18, 18, 18, 0, 18, 18, 9, 9, 16, 0, 0, 2, 2, 2, 0, 0,
18, 18, 0, 0, 0, 0, 9, 9, 16, 0, 0, 0, 0, 0, 0, 0,
0, 18, 0, 0, 0, 9, 9, 9, 16, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 2, 0, 9, 9, 0, 2, 2, 0, 0, 0, 0, 23, 23,
0, 0, 2, 15, 2, 9, 0, 2, 15, 15, 2, 0, 0, 0, 0, 0,
0, 0, 2, 15, 2, 2, 2, 15, 2, 2, 0, 0, 0, 0, 0, 0,
0, 0, 2, 15, 2, 2, 2, 15, 2, 0, 0, 0, 20, 20, 20, 0,
0, 2, 2, 15, 2, 2, 2, 14, 2, 0, 0, 0, 21, 21, 21, 0,
2, 15, 15, 15, 15, 15, 14, 14, 2, 0, 0, 0, 22, 22, 22, 0,
0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 5, 5, 5, 0,
0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 5, 5, 5, 5,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5
};


int run_game(Arguments *args) {
util::Timer timer;

Expand Down Expand Up @@ -144,7 +121,10 @@ GameMain::GameMain(Engine *engine)

// create the terrain which will be filled by chunks
this->terrain = std::make_shared<Terrain>(assetmanager, terrain_types, blending_modes, true);
this->terrain->fill(terrain_data, terrain_data_size);
// choose map engine
mapgen::MapGen mapgen{1,16,mapgen::MapGen::Engine::Mandelbrot};

this->terrain->fill(mapgen.generate(), mapgen.get_size());
this->placed_units.set_terrain(this->terrain);

// players
Expand Down
8 changes: 8 additions & 0 deletions cpp/mapgen/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
add_sources(${PROJECT_NAME}
mapgen.cpp
mapgenbase.cpp
)

add_subdirectory(static)
add_subdirectory(diamondsquare)
add_subdirectory(mandelbrot)
5 changes: 5 additions & 0 deletions cpp/mapgen/diamondsquare/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
add_sources(${PROJECT_NAME}
diamondsquare.cpp
land_gen.cpp
heightmap.cpp
)
39 changes: 39 additions & 0 deletions cpp/mapgen/diamondsquare/diamondsquare.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2015-2015 the openage authors. See copying.md for legal info.

#include <vector>

#include "diamondsquare.h"
#include "heightmap.h"
#include "../../log/log.h"
#include "../mapgen.h"
#include "../mapgenbase.h"

namespace openage {
namespace mapgen {


Diamondsquare::Diamondsquare(int chunks_per_side, int chunk_size)
:
MapGenBase(chunks_per_side,chunk_size) {}

int *Diamondsquare::generate() {
Heightmap heightmap(this->size);
heightmap.generate();

for (int y = 0; y < this->size.se; y++) {
for (int x = 0; x < this->size.ne; x++) {
float height = heightmap.tile(x, y);
int index = this->size.ne * y + x;
if (height > 0) {
this->map[index] = MapGen::Terrain::Dirt_1;
} else if (height == 0) {
this->map[index] = MapGen::Terrain::Water_Dark;
}
}
}

return this->map.data();
}

} // namespace mapgen
} // namespace openage
29 changes: 29 additions & 0 deletions cpp/mapgen/diamondsquare/diamondsquare.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2015-2015 the openage authors. See copying.md for legal info.

#ifndef OPENAGE_MAPGEN_DIAMONDSQUARE_H_
#define OPENAGE_MAPGEN_DIAMONDSQUARE_H_

#include <stddef.h>
#include <vector>

#include "../../coord/tile.h"
#include "../mapgenbase.h"

namespace openage {
namespace mapgen {


class Diamondsquare : public MapGenBase {
public:

Diamondsquare(int chunks_per_size, int chunk_size);
~Diamondsquare();

int *generate();

};

} // namespace mapgen
} // namespace openage

#endif
137 changes: 137 additions & 0 deletions cpp/mapgen/diamondsquare/heightmap.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// Copyright 2015-2015 the openage authors. See copying.md for legal info.

#include <cmath>
#include <ctime>

#include "heightmap.h"
#include "../../log/log.h"

namespace openage {
namespace mapgen {

Heightmap::Heightmap(coord::tile_delta size)
:
rng{(uint64_t)std::time(nullptr)} {

// Get the biggest side, and round it up to 2^n + 1
this->side_length = std::max(size.ne, size.se);
this->side_length = std::exp2(std::ceil(std::log2(static_cast<float>(this->side_length)))) + 1;

this->map.reserve(this->side_length * this->side_length);
}

std::vector<float> &Heightmap::generate() {
const float roughness = 1.5;

int dist = this->side_length - 1;
float displacement = 1;

// Initialize
this->tile(0, 0) = 0;
this->tile(dist, 0) = 0;
this->tile(0, dist) = 0;
this->tile(dist, dist) = 0;

while (dist > 1) {
log::log(MSG(dbg) << "dist = " << dist);
int mid = dist / 2;

// Diamond step: for each square, calculate the center from the corners
// (x-mid,y-mid) (x+mid,y-mid)
// \ /
// (x,y)
// / \
// (x-mid,y+mid) (x+mid,y+mid)
for (int y = mid; y < this->side_length; y += dist) {
for (int x = mid; x < this->side_length; x += dist) {
float diamond = 0;

// Add corner values
diamond += this->tile(x-mid, y-mid);
diamond += this->tile(x+mid, y-mid);
diamond += this->tile(x-mid, y+mid);
diamond += this->tile(x+mid, y+mid);

this->tile(x, y) = this->displace(diamond, 4, displacement);
log::log(MSG(dbg) << "diamond (" << x << "," << y << ") -> " << this->tile(x, y));
}
}

// Square step: for each diamond, calculate the center from the adjacent values
// (x,y-mid)
// |
// (x-mid,y) -- (x,y) -- (x+mid,y)
// |
// (x,y+mid)

// Handle tiles above and below diamond centers
for (int y = 0; y < this->side_length; y += dist) {
bool is_top = (y == 0);
bool is_bottom = (y == this->side_length - 1);
for (int x = mid; x < this->side_length; x += dist) {
float square = 0;
int neighbors = 2;

// Add neighbor values
if (!is_top) {
square += this->tile(x, y - mid);
neighbors++;
}
square += this->tile(x - mid, y);
square += this->tile(x + mid, y);
if (!is_bottom) {
square += this->tile(x, y + mid);
neighbors++;
}

this->tile(x, y) = this->displace(square, neighbors, displacement);
log::log(MSG(dbg) << "square1 (" << x << "," << y << ") -> " << this->tile(x, y));
}
}

// Handle tiles left and right of diamond centers
for (int y = mid; y < this->side_length; y += dist) {
for (int x = 0; x < this->side_length; x += dist) {
bool is_left = (x == 0);
bool is_right = (x == this->side_length - 1);

float square = 0;
int neighbors = 2;

// Add neighbor values
square += this->tile(x, y - mid);
if (!is_left) {
square += this->tile(x - mid, y);
neighbors++;
}
if (!is_right) {
square += this->tile(x + mid, y);
neighbors++;
}
square += this->tile(x, y + mid);

this->tile(x, y) = this->displace(square, neighbors, displacement);
log::log(MSG(dbg) << "square2 (" << x << "," << y << ") -> " << this->tile(x, y));
}
}

dist = mid;
displacement *= std::pow(2.0, -roughness);
}

return this->map;
}

float &Heightmap::tile(int x, int y) {
return this->map[this->side_length * y + x];
}

float Heightmap::displace(float value, int neighbors, float displacement) {
// Calculate average + offset
value /= neighbors;
value += this->rng.real_range(-displacement, displacement);
return value;
}

} // namespace mapgen
} // namespace openage
36 changes: 36 additions & 0 deletions cpp/mapgen/diamondsquare/heightmap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2015-2015 the openage authors. See copying.md for legal info.

#ifndef OPENAGE_MAPGEN_HEIGHTMAP_H_
#define OPENAGE_MAPGEN_HEIGHTMAP_H_

#include <vector>

#include "../../coord/tile.h"
#include "../../rng/rng.h"

namespace openage {
namespace mapgen {

/**
* Heightmap generation using the diamond-square algorithm
*/
class Heightmap {
public:
Heightmap(coord::tile_delta size);

std::vector<float> &generate();

float &tile(int x, int y);
private:
int side_length;

float displace(float value, int neighbors, float displacement);

std::vector<float> map;
rng::RNG rng;
};

} // namespace mapgen
} // namespace openage

#endif
11 changes: 11 additions & 0 deletions cpp/mapgen/diamondsquare/land_gen.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright 2015-2015 the openage authors. See copying.md for legal info.

#include "land_gen.h"
#include "heightmap.h"

namespace openage {
namespace mapgen {


} // namespace mapgen
} // namespace openage
18 changes: 18 additions & 0 deletions cpp/mapgen/diamondsquare/land_gen.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2015-2015 the openage authors. See copying.md for legal info.

#ifndef OPENAGE_MAPGEN_LAND_GEN_H_
#define OPENAGE_MAPGEN_LAND_GEN_H_

namespace openage {
namespace mapgen {

struct Land {
int terrain_type;

int land_percent;
};

} // namespace mapgen
} // namespace openage

#endif
3 changes: 3 additions & 0 deletions cpp/mapgen/mandelbrot/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
add_sources(${PROJECT_NAME}
mandelbrot.cpp
)
Loading