Initial commit

This commit is contained in:
Segey Lapin
2021-07-31 03:30:12 +03:00
commit 91cf9d2d34
249 changed files with 27582 additions and 0 deletions

View File

@@ -0,0 +1,232 @@
#include <cstdio>
#include "world_map_data.h"
#include "density_map.h"
void DensityMap::_get_property_list(List<PropertyInfo> *p_list) const
{
p_list->push_back(PropertyInfo(Variant::INT, "world/grid_size"));
p_list->push_back(PropertyInfo(Variant::INT, "world/clusters/count"));
if (grid_size == 0 || num_clusters == 0)
return;
p_list->push_back(PropertyInfo(Variant::INT, "world/size/x"));
p_list->push_back(PropertyInfo(Variant::INT, "world/size/y"));
p_list->push_back(PropertyInfo(Variant::INT, "world/size/z"));
if (world_x_size * world_y_size * world_z_size == 0U)
return;
p_list->push_back(PropertyInfo(Variant::INT, "world/clusters/seed"));
}
bool DensityMap::_get(const StringName &p_name, Variant &r_ret) const
{
if (p_name == "world/clusters/count") {
r_ret = num_clusters;
return true;
} else if (p_name == "world/clusters/seed") {
r_ret = seed;
return true;
} else if (p_name == "world/grid_size") {
r_ret = grid_size;
return true;
} else if (p_name == "world/size/x") {
r_ret = world_x_size;
return true;
} else if (p_name == "world/size/y") {
r_ret = world_y_size;
return true;
} else if (p_name == "world/size/z") {
r_ret = world_z_size;
return true;
}
const String pv = p_name.operator String();
return false;
}
bool DensityMap::_set(const StringName &p_name, const Variant &p_value)
{
bool update = false;
if (p_name == "world/clusters/count") {
num_clusters = p_value;
update = true;
} else if (p_name == "world/clusters/seed") {
seed = p_value;
update = true;
} else if (p_name == "world/grid_size") {
grid_size = p_value;
update = true;
} else if (p_name == "world/size/x") {
world_x_size = p_value;
update = true;
} else if (p_name == "world/size/y") {
world_y_size = p_value;
update = true;
} else if (p_name == "world/size/z") {
world_z_size = p_value;
update = true;
}
if (update) {
update_clusters();
_change_notify();
}
return update;
}
void DensityMap::populate_grid(List<struct area> &list)
{
}
void DensityMap::update_clusters()
{
int i;
clusters.clear();
regions.clear();
counties.clear();
cities.clear();
districts.clear();
circle_grid.clear();
if (num_clusters < 1)
return;
rnd->set_seed(seed);
world_center.x = world_x_size / 2;
world_center.y = world_y_size / 2;
world_center.z = world_z_size / 2;
if (world_x_size * world_y_size * world_z_size == 0)
return;
split_area(NULL, num_clusters, clusters);
for (i = 0; i < clusters.size(); i++) {
split_area(&clusters[i], num_regions, regions);
}
for (i = 0; i < regions.size(); i++) {
split_area(&regions[i], num_counties, counties);
}
for (i = 0; i < counties.size(); i++) {
split_area(&counties[i], num_cities, cities);
}
for (i = 0; i < cities.size(); i++) {
split_area(&cities[i], num_districts, districts);
}
WorldMapData *wmd = WorldMapData::get_singleton();
wmd->clear();
wmd->set_world_size(world_x_size, world_z_size);
#if 0
for (i = 0; i < clusters.size(); i++) {
wmd->add_circle(clusters[i].pos.x, clusters[i].pos.y, clusters[i].radius);
printf("cluster: %d x: %d y: %d radius: %f\n", i, clusters[i].pos.x, clusters[i].pos.y, clusters[i].radius);
}
#endif
for (i = 0; i < districts.size(); i++) {
wmd->add_circle(districts[i].pos.x, districts[i].pos.y, districts[i].radius);
printf("districts: %d x: %d y: %d radius: %f\n", i, districts[i].pos.x, districts[i].pos.y, districts[i].radius);
}
wmd->save_debug_image();
printf("num_clusters: %d - %d\n", (int)num_clusters, (int)clusters.size());
printf("num_regions: %d - %d\n", (int)num_regions, (int)regions.size());
printf("num_counties: %d - %d\n", (int)num_counties, (int)counties.size());
printf("num_cities: %d - %d\n", (int)num_cities, (int)cities.size());
printf("num_districts: %d - %d\n", (int)num_districts, (int)districts.size());
}
void DensityMap::split_area(struct area *area, int num_split, List<struct area> &list)
{
Vector2i pstart;
struct area astart;
float mrad;
int count = 500 * num_split;
int orig_size = (int)list.size();
if (area) {
pstart.x = area->pos.x;
pstart.y = area->pos.y;
#if 0
while (true) {
float angle = rnd->randf() * M_PI * 2.0f;
float off = rnd->randf() * area->radius;
float tx = cosf(angle) * off;
float ty = cosf(angle) * off;
int px = area->pos.x + (int)tx;
int py = area->pos.y + (int)ty;
if (px < 0 || px >= (int)world_x_size)
continue;
if (px < 0 || px >= (int)world_x_size)
continue;
pstart.x = px;
pstart.y = py;
break;
}
#endif
mrad = area->radius / (float)num_split;
} else {
pstart.x = rnd->randi() % world_x_size;
pstart.y = rnd->randi() % world_z_size;
mrad = sqrtf((float)world_x_size * (float)world_z_size) / (float)num_split;
mrad *= 0.9f;
pstart.x -= (int)mrad + 1;
pstart.y -= (int)mrad + 1;
}
astart.pos = pstart;
astart.radius = mrad;
astart.parent = area;
list.push_back(astart);
Vector2i cur(pstart.x, pstart.y);
while ((int)list.size() - orig_size < num_split && count-- > 0) {
float angle = rnd->randf() * M_PI * 2.0f;
float offt_x = cosf(angle) * mrad;
float offt_y = sinf(angle) * mrad;
int ox = (int)(cur.x + offt_x);
int oy = (int)(cur.y + offt_y);
if (ox < 0 || ox >= (int)world_x_size)
ox = (int)(cur.x - offt_x);
if (oy < 0 || ox >= (int)world_y_size)
oy = (int)(cur.y - offt_y);
if (area && !area->has_point(Vector2i(ox, oy)))
continue;
if (ox < 0 || ox >= (int)world_x_size)
continue;
if (oy < 0 || oy >= (int)world_z_size)
continue;
// printf("sample: %d %d %f\n", ox, oy, mrad);
const List<struct area>::Element *e = list.front();
bool good = true;
while (e) {
struct area a = e->get();
int oxd = ox - a.pos.x;
int oyd = oy - a.pos.y;
int r = oxd * oxd + oyd * oyd;
if (r < mrad * mrad) {
good = false;
break;
}
e = e->next();
}
if (good) {
struct area anext;
anext.pos.x = ox;
anext.pos.y = oy;
anext.radius = mrad;
anext.parent = area;
list.push_back(anext);
printf("result: %d %d %f\n", anext.pos.x, anext.pos.y, anext.radius);
}
}
if (count <= 0)
printf("list count %d\n", (int)list.size());
}
DensityMap::DensityMap()
{
rnd.instance();
rnd->randomize();
seed = rnd->get_seed();
world_x_size = 400000;
world_y_size = 1000;
world_z_size = 400000;
grid_size = 100;
num_clusters = 5;
num_regions = 15;
num_counties = 30;
num_cities = 5;
num_districts = 5;
}
DensityMap::~DensityMap()
{
}