mapgen_earth

This commit is contained in:
proller committed 2024-05-09 17:53:14 +02:00
1 parent fefbb53805
commit a4f487a891
9 files changed
+774 -1

No files matched your search

+2
View File
@@ -188,6 +188,8 @@ LOCAL_SRC_FILES += \
jni/src/log_types.cpp \
jni/src/mapgen_indev.cpp \
jni/src/mapgen_math.cpp \
jni/src/mapgen_earth.cpp \
jni/src/earth/hgt.cpp \
jni/src/threading/lock.cpp \
jni/src/threading/thread_vector.cpp \
jni/src/circuit.cpp \
+2 -1
View File
@@ -1,7 +1,8 @@
set(mapgen_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/mapgen_indev.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mapgen_math.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mapgen_earth.cpp
${CMAKE_CURRENT_SOURCE_DIR}/earth/hgt.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cavegen.cpp
${CMAKE_CURRENT_SOURCE_DIR}/dungeongen.cpp
+348
View File
@@ -0,0 +1,348 @@
/*
Copyright (C) 2024 proller <proler@gmail.com>
*/
/*
This file is part of Freeminer.
Freeminer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Freeminer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Freeminer. If not, see <http://www.gnu.org/licenses/>.
*/
// Some code got from https://github.com/zbycz/srtm-hgt-reader
#include "hgt.h"
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <fstream>
#include <ios>
#include <filesystem>
#include <iostream>
#include <math.h>
#include <sstream>
#include <string>
#include <sys/wait.h>
#include <thread>
#include <vector>
#include "debug/iostream_debug_helpers.h"
#include "filesys.h"
#include "httpfetch.h"
#include "log.h"
#include "settings.h"
#include "threading/concurrent_set.h"
#include "util/timetaker.h"
hgts::hgts(const std::string &folder) : folder{folder}
{
fs::CreateAllDirs(folder);
}
hgt *hgts::get(hgt::ll_t lat, hgt::ll_t lon)
{
if (map[lat].contains(lon)) {
return &map[lat][lon].value();
}
auto lock = std::unique_lock(mutex);
if (map[lat].contains(lon)) {
return &map[lat][lon].value();
}
// DUMP("insert", (long)this, lat, lon, folder, map.size(), map[lat].size());
map[lat][lon].emplace(folder, lat, lon).get(lat, lon);
return &map[lat][lon].value();
}
hgt::hgt(const std::string &folder, ll_t lat, ll_t lon) : folder{folder}
{
const int lat_dec = (int)floor(lat);
const int lon_dec = (int)floor(lon);
if (load(lat_dec, lon_dec)) {
static thread_local auto once = 0;
if (!once--)
DUMP("load failed", lat_dec, lon_dec);
}
}
std::basic_string<uint8_t> exec_to_string(const std::string &cmd)
{
std::array<uint8_t, 1000000> buffer;
std::basic_stringstream<uint8_t> result;
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
if (!pipe) {
throw std::runtime_error("popen() failed!");
}
size_t sz = 0;
while ((sz = read(pipe.get()->_fileno, buffer.data(),
static_cast<int>(buffer.size()))) > 0) {
result << std::basic_string<uint8_t>{buffer.data(), sz};
}
return result.str();
}
bool hgt::load(int lat_dec, int lon_dec)
{
//DUMP(lat_dec, lon_dec);
if (lat_loaded == lat_dec && lon_loaded == lon_dec) {
return false;
}
auto lock = std::unique_lock(mutex);
//DUMP(lat_dec, lon_dec);
if (lat_loaded == lat_dec && lon_loaded == lon_dec) {
return false;
}
if (lat_loading == lat_dec && lon_loading == lon_dec) {
//DUMP(lat_dec, lon_dec);
return true;
}
// DUMP((long)this, lat_dec, lon_dec, lat_loading, lon_loading, lat_loaded, lon_loaded);
TimeTaker timer("hgt load");
lat_loading = lat_dec;
lon_loading = lon_dec;
const auto gen_zip_name = [](int lat_dec, int lon_dec) {
std::string zipname;
if (lat_dec < 0) {
zipname += 'S';
zipname += char('A' + abs(ceil(lat_dec / 90.0 * 23)));
} else {
zipname += char('A' + abs(floor(lat_dec / 90.0 * 23)));
}
zipname += std::to_string(int(floor((((lon_dec + 180) / 360.0)) * 60) + 1));
return zipname;
};
#if GEN_TEST
{
size_t fails = 0;
for (const auto &t : {
std::pair{std::pair{36, 30}, "J36"},
std::pair{std::pair{39, 35}, "J36"},
std::pair{std::pair{36, 24}, "J35"},
std::pair{std::pair{39, 29}, "J35"},
std::pair{std::pair{40, 18}, "K34"},
std::pair{std::pair{80, 25}, "U26"},
std::pair{std::pair{83, 30}, "U26"},
std::pair{std::pair{68, 163}, "R03"}, // TODO!!!
std::pair{std::pair{70, 164}, "R03"},
}) {
std::string r;
if (r = gen_zip_name(t.first.first, t.first.second); t.second != r) {
DUMP("fail", t, r);
++fails;
}
}
DUMP(fails);
}
#endif
const auto zipname = gen_zip_name(lat_dec, lon_dec);
std::string zipfile = zipname + ".zip";
std::string zipfull = folder + "/" + zipfile;
std::string filename(255, 0);
sprintf(filename.data(), "%c%02d%c%03d.hgt", lat_dec > 0 ? 'N' : 'S', abs(lat_dec),
lon_dec > 0 ? 'E' : 'W', abs(lon_dec));
std::string filefull = folder + "/" + filename;
// DUMP(lat_dec, lon_dec, filename, zipname, zipfull);
std::basic_string<uint8_t> srtmTile;
size_t filesize = 0;
auto set_ratio = [&]() {
if (filesize == 2884802) {
seconds_per_px = 3;
} else if (filesize == 25934402) {
seconds_per_px = 1;
} else {
throw std::logic_error("unknown file size " + std::to_string(filesize));
}
side_length = sqrt(filesize >> 1);
};
// DUMP(filefull, zipfull);
if (!std::filesystem::exists(filefull) && !std::filesystem::exists(zipfull)) {
const auto http_to_file = [](const std::string &url, const std::string &zipfull) {
HTTPFetchRequest req;
req.url = url;
req.connect_timeout = req.timeout =
g_settings->getS32("curl_file_download_timeout");
actionstream << "Downloading map from " << req.url << "\n";
HTTPFetchResult res;
if (1) {
// TODO: why sync does not work?
req.caller = HTTPFETCH_SYNC;
httpfetch_sync(req, res);
} else {
req.caller = httpfetch_caller_alloc();
httpfetch_async(req);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
HTTPFetchResult res;
while (!httpfetch_async_get(req.caller, res)) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
httpfetch_caller_free(req.caller);
}
actionstream << req.url << " " << res.succeeded << " " << res.response_code
<< " " << res.data.size() << "\n";
if (!res.succeeded)
return uintmax_t{0};
if (!res.data.size())
return uintmax_t{0};
std::ofstream(zipfull) << res.data;
if (!std::filesystem::exists(zipfull))
return uintmax_t{0};
return std::filesystem::file_size(zipfull);
};
// TODO: https://viewfinderpanoramas.org/Coverage%20map%20viewfinderpanoramas_org15.htm
static concurrent_set<std::string> http_failed;
if (!http_failed.contains(zipfile))
if (!http_to_file("http://build.freeminer.org/earth/" + zipfile, zipfull))
if (!http_to_file(
"https://viewfinderpanoramas.org/dem1/" + zipfile, zipfull))
if (!http_to_file("https://viewfinderpanoramas.org/dem3/" + zipfile,
zipfull)) {
errorstream << "Not found " << zipfile << "\n"
<< "try to download manually: \n"
<< "curl -o " << zipfull
<< " https://viewfinderpanoramas.org/dem1/" << zipfile
<< " || " << "curl -o " << zipfull
<< " https://viewfinderpanoramas.org/dem3/" << zipfile
<< "\n";
http_failed.insert(zipfile);
}
}
if (!std::filesystem::exists(filefull) && std::filesystem::exists(zipfull)) {
// TODO: use some available in server and client zip lib to extract files
//auto fs = RenderingEngine::get_raw_device()->getFileSystem();
//bool ok = fs::extractZipFile(fs, zipfile, destination);
std::string cmd{"unzip -C -b -p " + zipfull + " " + zipname + "/" + filename};
srtmTile = exec_to_string(cmd);
filesize = srtmTile.size();
if (filesize) {
set_ratio();
}
}
// TODO: first try load unpached file, then unpack zip
if (srtmTile.empty()) {
if (!std::filesystem::exists(filename)) {
static thread_local auto once = 0;
if (!once++) {
std::cerr << "Missing file " << filename << " for " << lat_dec << ","
<< lon_dec << std::endl;
}
return true;
}
filesize = std::filesystem::file_size(filename);
set_ratio();
std::ifstream istrm(filename, std::ios::binary);
if (!istrm.good()) {
std::cerr << "Error opening " << filename << std::endl;
return true;
}
srtmTile.resize(filesize);
istrm.read(reinterpret_cast<char *>(srtmTile.data()), filesize);
}
if (srtmTile.empty()) {
static thread_local auto once = 0;
if (!once++) {
std::cerr << "Missing file " << filename << " " << zipname << " for "
<< lat_dec << "," << lon_dec << std::endl;
}
return true;
}
heights.resize(filesize >> 1);
for (uint32_t i = 0; i < filesize >> 1; ++i) {
int16_t height = (srtmTile[i << 1] << 8) | (srtmTile[(i << 1) + 1]);
if (height == -32768) {
height = 0;
}
heights[i] = height;
}
lat_loaded = lat_dec;
lon_loaded = lon_dec;
// DUMP("loadok", (long)this, heights.size(), lat_loaded, lon_loaded, filesize, zipname, filename, seconds_per_px, get(lat_dec, lon_dec));
return false;
}
/** Pixel idx from left bottom corner (0-1200) */
int16_t hgt::read(int16_t y, int16_t x)
{
const int row = (side_length - 1) - y;
const int col = x;
const int pos = (row * side_length + col);
return heights[pos];
}
float hgt::get(ll_t lat, ll_t lon)
{
const int lat_dec = (int)floor(lat);
const int lon_dec = (int)floor(lon);
if (lat_loaded != lat_dec || lon_loaded != lon_dec) {
// DUMP("notloaded", lat, lon, lat_dec, lon_dec, lat_loaded, lon_loaded, lat_loading, lon_loading, heights.size());
return {};
}
const ll_t lat_seconds = (lat - (ll_t)lat_dec) * 60 * 60;
const ll_t lon_seconds = (lon - (ll_t)lon_dec) * 60 * 60;
const int y = lat_seconds / seconds_per_px;
const int x = lon_seconds / seconds_per_px;
const int16_t height[] = {
read(y + 1, x),
read(y + 1, x + 1),
read(y, x),
read(y, x + 1),
};
// return height[2]; // debug not interpolated
// ratio where X lays
const float dy = fmod(lat_seconds, seconds_per_px) / seconds_per_px;
const float dx = fmod(lon_seconds, seconds_per_px) / seconds_per_px;
// Bilinear interpolation
// h0------------h1
// |
// |--dx-- .
// | |
// | dy
// | |
// h2------------h3
return height[0] * dy * (1 - dx) + height[1] * dy * (dx) +
height[2] * (1 - dy) * (1 - dx) + height[3] * (1 - dy) * dx;
}
+63
View File
@@ -0,0 +1,63 @@
/*
Copyright (C) 2024 proller <proler@gmail.com>
*/
/*
This file is part of Freeminer.
Freeminer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Freeminer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Freeminer. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <map>
#include <mutex>
#include <optional>
#include <string>
#include <vector>
class hgt
{
public:
using ll_t = float;
private:
uint16_t side_length = 0; // = 3601;
uint8_t seconds_per_px = 0;
const std::string folder;
int lat_loaded = 200;
int lon_loaded = 200;
int lat_loading = 200;
int lon_loading = 200;
std::mutex mutex; //, mutex2;
std::vector<int16_t> heights;
bool load(int lat_dec, int lon_dec);
int16_t read(int16_t y, int16_t x);
public:
hgt(const std::string &folder, ll_t lat, ll_t lon);
float get(ll_t lat, ll_t lon);
};
class hgts
{
std::map<int, std::map<int, std::optional<hgt>>> map;
const std::string folder;
std::mutex mutex;
public:
hgts(const std::string &folder);
hgt *get(hgt::ll_t lat, hgt::ll_t lon);
};
+6
View File
@@ -57,6 +57,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "log_types.h"
#include "mapgen_indev.h"
#include "mapgen_math.h"
#include "mapgen_earth.h"
#include "serverenvironment.h"
@@ -108,6 +109,7 @@ static MapgenDesc g_reg_mapgens[] = {
{"indev", true},
{"math", true},
{"earth", true},
};
static_assert(
@@ -186,6 +188,8 @@ Mapgen *Mapgen::createMapgen(MapgenType mgtype, MapgenParams *params,
return new MapgenIndev((MapgenIndevParams *)params, emerge);
case MAPGEN_MATH:
return new MapgenMath((MapgenMathParams *)params, emerge);
case MAPGEN_EARTH:
return new MapgenEarth((MapgenEarthParams *)params, emerge);
case MAPGEN_CARPATHIAN:
return new MapgenCarpathian((MapgenCarpathianParams *)params, emerge);
@@ -217,6 +221,8 @@ MapgenParams *Mapgen::createMapgenParams(MapgenType mgtype)
return new MapgenIndevParams;
case MAPGEN_MATH:
return new MapgenMathParams;
case MAPGEN_EARTH:
return new MapgenEarthParams;
case MAPGEN_CARPATHIAN:
return new MapgenCarpathianParams;
+1
View File
@@ -117,6 +117,7 @@ enum MapgenType {
MAPGEN_INDEV,
MAPGEN_MATH,
MAPGEN_EARTH,
MAPGEN_INVALID,
};
+270
View File
@@ -0,0 +1,270 @@
/*
Copyright (C) 2024 proller <proler@gmail.com>
*/
/*
This file is part of Freeminer.
Freeminer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Freeminer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Freeminer. If not, see <http://www.gnu.org/licenses/>.
*/
#include <cmath>
#include <cstdlib>
#include <string>
#include "debug/iostream_debug_helpers.h"
#include "filesys.h"
#include "irr_v2d.h"
#include "irrlichttypes.h"
#include "mapgen/earth/hgt.h"
#include "mapgen_earth.h"
#include "voxel.h"
#include "mapblock.h"
#include "mapnode.h"
#include "map.h"
#include "nodedef.h"
#include "voxelalgorithms.h"
#include "settings.h"
#include "emerge.h"
#include "serverenvironment.h"
#include "mg_biome.h"
#include "log_types.h"
void MapgenEarthParams::setDefaultSettings(Settings *settings)
{
settings->setDefault("mgearth_spflags", flagdesc_mapgen_v7, 0);
}
void MapgenEarthParams::readParams(const Settings *settings)
{
try {
MapgenV7Params::readParams(settings);
} catch (...) {
}
auto mg_earth = settings->getJson("mg_earth");
if (!mg_earth.isNull())
params = mg_earth;
}
void MapgenEarthParams::writeParams(Settings *settings) const
{
settings->setJson("mg_earth", params);
try {
MapgenV7Params::writeParams(settings);
} catch (...) {
}
}
///////////////////////////////////////////////////////////////////////////////
/*
// Utility function for converting degrees to radians
long double toRadians(const long double degree)
{
// cmath library in C++ defines the constant M_PI as the value of pi accurate to 1e-30
long double one_deg = (M_PI) / 180;
return (one_deg * degree);
}
long double distance(
long double lat1, long double long1, long double lat2, long double long2)
{
DUMP(lat1, long1, lat2, long2);
// Convert the latitudes and longitudes from degree to radians.
lat1 = toRadians(lat1);
long1 = toRadians(long1);
lat2 = toRadians(lat2);
long2 = toRadians(long2);
// Haversine Formula
long double dlong = long2 - long1;
long double dlat = lat2 - lat1;
long double ans =
pow(sin(dlat / 2), 2) + cos(lat1) * cos(lat2) * pow(sin(dlong / 2), 2);
ans = 2 * asin(sqrt(ans));
// Radius of Earth in Kilometers, R = 6371 Use R = 3956 for miles long double R =
// 6371;
constexpr double R{6378137.0};
// Calculate the result
ans = ans * R;
return ans;
}
*/
MapgenEarth::MapgenEarth(MapgenEarthParams *params_, EmergeParams *emerge) :
MapgenV7((MapgenV7Params *)params_, emerge),
hgt_reader(porting::path_share + DIR_DELIM + "earth")
{
ndef = emerge->ndef;
// mg_params = (MapgenEarthParams *)params_->sparams;
mg_params = params_;
Json::Value &params = mg_params->params;
if (params.get("light", 0).asBool())
this->flags &= ~MG_LIGHT;
n_air = MapNode(ndef->getId(params.get("air", "air").asString()), LIGHT_SUN);
n_water = MapNode(
ndef->getId(params.get("water_source", "mapgen_water_source").asString()),
LIGHT_SUN);
n_stone = MapNode(
ndef->getId(params.get("stone", "mapgen_stone").asString()), LIGHT_SUN);
if (params.get("center", Json::Value()).isObject())
center = {params["center"]["x"].asDouble(), params["center"]["y"].asDouble(),
params["center"]["z"].asDouble()};
if (params.get("scale", Json::Value()).isObject())
scale = {params["scale"]["x"].asDouble(), params["scale"]["y"].asDouble(),
params["scale"]["z"].asDouble()};
/* todomake test
static bool shown = 0;
if (!shown) {
shown = true;
std::vector<std::pair<int, int>> a{{0, 0}, {0, 1000}, {1000, 0}, {0, 30000},
{30000, 0}, {-30000, -30000}, {-30000, 30000}, {30000, -30000},
{30000, 30000}};
auto p0 = pos_to_ll(0, 0);
for (const auto &c : a) {
// auto p1 = posToLl(30000, 0);
// auto p2 = posToLl(0, 30000);
// auto p3 = posToLl(0, 0);
auto p = pos_to_ll(c.first, c.second);
auto dist1 = distance(p0.lat, p0.lon, p.lat, p.lon);
// auto dist2 = distance(p0.lat, p0.lat, p.lat, p.lon);
auto h = get_height(c.first, c.second);
DUMP(c.first, c.second, p0, p, dist1, h);
}
}
*/
/*
hgt_reader.debug = 1;
std::vector<std::pair<int, int>> a{
{0, 0}, {-30000, -30000}, {-30000, 30000}, {30000, -30000}, {30000, 30000}};
for (const auto &c : a) {
const auto tc = posToLl(c.first, c.second);
// DUMP(x, z, tc.lat, tc.lon, center);
// auto y = hgt_reader.srtmGetElevation(tc.lat, tc.lon);
// if (!(x % 100) && !(z % 100)) {
// auto url = std::string{"https://www.google.com/maps/@"} +
// std::to_string(tc.lat) +"," + std::to_string(tc.lon) + ",11z";
auto url = std::string{"https://yandex.ru/maps/?ll="} + std::to_string(tc.lon) +
"%2C" + std::to_string(tc.lat) + "&z=11";
auto h = getHeight(c.first, c.second);
DUMP(h, c.first, c.second, tc.lat, tc.lon, scale, center, url);
}
hgt_reader.debug = 0;
*/
}
MapgenEarth::~MapgenEarth()
{
}
//////////////////////// Map generator
MapNode MapgenEarth::layers_get(float value, float max)
{
auto layer_index = rangelim((unsigned int)myround((value / max) * layers_node_size),
0, layers_node_size - 1);
return layers_node[layer_index];
}
bool MapgenEarth::visible(const v3pos_t &p)
{
return p.Y < get_height(p.X, p.Z);
}
const MapNode &MapgenEarth::visible_content(const v3pos_t &p)
{
const auto v = visible(p);
const auto vw = visible_water_level(p);
if (!v && !vw)
return visible_transparent;
auto heat = 10;
heat += p.Y / -100; // upper=colder, lower=hotter, 3c per 1000
if (!v && p.Y < water_level)
return heat < 0 ? visible_ice : visible_water;
const auto humidity = 60;
return heat < 0 ? (humidity < 20 ? visible_surface : visible_surface_cold)
: heat < 10 ? visible_surface
: heat < 40 ? (humidity < 20 ? visible_surface_dry : visible_surface_green)
: visible_surface_hot;
}
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;
return {(ll_t)lat, (ll_t)lon};
}
pos_t MapgenEarth::get_height(pos_t x, pos_t z)
{
const auto tc = pos_to_ll(x, z);
auto y = hgt_reader.get(tc.lat, tc.lon)->get(tc.lat, tc.lon);
return y * scale.Y - center.Y;
}
int MapgenEarth::getSpawnLevelAtPoint(v2pos_t p)
{
return get_height(p.X, p.Y) + 2;
}
int MapgenEarth::generateTerrain()
{
MapNode n_ice(c_ice);
u32 index = 0;
v3pos_t em = vm->m_area.getExtent();
//auto zstride_1d = csize.X * (csize.Y + 1);
for (pos_t z = node_min.Z; z <= node_max.Z; z++) {
for (pos_t x = node_min.X; x <= node_max.X; x++, index++) {
s16 heat =
m_emerge->env->m_use_weather
? m_emerge->env->getServerMap().updateBlockHeat(m_emerge->env,
v3pos_t(x, node_max.Y, z), nullptr, &heat_cache)
: 0;
auto height = get_height(x, z);
u32 i = vm->m_area.index(x, node_min.Y, z);
for (pos_t y = node_min.Y; y <= node_max.Y; y++) {
// auto [have, d] = calc_point(x,y,z);
bool underground = height >= y;
if (underground) {
if (!vm->m_data[i]) {
vm->m_data[i] = layers_get(0, 1);
}
} else if (y <= water_level) {
vm->m_data[i] = (heat < 0 && y > heat / 3) ? n_ice : n_water;
} else {
vm->m_data[i] = n_air;
}
vm->m_area.add_y(em, i, 1);
}
}
}
return 0;
}
+81
View File
@@ -0,0 +1,81 @@
/*
Copyright (C) 2024 proller <proler@gmail.com>
*/
/*
This file is part of Freeminer.
Freeminer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Freeminer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Freeminer. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#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;
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 << ")";
return s;
}
struct MapgenEarthParams : public MapgenV7Params
{
MapgenEarthParams(){};
~MapgenEarthParams(){};
Json::Value params;
void readParams(const Settings *settings) override;
void writeParams(Settings *settings) const override;
void setDefaultSettings(Settings *settings) override;
};
class MapgenEarth : public MapgenV7
{
public:
MapgenEarthParams *mg_params;
virtual MapgenType getType() const override { return MAPGEN_EARTH; }
MapgenEarth(MapgenEarthParams *mg_params, EmergeParams *emerge);
~MapgenEarth();
virtual int generateTerrain() override;
int getSpawnLevelAtPoint(v2s16 p) override;
v3d scale{1, 1, 1};
v3d center{0, 0, 0};
bool no_layers = false;
MapNode n_air, n_water, n_stone;
MapNode layers_get(float value, float max);
bool visible(const v3pos_t &p) override;
const MapNode &visible_content(const v3pos_t &p) override;
hgts hgt_reader;
pos_t get_height(pos_t x, pos_t z);
ll pos_to_ll(pos_t x, pos_t z);
};
+1
View File
@@ -99,6 +99,7 @@ public:
virtual MapgenType getType() const { return MAPGEN_V7; }
virtual void makeChunk(BlockMakeData *data);
virtual
int getSpawnLevelAtPoint(v2s16 p);
float baseTerrainLevelAtPoint(s16 x, s16 z);