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

[WIP] Map Engine #305

Closed
wants to merge 14 commits into from
13 changes: 13 additions & 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 Expand Up @@ -134,6 +135,18 @@ cmake modules ([3-clause BSD license](/legal/BSD-3-clause))
- `buildsystem/modules/FindGPerfTools.cmake` (taken from [VAST](https://github.com/mavam/vast))
- `buildsystem/modules/FindOpusfile.cmake` (taken from [Unvanquished](https://github.com/Unvanquished/Unvanquished))

From [libnoise](http://libnoise.sourceforge.net/) ([GPL 2.1](/legal/GPL 2.1 or later))
- `cpp/mapgen/perlinnoise/libnoise/basictypes.h`
- `cpp/mapgen/perlinnoise/libnoise/exception.h`
- `cpp/mapgen/perlinnoise/libnoise/interp.h`
- `cpp/mapgen/perlinnoise/libnoise/modulebase.cpp`
- `cpp/mapgen/perlinnoise/libnoise/modulebase.h`
- `cpp/mapgen/perlinnoise/libnoise/noisegen.cpp`
- `cpp/mapgen/perlinnoise/libnoise/noisegen.h`
- `cpp/mapgen/perlinnoise/libnoise/perlin.cpp`
- `cpp/mapgen/perlinnoise/libnoise/perlin.h`
- `cpp/mapgen/perlinnoise/libnoise/vectortable.h`

Notes about this file:

I (mic_e) am not a lawyer. This is an open-source project, we're doing this for
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
31 changes: 6 additions & 25 deletions cpp/game_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,30 +41,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 +120,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
map = new mapgen::MapGen(16,mapgen::MapGen::Engine::Perlin,0);

this->terrain->fill(map->getMap(), map->get_size());
this->placed_units.set_terrain(this->terrain);

// players
Expand Down Expand Up @@ -388,6 +367,8 @@ bool GameMain::on_input(SDL_Event *e) {
" SE " << std::setw(8) << mousepos_tile.se);

TerrainChunk *chunk = terrain->get_create_chunk(mousepos_tile);
log::log(MSG(dbg) << "adding Chunk at Position: (" << mousepos_tile.to_chunk().ne << "," << mousepos_tile.to_chunk().se << ")\n");
chunk->fill(map->getMap(mousepos_tile.to_chunk().ne, mousepos_tile.to_chunk().se),map->get_size());
chunk->get_data(mousepos_tile)->terrain_id = editor_current_terrain;
}
else if (clicking_active and e->button.button == SDL_BUTTON_RIGHT and !construct_mode) {
Expand Down
2 changes: 2 additions & 0 deletions cpp/game_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "coord/tile.h"
#include "handlers.h"
#include "keybinds/keybind_manager.h"
#include "mapgen/mapgen.h"
#include "player.h"
#include "terrain/terrain.h"
#include "terrain/terrain_object.h"
Expand Down Expand Up @@ -100,6 +101,7 @@ class GameMain :
*/
Command get_action(const coord::phys3 &pos) const;

mapgen::MapGen *map;
openage::Engine *engine;
};

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

add_subdirectory(static)
add_subdirectory(diamondsquare)
add_subdirectory(mandelbrot)
add_subdirectory(perlinnoise)
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 chunk_size, uint64_t seed)
:
MapGenBase(chunk_size, seed) {}

int *Diamondsquare::get_map(int32_t x, int32_t y) {
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_DIAMONDSQUARE_H_
#define OPENAGE_MAPGEN_DIAMONDSQUARE_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 chunk_size, uint64_t seed);
~Diamondsquare();

int *get_map(int32_t x, int32_t y);

};

} // 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_DIAMONDSQUARE_HEIGHTMAP_H_
#define OPENAGE_MAPGEN_DIAMONDSQUARE_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_DIAMONDSQUARE_LAND_GEN_H_
#define OPENAGE_MAPGEN_DIAMONDSQUARE_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