Updated world module (now voronoi roads work
This commit is contained in:
@@ -4,37 +4,26 @@
|
||||
|
||||
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"));
|
||||
// p_list->push_back(PropertyInfo(Variant::INT, "world/grid_size"));
|
||||
p_list->push_back(PropertyInfo(Variant::OBJECT, "noise", PROPERTY_HINT_RESOURCE_TYPE, "OpenSimplexNoise"));
|
||||
p_list->push_back(PropertyInfo(Variant::INT, "rnd_seed"));
|
||||
p_list->push_back(PropertyInfo(Variant::OBJECT, "curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"));
|
||||
p_list->push_back(PropertyInfo(Variant::OBJECT, "height_map", PROPERTY_HINT_RESOURCE_TYPE, "WorldHeightMap"));
|
||||
}
|
||||
|
||||
bool DensityMap::_get(const StringName &p_name, Variant &r_ret) const
|
||||
{
|
||||
if (p_name == "world/clusters/count") {
|
||||
r_ret = num_clusters;
|
||||
if (p_name == "noise") {
|
||||
r_ret = noise;
|
||||
return true;
|
||||
} else if (p_name == "world/clusters/seed") {
|
||||
} else if (p_name == "rnd_seed") {
|
||||
r_ret = seed;
|
||||
return true;
|
||||
} else if (p_name == "world/grid_size") {
|
||||
r_ret = grid_size;
|
||||
} else if (p_name == "curve") {
|
||||
r_ret = curve;
|
||||
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;
|
||||
} else if (p_name == "height_map") {
|
||||
r_ret = height_map;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -44,189 +33,66 @@ bool DensityMap::_get(const StringName &p_name, Variant &r_ret) const
|
||||
bool DensityMap::_set(const StringName &p_name, const Variant &p_value)
|
||||
{
|
||||
bool update = false;
|
||||
if (p_name == "world/clusters/count") {
|
||||
num_clusters = p_value;
|
||||
if (p_name == "noise") {
|
||||
noise = p_value;
|
||||
update = true;
|
||||
} else if (p_name == "world/clusters/seed") {
|
||||
} else if (p_name == "rnd_seed") {
|
||||
seed = p_value;
|
||||
update = true;
|
||||
} else if (p_name == "world/grid_size") {
|
||||
grid_size = p_value;
|
||||
} else if (p_name == "curve") {
|
||||
curve = 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;
|
||||
} else if (p_name == "height_map") {
|
||||
curve = p_value;
|
||||
update = true;
|
||||
}
|
||||
if (update) {
|
||||
update_clusters();
|
||||
update_all();
|
||||
_change_notify();
|
||||
}
|
||||
|
||||
return update;
|
||||
}
|
||||
|
||||
void DensityMap::populate_grid(List<struct area> &list)
|
||||
void DensityMap::update_all()
|
||||
{
|
||||
}
|
||||
|
||||
void DensityMap::update_clusters()
|
||||
{
|
||||
int i;
|
||||
clusters.clear();
|
||||
regions.clear();
|
||||
counties.clear();
|
||||
cities.clear();
|
||||
districts.clear();
|
||||
circle_grid.clear();
|
||||
if (num_clusters < 1)
|
||||
if (!curve.ptr() || !rnd.ptr() || !noise.ptr() || !height_map.ptr())
|
||||
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(®ions[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)
|
||||
void DensityMap::_bind_methods()
|
||||
{
|
||||
ClassDB::bind_method(D_METHOD("get_population_density", "x", "y"), &DensityMap::get_population_density);
|
||||
}
|
||||
float DensityMap::get_population_density(float x, float y)
|
||||
{
|
||||
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;
|
||||
}
|
||||
float n = (noise->get_noise_2d(x, y) + 1.0f) * 0.5f;
|
||||
float d = curve->interpolate_baked(n);
|
||||
#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());
|
||||
float h = height_map->get_surface_height(x, y);
|
||||
if (h < 0.0f || h > max_height)
|
||||
return 0.0f;
|
||||
float s = height_map->get_base_steepness(x, y);
|
||||
if (s > 0.3f)
|
||||
return 0.0f;
|
||||
float d = 0.0f;
|
||||
/* Still use curve for it? */
|
||||
if (h < max_height * 0.3f)
|
||||
d = 1.0f;
|
||||
else
|
||||
d = max_height * 0.3f / h;
|
||||
return d * s;
|
||||
}
|
||||
|
||||
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;
|
||||
max_height = 300.0f;
|
||||
}
|
||||
|
||||
DensityMap::~DensityMap()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user