This commit is contained in:
proller committed 2024-08-11 02:47:29 +02:00
1 parent 6d83408a1c
commit c7e68bfa41
11 files changed
+299 -22

No files matched your search

+22
View File
@@ -731,6 +731,26 @@ if(ENABLE_TIFF AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/external/libtiff/CMakeList
set(USE_TIFF 1)
endif()
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/external/libosmium/CMakeLists.txt)
set(BUILD_TESTING 0 CACHE INTERNAL "")
set(BUILD_DATA_TESTS 0 CACHE INTERNAL "")
set(BUILD_EXAMPLES 0 CACHE INTERNAL "")
set(BUILD_BENCHMARKS 0 CACHE INTERNAL "")
add_subdirectory(external/libosmium)
set(OSMIUM_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/libosmium/include)
include_directories(BEFORE SYSTEM ${OSMIUM_INCLUDE_DIR})
find_package(BZip2)
if(BZIP2_FOUND)
set (OSMIUM_LIRARY ${OSMIUM_LIRARY} BZip2::BZip2)
endif()
find_package(EXPAT)
if(EXPAT_FOUND)
set (OSMIUM_LIRARY ${OSMIUM_LIRARY} EXPAT::EXPAT)
endif()
set(USE_OSMIUM 1)
message(STATUS "Using osmium: ${OSMIUM_INCLUDE_DIR} : ${OSMIUM_LIRARY}")
endif()
if (CMAKE_BUILD_TYPE STREQUAL "Debug" AND ${CMAKE_VERSION} VERSION_GREATER "3.11.0")
set(USE_DEBUG_HELPERS ON CACHE BOOL "")
endif()
@@ -995,6 +1015,7 @@ if(BUILD_CLIENT)
${SCTP_LIBRARY}
${WEBSOCKETPP_LIBRARY}
${TIFF_LIRARY}
${OSMIUM_LIRARY}
${LUA_BIT_LIBRARY}
${FREETYPE_LIBRARY}
@@ -1075,6 +1096,7 @@ if(BUILD_SERVER)
${SCTP_LIBRARY}
${WEBSOCKETPP_LIBRARY}
${TIFF_LIRARY}
${OSMIUM_LIRARY}
${LUA_LIBRARY}
${LUA_BIT_LIBRARY}
+1
View File
@@ -20,6 +20,7 @@
#cmakedefine01 USE_IPV4_DEFAULT
#cmakedefine01 USE_MANDELBULBER
#cmakedefine01 USE_MULTI
#cmakedefine01 USE_OSMIUM
#cmakedefine01 USE_SCTP
#cmakedefine01 USE_SQLITE3
#cmakedefine01 USE_TIFF
+4 -2
View File
@@ -740,10 +740,12 @@ void *EmergeThread::run()
m_mapgen = m_emerge->m_mapgens[id];
enable_mapgen_debug_info = m_emerge->enable_mapgen_debug_info;
try {
reg("EmergeThread" + itos(id), 5);
while (!stopRequested()) {
try {
BlockEmergeData bedata;
BlockMakeData bmdata;
EmergeAction action;
@@ -794,7 +796,6 @@ void *EmergeThread::run()
if (m_mapgen->heat_cache.size() > 1000) {
m_mapgen->heat_cache.clear();
m_mapgen->humidity_cache.clear();
}
}
} catch (VersionMismatchException &e) {
std::ostringstream err;
@@ -817,6 +818,7 @@ void *EmergeThread::run()
} catch (const std::exception &e) {
errorstream << m_name << ": exception at " << pos << " : " << e.what() << std::endl;
}
}
cancelPendingItems();
+7 -7
View File
@@ -895,10 +895,10 @@ bool height_gebco_tif::load(ll_t lat, ll_t lon)
return false;
}
std::tuple<size_t, size_t, ll_t, ll_t> height_gebco_tif::ll_to_xy(ll_t lat, ll_t lon)
std::tuple<size_t, size_t, height::ll_t, height::ll_t> height_gebco_tif::ll_to_xy(ll_t lat, ll_t lon)
{
const ll_t lat_seconds = (lat_loaded - lat) * 60 * 60;
const ll_t lon_seconds = (lon - lon_loaded) * 60 * 60;
const height::ll_t lat_seconds = (lat_loaded - lat) * 60 * 60;
const height::ll_t lon_seconds = (lon - lon_loaded) * 60 * 60;
const size_t y = ((lat_loaded - lat) * pixel_per_deg_y) - 1;
const size_t x = (lon - lon_loaded) * pixel_per_deg_x;
@@ -921,17 +921,17 @@ int16_t height_gebco_tif::read(uint16_t y, uint16_t x)
return heights[pos];
}
std::tuple<size_t, size_t, ll_t, ll_t> height_hgt::ll_to_xy(ll_t lat, ll_t lon)
std::tuple<size_t, size_t, height::ll_t, height::ll_t> height_hgt::ll_to_xy(height::ll_t lat, height::ll_t lon)
{
const ll_t lat_seconds = (lat - (ll_t)lat_loaded) * 60 * 60;
const ll_t lon_seconds = (lon - (ll_t)lon_loaded) * 60 * 60;
const height::ll_t lat_seconds = (lat - (ll_t)lat_loaded) * 60 * 60;
const height::ll_t lon_seconds = (lon - (ll_t)lon_loaded) * 60 * 60;
const int y = lat_seconds / seconds_per_px_y;
const int x = lon_seconds / seconds_per_px_x;
return {x, y, lat_seconds, lon_seconds};
}
std::tuple<size_t, size_t, ll_t, ll_t> height_tif::ll_to_xy(ll_t lat, ll_t lon)
std::tuple<size_t, size_t, height::ll_t, height::ll_t> height_tif::ll_to_xy(height::ll_t lat, height::ll_t lon)
{
const ll_t lat_seconds = (lat - (ll_t)lat_loaded) * 60 * 60;
const ll_t lon_seconds = (lon - (ll_t)lon_loaded) * 60 * 60;
+133
View File
@@ -0,0 +1,133 @@
class MyHandler : public osmium::handler::Handler
{
MapgenEarth *mg;
const bool todo{false};
public:
MyHandler(MapgenEarth *mg) : mg{mg} {}
void osm_object(const osmium::OSMObject &osm_object) const noexcept
{
}
void build_poly(const osmium::NodeRefList &a, short h, MapNode n)
{
const auto pos_ok = [&](const v2pos_t &pos) {
return (pos.X >= mg->node_min.X && pos.X < mg->node_max.X &&
pos.Y >= mg->node_min.Z && pos.Y < mg->node_max.Z);
};
v2pos_t prev_pos;
size_t prev_ok = 0;
for (const auto &node_ref : a) {
if (!node_ref.location())
continue;
{
v2pos_t pos = mg->ll_to_pos(
ll(node_ref.location().lat(), node_ref.location().lon()));
if (
!pos_ok(pos)) {
}
if (prev_ok && (pos_ok(pos) || pos_ok(prev_pos))) {
mg->bresenham(pos.X, pos.Y, prev_pos.X, prev_pos.Y,
mg->get_height(pos.X, pos.Y), h, n);
}
prev_pos = pos;
++prev_ok;
}
}
}
void way(const osmium::Way &way)
{
MapNode n;
pos_t h = 0;
if (way.tags().has_key("building")) {
if (const auto levels = way.tags().get_value_by_key("building:levels")) {
h = 4 * stoi(levels);
} else {
h = 8;
}
n = mg->c_cobble;
} else if (way.tags().has_key("highway") || way.tags().has_key("aeroway")) {
h = 1;
n = mg->c_cobble;
} else if (way.tags().has_key("barrier")) {
h = 2;
n = mg->c_cobble;
} else if (way.tags().has_key("natural") &&
way.tags().get_value_by_key("natural") == std::string{"coastline"}) {
h = 1;
n = mg->visible_surface_hot;
} else if (way.tags().has_key("waterway")) {
h = 1;
n = mg->n_water;
} else {
if (todo)
DUMP("skip", way.id(), way.tags());
return;
}
build_poly(way.nodes(), h, n);
void relation(const osmium::Relation &relation)
{
if (!relation.tags().has_key("building")) {
return;
}
for (const auto &sn : relation.subitems<osmium::Way>()) {
build_poly(sn.nodes(), 4, mg->visible_surface_dry);
}
}
};
class hdl : public handler_i
{
using index_t = osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type,
osmium::Location>;
using cache_t = osmium::handler::NodeLocationsForWays<index_t>;
index_t index;
cache_t cache{index};
const std::string path_name;
MapgenEarth *mg;
public:
hdl(MapgenEarth *mg, const std::string &path_name) :
path_name{path_name}, mg{mg}
{
cache.ignore_errors();
}
void apply() override
{
osmium::area::Assembler::config_type
assembler_config;
assembler_config.create_empty_areas = false;
// Initialize the MultipolygonManager. Its job is to collect all
// relations and member ways needed for each area. It then calls an
// instance of the osmium::area::Assembler class (with the given config)
// to actually assemble one area.
osmium::area::MultipolygonManager<osmium::area::Assembler> mp_manager{
assembler_config};
// We read the input file twice. In the first pass, only relations are
// read and fed into the multipolygon manager.
MyHandler handler{mg};
osmium::relations::read_relations(osmium::io::File{path_name}, mp_manager);
osmium::io::Reader reader{osmium::io::File{path_name, "pbf"}};
osmium::apply(reader, cache, handler,
mp_manager.handler([&handler](const osmium::memory::Buffer &area_buffer) {
osmium::apply(area_buffer, handler);
}));
}
};
+2
View File
@@ -323,6 +323,8 @@ public:
virtual bool generateCavernsNoise(s16 max_stone_y);
virtual void generateDungeons(s16 max_stone_y);
virtual void generateBuildings() {};
protected:
BiomeManager *m_bmgr;
+100 -1
View File
@@ -40,6 +40,19 @@ along with Freeminer. If not, see <http://www.gnu.org/licenses/>.
#include "serverenvironment.h"
#include "mg_biome.h"
#include "log_types.h"
#if USE_OSMIUM
#include <filesystem>
#include <osmium/area/assembler.hpp>
#include <osmium/area/multipolygon_manager.hpp>
#include <osmium/dynamic_handler.hpp>
#include <osmium/handler/node_locations_for_ways.hpp>
#include <osmium/index/map/sparse_mem_array.hpp>
#include <osmium/io/file.hpp>
#include <osmium/osm/entity_bits.hpp>
#include <osmium/osm/node.hpp>
#include <osmium/osm/way.hpp>
#include <osmium/tags/tags_filter.hpp>
#endif
void MapgenEarthParams::setDefaultSettings(Settings *settings)
{
@@ -176,6 +189,15 @@ MapgenEarth::MapgenEarth(MapgenEarthParams *params_, EmergeParams *emerge) :
}
hgt_reader.debug = 0;
*/
#if USE_OSMIUM
#include "earth/osmium-inl.h"
const auto path_name =
porting::path_cache + DIR_DELIM + "earth" + DIR_DELIM + "map.pbf";
if (std::filesystem::exists(path_name)) {
handler = std::make_unique<hdl>(this, path_name);
}
#endif
}
MapgenEarth::~MapgenEarth()
@@ -214,9 +236,9 @@ const MapNode &MapgenEarth::visible_content(const v3pos_t &p)
: visible_surface_hot;
}
constexpr double EQUATOR_LEN{40075696.0};
ll MapgenEarth::pos_to_ll(const pos_t x, const pos_t z)
{
constexpr double EQUATOR_LEN{40075696.0};
const auto lon = ((ll_t)x * scale.X) / (EQUATOR_LEN / 360) + center.X;
const auto lat = ((ll_t)z * scale.Z) / (EQUATOR_LEN / 360) + center.Z;
if (lat < 90 && lat > -90 && lon < 180 && lon > -180) {
@@ -226,6 +248,12 @@ ll MapgenEarth::pos_to_ll(const pos_t x, const pos_t z)
}
}
v2pos_t MapgenEarth::ll_to_pos(const ll &l)
{
return v2pos_t((l.lon / scale.X - center.X) * (EQUATOR_LEN / 360),
(l.lat / scale.Z - center.Z) * (EQUATOR_LEN / 360));
}
pos_t MapgenEarth::get_height(pos_t x, pos_t z)
{
const auto tc = pos_to_ll(x, z);
@@ -238,6 +266,69 @@ int MapgenEarth::getSpawnLevelAtPoint(v2pos_t p)
return std::max(2, get_height(p.X, p.Y) + 2);
}
// https://www.roguebasin.com/index.php?title=Bresenham%27s_Line_Algorithm
void MapgenEarth::bresenham(pos_t x1, pos_t y1, const pos_t x2, const pos_t y2, pos_t y,
pos_t h, const MapNode &n)
{
pos_t delta_x(x2 - x1);
// if x1 == x2, then it does not matter what we set here
const int8_t ix((delta_x > 0) - (delta_x < 0));
delta_x = std::abs(delta_x) << 1;
pos_t delta_y(y2 - y1);
// if y1 == y2, then it does not matter what we set here
const int8_t iy((delta_y > 0) - (delta_y < 0));
delta_y = std::abs(delta_y) << 1;
if (vm->exists({x1, y, y1})) {
for (pos_t yi = y; yi <= y + h; ++yi) {
vm->setNode({x1, yi, y1}, n);
}
}
if (delta_x >= delta_y) {
// error may go below zero
pos_t error(delta_y - (delta_x >> 1));
while (x1 != x2) {
// reduce error, while taking into account the corner case of error == 0
if ((error > 0) || (!error && (ix > 0))) {
error -= delta_x;
y1 += iy;
}
error += delta_y;
x1 += ix;
if (vm->exists({x1, y, y1})) {
for (pos_t yi = y; yi <= y + h; ++yi) {
vm->setNode({x1, yi, y1}, n);
}
}
}
} else {
// error may go below zero
int error(delta_x - (delta_y >> 1));
while (y1 != y2) {
// reduce error, while taking into account the corner case of error == 0
if ((error > 0) || (!error && (iy > 0))) {
error -= delta_y;
x1 += ix;
}
error += delta_x;
y1 += iy;
if (vm->exists({x1, y, y1})) {
for (pos_t yi = y; yi <= y + h; ++yi) {
vm->setNode({x1, yi, y1}, n);
}
}
}
}
}
int MapgenEarth::generateTerrain()
{
MapNode n_ice(c_ice);
@@ -270,3 +361,11 @@ int MapgenEarth::generateTerrain()
}
return 0;
}
void MapgenEarth::generateBuildings()
{
if (handler)
handler->apply();
}
+19 -3
View File
@@ -21,18 +21,21 @@ along with Freeminer. If not, see <http://www.gnu.org/licenses/>.
#pragma once
#include <memory>
#include "config.h"
#include "mapgen/earth/hgt.h"
#include "mapgen/mapgen.h"
#include "mapgen/mapgen_v7.h"
#include "json/json.h"
using ll_t = float;
//using ll_t = float;
using ll_t = double;
struct ll
{
ll_t lat = 0;
ll_t lon = 0;
};
inline std::ostream &operator<<(std::ostream &s, const ll &p)
{
s << "(" << p.lat << "," << p.lon << ")";
@@ -41,7 +44,6 @@ inline std::ostream &operator<<(std::ostream &s, const ll &p)
struct MapgenEarthParams : public MapgenV7Params
{
MapgenEarthParams(){};
~MapgenEarthParams(){};
@@ -52,16 +54,27 @@ struct MapgenEarthParams : public MapgenV7Params
void setDefaultSettings(Settings *settings) override;
};
class MapgenEarth;
class handler_i
{
public:
virtual void apply() = 0;
};
class MapgenEarth : public MapgenV7
{
public:
MapgenEarthParams *mg_params;
std::unique_ptr<handler_i> handler;
virtual MapgenType getType() const override { return MAPGEN_EARTH; }
MapgenEarth(MapgenEarthParams *mg_params, EmergeParams *emerge);
~MapgenEarth();
virtual int generateTerrain() override;
int generateTerrain() override;
void generateBuildings() override;
int getSpawnLevelAtPoint(v2pos_t p) override;
v3d scale{1, 1, 1};
@@ -78,4 +91,7 @@ public:
pos_t get_height(pos_t x, pos_t z);
ll pos_to_ll(pos_t x, pos_t z);
v2pos_t ll_to_pos(const ll &l);
void bresenham(
pos_t xa, pos_t za, pos_t xb, pos_t zb, pos_t y, pos_t h, const MapNode &n);
};
+5 -5
View File
@@ -108,14 +108,14 @@ public:
int zstride;
virtual MapgenType getType() const { return MAPGEN_INDEV; }
virtual MapgenType getType() const override { return MAPGEN_INDEV; }
MapgenIndev(MapgenIndevParams *params, EmergeParams *emerge);
~MapgenIndev();
virtual void calculateNoise();
int generateGround();
void generateCaves(int max_stone_y);
void generateExperimental();
void calculateNoise() override;
int generateGround() override;
void generateCaves(int max_stone_y) override;
void generateExperimental() override;
bool getFloatlandTerrainFromMap(int idx_xyz, float float_offset);
};
+4 -4
View File
@@ -55,13 +55,13 @@ class MapgenMath : public MapgenV7
public:
MapgenMathParams *mg_params;
virtual MapgenType getType() const override { return MAPGEN_MATH; }
MapgenType getType() const override { return MAPGEN_MATH; }
MapgenMath(MapgenMathParams *mg_params, EmergeParams *emerge);
~MapgenMath();
virtual void calculateNoise();
virtual int generateTerrain() override;
virtual void generateRidgeTerrain();
void calculateNoise();
int generateTerrain() override;
void generateRidgeTerrain();
//int getGroundLevelAtPoint(v2POS p);
bool internal;
+2
View File
@@ -419,6 +419,8 @@ void MapgenV7::makeChunk(BlockMakeData *data)
if (flags & MG_BIOMES)
dustTopNodes();
generateBuildings();
// Update liquids
updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);