Refactored region growth
This commit is contained in:
@@ -59,15 +59,14 @@ public:
|
|||||||
const String &module_name);
|
const String &module_name);
|
||||||
void room_growth_module(flecs::world &ecs,
|
void room_growth_module(flecs::world &ecs,
|
||||||
const String &module_name);
|
const String &module_name);
|
||||||
|
void zones_graph_module(flecs::world &ecs,
|
||||||
|
const String &module_name);
|
||||||
void create_floor_components(
|
void create_floor_components(
|
||||||
flecs::entity floor_e, flecs::entity base_floor_e,
|
flecs::entity floor_e, flecs::entity base_floor_e,
|
||||||
const WorldEditor::components::buildings_layout_grid_size
|
const WorldEditor::components::buildings_layout_grid_size
|
||||||
&size);
|
&size);
|
||||||
void create_region(flecs::entity floor_e, flecs::entity seed_e,
|
|
||||||
flecs::entity region_e,
|
|
||||||
const Vector2i &position, float area);
|
|
||||||
bool check_region(flecs::entity floor_e, int index,
|
bool check_region(flecs::entity floor_e, int index,
|
||||||
const Rect2i &rect);
|
const Rect2i &rect) const;
|
||||||
graph_module(flecs::world &ecs);
|
graph_module(flecs::world &ecs);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -273,15 +273,13 @@ void BuildingLayoutGraph::graph_module::create_floor_components(
|
|||||||
floor_e.set<WorldEditor::components::buildings_layout_grid_floor>(
|
floor_e.set<WorldEditor::components::buildings_layout_grid_floor>(
|
||||||
{ Set<int>(), size.grid_size, size.growth_size });
|
{ Set<int>(), size.grid_size, size.growth_size });
|
||||||
floor_e.set<growth_regions>(
|
floor_e.set<growth_regions>(
|
||||||
{ Vector<struct growth_regions::region>() });
|
{ Vector<struct growth_regions::region>(), false });
|
||||||
floor_e.add<WorldEditor::components::belongs>(base_floor_e);
|
floor_e.add<WorldEditor::components::belongs>(base_floor_e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildingLayoutGraph::graph_module::create_region(flecs::entity floor_e,
|
void growth_regions::create_region(flecs::entity floor_e, flecs::entity seed_e,
|
||||||
flecs::entity seed_e,
|
|
||||||
flecs::entity region_e,
|
flecs::entity region_e,
|
||||||
const Vector2i &position,
|
const Vector2i &position, float area)
|
||||||
float area)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct growth_regions::region r;
|
struct growth_regions::region r;
|
||||||
@@ -291,8 +289,9 @@ void BuildingLayoutGraph::graph_module::create_region(flecs::entity floor_e,
|
|||||||
r.rect.size = Vector2i(1, 1);
|
r.rect.size = Vector2i(1, 1);
|
||||||
r.remains_area = MAX((int)(area * 2.0f) / 16 + 1, 16);
|
r.remains_area = MAX((int)(area * 2.0f) / 16 + 1, 16);
|
||||||
r.can_grow_square = true;
|
r.can_grow_square = true;
|
||||||
|
r.can_grow = true;
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
assert(check_region(floor_e, -1, r.rect));
|
assert(check_region(-1, r.rect));
|
||||||
const struct growth_regions *reg = floor_e.get<growth_regions>();
|
const struct growth_regions *reg = floor_e.get<growth_regions>();
|
||||||
for (i = 0; i < reg->regions.size(); i++) {
|
for (i = 0; i < reg->regions.size(); i++) {
|
||||||
if (reg->regions[i].region_et == r.region_et) {
|
if (reg->regions[i].region_et == r.region_et) {
|
||||||
@@ -307,91 +306,27 @@ void BuildingLayoutGraph::graph_module::create_region(flecs::entity floor_e,
|
|||||||
r.remains_area -= 1;
|
r.remains_area -= 1;
|
||||||
assert(ok);
|
assert(ok);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
|
floor_e.get_mut<growth_regions>()->complete = false;
|
||||||
floor_e.get_mut<growth_regions>()->regions.push_back(r);
|
floor_e.get_mut<growth_regions>()->regions.push_back(r);
|
||||||
floor_e.modified<growth_regions>();
|
floor_e.modified<growth_regions>();
|
||||||
flecs::log::warn("region created for %s",
|
flecs::log::warn("region created for %s",
|
||||||
region_e.path().c_str());
|
region_e.path().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BuildingLayoutGraph::graph_module::check_region(flecs::entity floor_e,
|
bool BuildingLayoutGraph::graph_module::check_region(flecs::entity floor_e,
|
||||||
int index,
|
int index,
|
||||||
const Rect2i &rect)
|
const Rect2i &rect) const
|
||||||
{
|
{
|
||||||
const Vector<growth_regions::region> ®ions =
|
const growth_regions *g = floor_e.get<growth_regions>();
|
||||||
floor_e.get<growth_regions>()->regions;
|
return g->check_region(index, rect);
|
||||||
int i;
|
|
||||||
bool ret = true;
|
|
||||||
for (i = 0; i < regions.size(); i++) {
|
|
||||||
if (i == index)
|
|
||||||
continue;
|
|
||||||
if (rect.intersects(regions[i].rect)) {
|
|
||||||
ret = false;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
void BuildingLayoutGraph::graph_module::zones_graph_module(
|
||||||
return ret;
|
flecs::world &ecs, const String &module_name)
|
||||||
}
|
|
||||||
|
|
||||||
BuildingLayoutGraph::graph_module::graph_module(flecs::world &ecs)
|
|
||||||
{
|
{
|
||||||
ecs.module<BuildingLayoutGraph::graph_module>();
|
|
||||||
ecs.import <flecs::stats>();
|
|
||||||
ecs.set<flecs::Rest>({});
|
|
||||||
ecs.component<WorldEditor::components::buildings_layout_graph>();
|
|
||||||
ecs.component<WorldEditor::components::buildings_layout_graph_node>();
|
|
||||||
ecs.component<WorldEditor::components::buildings_layout_base>();
|
|
||||||
ecs.component<WorldEditor::components::buildings_layout_room>();
|
|
||||||
ecs.component<WorldEditor::components::buildings_layout_zone>();
|
|
||||||
ecs.component<WorldEditor::components::buildings_layout_unit>();
|
|
||||||
ecs.component<WorldEditor::components::buildings_layout_floor>();
|
|
||||||
ecs.component<WorldEditor::components::buildings_layout_floor_index>()
|
|
||||||
.member<int>("index");
|
|
||||||
ecs.component<WorldEditor::components::buildings_layout_grid>();
|
|
||||||
ecs.component<WorldEditor::components::buildings_layout_grid_cell>();
|
|
||||||
ecs.component<WorldEditor::components::buildings_layout_grid_floor>();
|
|
||||||
ecs.component<WorldEditor::components::buildings_layout_grid_size>()
|
|
||||||
.member<int>("grid_size");
|
|
||||||
ecs.component<WorldEditor::components::buildings_layout_area>()
|
|
||||||
.member<float>("area");
|
|
||||||
ecs.component<WorldEditor::components::buildings_layout_order>()
|
|
||||||
.member<int>("index");
|
|
||||||
ecs.component<WorldEditor::components::belongs>();
|
|
||||||
#if 0
|
|
||||||
ecs.component<
|
|
||||||
WorldEditor::components::buildings_layout_commands::command>()
|
|
||||||
.member<int>("command")
|
|
||||||
.member<Vector<Variant> >("args");
|
|
||||||
ecs.component<WorldEditor::components::buildings_layout_commands>()
|
|
||||||
.member<WorldEditor::components::buildings_layout_commands::
|
|
||||||
command>("commands");
|
|
||||||
#endif
|
|
||||||
ecs.component<WorldEditor::components::buildings_layout_commands>();
|
|
||||||
// get_layout_grid_base();
|
|
||||||
// BuildingLayoutGraph::get_singleton()->get_layout_grid_base();
|
|
||||||
const String &module_name = "::BuildingLayoutGraph::graph_module";
|
|
||||||
flecs::entity GraphSolveZones = ecs.entity("GraphSolveZones")
|
flecs::entity GraphSolveZones = ecs.entity("GraphSolveZones")
|
||||||
.add(flecs::Phase)
|
.add(flecs::Phase)
|
||||||
.depends_on(flecs::OnUpdate);
|
.depends_on(flecs::OnUpdate);
|
||||||
GraphSolveZones.disable();
|
GraphSolveZones.disable();
|
||||||
flecs::entity GraphSolveUnits = ecs.entity("GraphSolveUnits")
|
|
||||||
.add(flecs::Phase)
|
|
||||||
.depends_on(GraphSolveZones);
|
|
||||||
flecs::entity GraphSolveFloors = ecs.entity("GraphSolveFloors")
|
|
||||||
.add(flecs::Phase)
|
|
||||||
.depends_on(GraphSolveUnits);
|
|
||||||
GraphSolve = ecs.entity("GraphSolve")
|
|
||||||
.add(flecs::Phase)
|
|
||||||
.depends_on(GraphSolveFloors);
|
|
||||||
flecs::entity GraphAssembleSkeleton =
|
|
||||||
ecs.entity("GraphAssembleSkeleton")
|
|
||||||
.add(flecs::Phase)
|
|
||||||
.depends_on(GraphSolve);
|
|
||||||
GraphAssembleSkeleton.disable();
|
|
||||||
flecs::entity GraphPostSolve = ecs.entity("GraphPostSolve")
|
|
||||||
.add(flecs::Phase)
|
|
||||||
.depends_on(flecs::PostUpdate);
|
|
||||||
GraphPostSolve.disable();
|
|
||||||
|
|
||||||
ecs.system("ZonesStart")
|
ecs.system("ZonesStart")
|
||||||
.kind(GraphSolveZones)
|
.kind(GraphSolveZones)
|
||||||
@@ -592,7 +527,68 @@ BuildingLayoutGraph::graph_module::graph_module(flecs::world &ecs)
|
|||||||
.run([module_name](flecs::iter &it) {
|
.run([module_name](flecs::iter &it) {
|
||||||
print_line("Processing units...");
|
print_line("Processing units...");
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
BuildingLayoutGraph::graph_module::graph_module(flecs::world &ecs)
|
||||||
|
{
|
||||||
|
const String &module_name = "::BuildingLayoutGraph::graph_module";
|
||||||
|
ecs.module<BuildingLayoutGraph::graph_module>();
|
||||||
|
ecs.import <flecs::stats>();
|
||||||
|
ecs.set<flecs::Rest>({});
|
||||||
|
ecs.component<WorldEditor::components::buildings_layout_graph>();
|
||||||
|
ecs.component<WorldEditor::components::buildings_layout_graph_node>();
|
||||||
|
ecs.component<WorldEditor::components::buildings_layout_base>();
|
||||||
|
ecs.component<WorldEditor::components::buildings_layout_room>();
|
||||||
|
ecs.component<WorldEditor::components::buildings_layout_zone>();
|
||||||
|
ecs.component<WorldEditor::components::buildings_layout_unit>();
|
||||||
|
ecs.component<WorldEditor::components::buildings_layout_floor>();
|
||||||
|
ecs.component<WorldEditor::components::buildings_layout_floor_index>()
|
||||||
|
.member<int>("index");
|
||||||
|
ecs.component<WorldEditor::components::buildings_layout_grid>();
|
||||||
|
ecs.component<WorldEditor::components::buildings_layout_grid_cell>();
|
||||||
|
ecs.component<WorldEditor::components::buildings_layout_grid_floor>();
|
||||||
|
ecs.component<WorldEditor::components::buildings_layout_grid_size>()
|
||||||
|
.member<int>("grid_size");
|
||||||
|
ecs.component<WorldEditor::components::buildings_layout_area>()
|
||||||
|
.member<float>("area");
|
||||||
|
ecs.component<WorldEditor::components::buildings_layout_order>()
|
||||||
|
.member<int>("index");
|
||||||
|
ecs.component<WorldEditor::components::belongs>();
|
||||||
|
#if 0
|
||||||
|
ecs.component<
|
||||||
|
WorldEditor::components::buildings_layout_commands::command>()
|
||||||
|
.member<int>("command")
|
||||||
|
.member<Vector<Variant> >("args");
|
||||||
|
ecs.component<WorldEditor::components::buildings_layout_commands>()
|
||||||
|
.member<WorldEditor::components::buildings_layout_commands::
|
||||||
|
command>("commands");
|
||||||
|
#endif
|
||||||
|
ecs.component<WorldEditor::components::buildings_layout_commands>();
|
||||||
|
// get_layout_grid_base();
|
||||||
|
// BuildingLayoutGraph::get_singleton()->get_layout_grid_base();
|
||||||
|
flecs::entity GraphPostSolve = ecs.entity("GraphPostSolve")
|
||||||
|
.add(flecs::Phase)
|
||||||
|
.depends_on(flecs::PostUpdate);
|
||||||
|
GraphPostSolve.disable();
|
||||||
|
|
||||||
|
zones_graph_module(ecs, module_name);
|
||||||
|
flecs::entity GraphSolveZones =
|
||||||
|
ecs.lookup((module_name + "::GraphSolveZones").ascii().ptr());
|
||||||
|
assert(GraphSolveZones.is_valid());
|
||||||
|
flecs::entity GraphSolveUnits = ecs.entity("GraphSolveUnits")
|
||||||
|
.add(flecs::Phase)
|
||||||
|
.depends_on(GraphSolveZones);
|
||||||
|
flecs::entity GraphSolveFloors = ecs.entity("GraphSolveFloors")
|
||||||
|
.add(flecs::Phase)
|
||||||
|
.depends_on(GraphSolveUnits);
|
||||||
|
GraphSolve = ecs.entity("GraphSolve")
|
||||||
|
.add(flecs::Phase)
|
||||||
|
.depends_on(GraphSolveFloors);
|
||||||
|
flecs::entity GraphAssembleSkeleton =
|
||||||
|
ecs.entity("GraphAssembleSkeleton")
|
||||||
|
.add(flecs::Phase)
|
||||||
|
.depends_on(GraphSolve);
|
||||||
|
GraphAssembleSkeleton.disable();
|
||||||
ecs.system<WorldEditor::components::buildings_layout_unit>("UnitArea")
|
ecs.system<WorldEditor::components::buildings_layout_unit>("UnitArea")
|
||||||
.kind(GraphSolveUnits)
|
.kind(GraphSolveUnits)
|
||||||
.without<WorldEditor::components::buildings_layout_area>()
|
.without<WorldEditor::components::buildings_layout_area>()
|
||||||
|
|||||||
@@ -7,8 +7,63 @@ struct growth_regions {
|
|||||||
Rect2i rect;
|
Rect2i rect;
|
||||||
int remains_area;
|
int remains_area;
|
||||||
bool can_grow_square;
|
bool can_grow_square;
|
||||||
|
bool can_grow;
|
||||||
|
bool can_grow_region() const
|
||||||
|
{
|
||||||
|
bool ret = can_grow;
|
||||||
|
if (remains_area <= 0)
|
||||||
|
ret = false;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
bool update_region_size(Rect2i &mrect)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
int old_area = rect.get_area();
|
||||||
|
int new_area = mrect.get_area();
|
||||||
|
int area_diff = new_area - old_area;
|
||||||
|
if (area_diff > 0) {
|
||||||
|
rect = mrect;
|
||||||
|
remains_area -= area_diff;
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
if (remains_area <= 0) {
|
||||||
|
can_grow_square = false;
|
||||||
|
can_grow = false;
|
||||||
|
}
|
||||||
|
flecs::log::dbg("update_region_size %d -> %d",
|
||||||
|
area_diff, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
Vector<struct region> regions;
|
Vector<struct region> regions;
|
||||||
|
bool complete;
|
||||||
|
bool check_region(int index, const Rect2i &rect) const
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
bool ret = true;
|
||||||
|
for (i = 0; i < regions.size(); i++) {
|
||||||
|
if (i == index)
|
||||||
|
continue;
|
||||||
|
if (rect.intersects(regions[i].rect)) {
|
||||||
|
ret = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
flecs::log::dbg("check_region: %d -> %d", index, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
bool update_region_size(int index, Rect2i &mrect)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
bool ok = check_region(index, mrect);
|
||||||
|
if (ok)
|
||||||
|
ret = regions.write[index].update_region_size(mrect);
|
||||||
|
flecs::log::dbg("update_region_size %d -> %d", index, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
void create_region(flecs::entity floor_e, flecs::entity seed_e,
|
||||||
|
flecs::entity region_e, const Vector2i &position,
|
||||||
|
float area);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct make_random {
|
struct make_random {
|
||||||
|
|||||||
@@ -4,15 +4,6 @@
|
|||||||
#include "building_layout_graph.h"
|
#include "building_layout_graph.h"
|
||||||
#include "graph_module.h"
|
#include "graph_module.h"
|
||||||
|
|
||||||
void BuildingLayoutGraph::graph_module::growth_module(flecs::world &ecs,
|
|
||||||
const String &module_name)
|
|
||||||
{
|
|
||||||
ecs.component<growth_regions>();
|
|
||||||
flecs::entity GraphFilter = ecs.entity("GraphFilter")
|
|
||||||
.add(flecs::Phase)
|
|
||||||
.depends_on(flecs::OnUpdate);
|
|
||||||
GraphFilter.disable();
|
|
||||||
|
|
||||||
struct grid_calc {
|
struct grid_calc {
|
||||||
int grid_size;
|
int grid_size;
|
||||||
int index2x(int index)
|
int index2x(int index)
|
||||||
@@ -35,16 +26,14 @@ void BuildingLayoutGraph::graph_module::growth_module(flecs::world &ecs,
|
|||||||
int cx = x + i, cy = y + j;
|
int cx = x + i, cy = y + j;
|
||||||
if (cx >= 0 && cx < grid_size &&
|
if (cx >= 0 && cx < grid_size &&
|
||||||
cy >= 0 && cy < grid_size) {
|
cy >= 0 && cy < grid_size) {
|
||||||
int id = cx +
|
int id = cx + grid_size * cy;
|
||||||
grid_size * cy;
|
|
||||||
candidates[idx++] = id;
|
candidates[idx++] = id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
grid_calc(flecs::entity layout_e)
|
grid_calc(flecs::entity layout_e)
|
||||||
: grid_size(
|
: grid_size(layout_e.get<WorldEditor::components::
|
||||||
layout_e.get<WorldEditor::components::
|
|
||||||
buildings_layout_grid_size>()
|
buildings_layout_grid_size>()
|
||||||
->grid_size)
|
->grid_size)
|
||||||
{
|
{
|
||||||
@@ -83,110 +72,129 @@ void BuildingLayoutGraph::graph_module::growth_module(flecs::world &ecs,
|
|||||||
for (i = 0; i < (int)candidates_data.size(); i++)
|
for (i = 0; i < (int)candidates_data.size(); i++)
|
||||||
candidates[i] = candidates_data[i];
|
candidates[i] = candidates_data[i];
|
||||||
}
|
}
|
||||||
void setup_floor(
|
int get_floor_index(flecs::entity e) const
|
||||||
flecs::entity grid_e, flecs::entity_t base_et,
|
|
||||||
const WorldEditor::components::buildings_layout_grid_size
|
|
||||||
&size,
|
|
||||||
BuildingLayoutGraph::graph_module *obj)
|
|
||||||
{
|
{
|
||||||
int i, j;
|
return e.get<WorldEditor::components::
|
||||||
flecs::entity base_floor_e =
|
|
||||||
grid_e.world().entity(base_et);
|
|
||||||
flecs::log::warn("base_floor: %s",
|
|
||||||
base_floor_e.path().c_str());
|
|
||||||
int floor_index =
|
|
||||||
base_floor_e
|
|
||||||
.get<WorldEditor::components::
|
|
||||||
buildings_layout_floor_index>()
|
buildings_layout_floor_index>()
|
||||||
->index;
|
->index;
|
||||||
String floor_name = "floor_" + itos(floor_index);
|
}
|
||||||
flecs::entity floor_e =
|
flecs::entity get_grid_floor(flecs::entity grid_e,
|
||||||
grid_e.lookup(floor_name.ascii().ptr());
|
flecs::entity graph_floor_e)
|
||||||
print_line("grid: " + String(grid_e.path()));
|
{
|
||||||
print_line("floor: " + floor_name);
|
|
||||||
assert(floor_e.is_valid());
|
|
||||||
assert(grid_e.is_valid());
|
assert(grid_e.is_valid());
|
||||||
obj->create_floor_components(floor_e, base_floor_e,
|
assert(graph_floor_e.is_valid());
|
||||||
size);
|
int floor_index = get_floor_index(graph_floor_e);
|
||||||
flecs::log::warn("grid floor: %s",
|
String floor_name = "floor_" + itos(floor_index);
|
||||||
floor_e.path().c_str());
|
flecs::log::dbg("floor: %s", floor_name.ascii().ptr());
|
||||||
|
flecs::entity floor_e = grid_e.lookup(floor_name.ascii().ptr());
|
||||||
|
assert(floor_e.is_valid());
|
||||||
|
return floor_e;
|
||||||
|
}
|
||||||
|
bool check_duplicates()
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
bool result = true;
|
||||||
for (i = 0; i < (int)positions.size(); i++)
|
for (i = 0; i < (int)positions.size(); i++)
|
||||||
for (j = 0; j < (int)positions.size(); j++) {
|
for (j = 0; j < (int)positions.size(); j++) {
|
||||||
if (i == j)
|
if (i == j)
|
||||||
continue;
|
continue;
|
||||||
if (positions[i].second ==
|
if (positions[i].second ==
|
||||||
positions[j].second)
|
positions[j].second) {
|
||||||
flecs::log::err(
|
flecs::log::err("duplicate positions");
|
||||||
"duplicate positions");
|
result = false;
|
||||||
assert(positions[i].second !=
|
goto out;
|
||||||
positions[j].second);
|
|
||||||
}
|
}
|
||||||
for (i = 0; i < (int)positions.size(); i++) {
|
}
|
||||||
int cell_id =
|
out:
|
||||||
positions[i].second.x +
|
return result;
|
||||||
size.grid_size * positions[i].second.y;
|
}
|
||||||
flecs::entity region_e = grid_e.world().entity(
|
struct region_desc {
|
||||||
positions[i].first);
|
flecs::entity region_e;
|
||||||
float area =
|
int cell_id;
|
||||||
region_e.get<WorldEditor::components::
|
Vector2i position;
|
||||||
buildings_layout_area>()
|
float area;
|
||||||
->area;
|
template <class T>
|
||||||
assert(region_e.is_valid());
|
void create_region(T *obj, flecs::entity grid_floor_e)
|
||||||
assert(floor_e.is_valid());
|
{
|
||||||
Rect2i check;
|
|
||||||
check.position = positions[i].second;
|
|
||||||
check.size = Vector2i(1, 1);
|
|
||||||
assert(obj->check_region(floor_e, -1, check));
|
|
||||||
flecs::entity cell_e = obj->create_cell(
|
flecs::entity cell_e = obj->create_cell(
|
||||||
floor_e, region_e, cell_id);
|
grid_floor_e, region_e, cell_id);
|
||||||
assert(cell_e.is_valid());
|
growth_regions *g =
|
||||||
obj->create_region(floor_e, cell_e, region_e,
|
grid_floor_e.get_mut<growth_regions>();
|
||||||
positions[i].second, area);
|
g->create_region(grid_floor_e, cell_e, region_e,
|
||||||
|
position, area);
|
||||||
flecs::log::warn("grid cell: %s",
|
flecs::log::warn("grid cell: %s",
|
||||||
cell_e.path().c_str());
|
cell_e.path().c_str());
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
Vector<struct region_desc> regions;
|
||||||
|
void setup_floor(flecs::entity grid_floor_e, int grid_size,
|
||||||
|
BuildingLayoutGraph::graph_module *obj)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
assert(grid_floor_e.is_valid());
|
||||||
|
flecs::entity grid_e = grid_floor_e.parent();
|
||||||
|
assert(grid_e.is_valid());
|
||||||
|
flecs::log::dbg("grid: %s", grid_e.path().c_str());
|
||||||
|
flecs::log::warn("grid floor: %s", grid_floor_e.path().c_str());
|
||||||
|
assert(check_duplicates());
|
||||||
|
int region_count = 0;
|
||||||
|
regions.resize(positions.size());
|
||||||
|
for (i = 0; i < (int)positions.size(); i++) {
|
||||||
|
int cell_id = positions[i].second.x +
|
||||||
|
grid_size * positions[i].second.y;
|
||||||
|
flecs::entity region_e =
|
||||||
|
grid_e.world().entity(positions[i].first);
|
||||||
|
assert(region_e.is_valid());
|
||||||
|
float area = get_entity_area(region_e);
|
||||||
|
Rect2i check;
|
||||||
|
check.position = positions[i].second;
|
||||||
|
check.size = Vector2i(1, 1);
|
||||||
|
assert(obj->check_region(grid_floor_e, -1, check));
|
||||||
|
regions.write[region_count++] = { region_e, cell_id,
|
||||||
|
positions[i].second,
|
||||||
|
area };
|
||||||
|
}
|
||||||
|
regions.resize(region_count);
|
||||||
|
}
|
||||||
|
void place_regions(flecs::entity grid_floor_e,
|
||||||
|
BuildingLayoutGraph::graph_module *obj)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < regions.size(); i++)
|
||||||
|
regions.write[i].create_region(obj, grid_floor_e);
|
||||||
}
|
}
|
||||||
float get_entity_area(flecs::entity e) const
|
float get_entity_area(flecs::entity e) const
|
||||||
{
|
{
|
||||||
return e.get<WorldEditor::components::
|
return e.get<WorldEditor::components::buildings_layout_area>()
|
||||||
buildings_layout_area>()
|
|
||||||
->area;
|
->area;
|
||||||
}
|
}
|
||||||
float get_entity_area(flecs::world &&ecs,
|
float get_entity_area(flecs::world &&ecs, flecs::entity_t et) const
|
||||||
flecs::entity_t et) const
|
|
||||||
{
|
{
|
||||||
flecs::entity e = ecs.entity(et);
|
flecs::entity e = ecs.entity(et);
|
||||||
return e.get<WorldEditor::components::
|
return e.get<WorldEditor::components::buildings_layout_area>()
|
||||||
buildings_layout_area>()
|
|
||||||
->area;
|
->area;
|
||||||
}
|
}
|
||||||
float get_entity_area(flecs::world &ecs,
|
float get_entity_area(flecs::world &ecs, flecs::entity_t et) const
|
||||||
flecs::entity_t et) const
|
|
||||||
{
|
{
|
||||||
flecs::entity e = ecs.entity(et);
|
flecs::entity e = ecs.entity(et);
|
||||||
return e.get<WorldEditor::components::
|
return e.get<WorldEditor::components::buildings_layout_area>()
|
||||||
buildings_layout_area>()
|
|
||||||
->area;
|
->area;
|
||||||
}
|
}
|
||||||
int get_base_radius(flecs::world &&ecs,
|
int get_base_radius(flecs::world &&ecs, flecs::entity_t et) const
|
||||||
flecs::entity_t et) const
|
|
||||||
{
|
{
|
||||||
float base_area = get_entity_area(ecs, et);
|
float base_area = get_entity_area(ecs, et);
|
||||||
int base_radius =
|
int base_radius = (int)((Math::sqrt(base_area) * 1.6f) / 2.0f) /
|
||||||
(int)((Math::sqrt(base_area) * 1.6f) / 2.0f) /
|
|
||||||
4; /* grid conversion */
|
4; /* grid conversion */
|
||||||
return base_radius;
|
return base_radius;
|
||||||
}
|
}
|
||||||
int get_base_radius(flecs::world &ecs, flecs::entity_t et) const
|
int get_base_radius(flecs::world &ecs, flecs::entity_t et) const
|
||||||
{
|
{
|
||||||
float base_area = get_entity_area(ecs, et);
|
float base_area = get_entity_area(ecs, et);
|
||||||
int base_radius =
|
int base_radius = (int)((Math::sqrt(base_area) * 1.6f) / 2.0f) /
|
||||||
(int)((Math::sqrt(base_area) * 1.6f) / 2.0f) /
|
|
||||||
4; /* grid conversion */
|
4; /* grid conversion */
|
||||||
return base_radius;
|
return base_radius;
|
||||||
}
|
}
|
||||||
int distance_squared(const Vector2i &p1,
|
int distance_squared(const Vector2i &p1, const Vector2i &p2) const
|
||||||
const Vector2i &p2) const
|
|
||||||
{
|
{
|
||||||
int lx = p2.x - p1.x;
|
int lx = p2.x - p1.x;
|
||||||
int ly = p2.y - p1.y;
|
int ly = p2.y - p1.y;
|
||||||
@@ -197,8 +205,7 @@ void BuildingLayoutGraph::graph_module::growth_module(flecs::world &ecs,
|
|||||||
int i;
|
int i;
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
for (i = 0; i < (int)positions.size(); i++)
|
for (i = 0; i < (int)positions.size(); i++)
|
||||||
if (distance_squared(check,
|
if (distance_squared(check, positions[i].second) < 1) {
|
||||||
positions[i].second) < 1) {
|
|
||||||
ret = false;
|
ret = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -221,27 +228,24 @@ void BuildingLayoutGraph::graph_module::growth_module(flecs::world &ecs,
|
|||||||
}
|
}
|
||||||
return !bad;
|
return !bad;
|
||||||
}
|
}
|
||||||
bool accept_candidate(flecs::entity ce,
|
bool accept_candidate(flecs::entity ce, const Vector2i &candidate,
|
||||||
const Vector2i &candidate, float area)
|
float area)
|
||||||
{
|
{
|
||||||
int k;
|
int k;
|
||||||
int local_radius =
|
int local_radius = (int)((Math::sqrt(area) * 1.6f) / 2.0f) /
|
||||||
(int)((Math::sqrt(area) * 1.6f) / 2.0f) /
|
|
||||||
4; /* grid conversion */
|
4; /* grid conversion */
|
||||||
local_radius = MAX(1, local_radius);
|
local_radius = MAX(1, local_radius);
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
for (k = 0; k < (int)positions.size(); k++) {
|
for (k = 0; k < (int)positions.size(); k++) {
|
||||||
assert(k < (int)positions.size());
|
assert(k < (int)positions.size());
|
||||||
flecs::entity_t pbase_et = positions[k].first;
|
flecs::entity_t pbase_et = positions[k].first;
|
||||||
float parea =
|
float parea = get_entity_area(ce.world(), pbase_et);
|
||||||
get_entity_area(ce.world(), pbase_et);
|
int pdim = (int)((Math::sqrt(parea) * 1.5f) / 2.0f) /
|
||||||
int pdim = (int)((Math::sqrt(parea) * 1.5f) /
|
|
||||||
2.0f) /
|
|
||||||
4; /* radius converted to grid 4x4*/
|
4; /* radius converted to grid 4x4*/
|
||||||
int radius = pdim + local_radius;
|
int radius = pdim + local_radius;
|
||||||
int radius_sq = radius * radius;
|
int radius_sq = radius * radius;
|
||||||
if (distance_squared(positions[k].second,
|
if (distance_squared(positions[k].second, candidate) <
|
||||||
candidate) < radius_sq)
|
radius_sq)
|
||||||
continue;
|
continue;
|
||||||
assert(check_candidates_tolerance(candidate));
|
assert(check_candidates_tolerance(candidate));
|
||||||
accepted.push_back(candidate);
|
accepted.push_back(candidate);
|
||||||
@@ -251,15 +255,13 @@ void BuildingLayoutGraph::graph_module::growth_module(flecs::world &ecs,
|
|||||||
}
|
}
|
||||||
bool process_candidates(
|
bool process_candidates(
|
||||||
flecs::entity ce, const Vector2i &base, float area,
|
flecs::entity ce, const Vector2i &base, float area,
|
||||||
const WorldEditor::components::buildings_layout_grid_size
|
const WorldEditor::components::buildings_layout_grid_size &size,
|
||||||
&size,
|
|
||||||
flecs::entity_t base_et, int dim)
|
flecs::entity_t base_et, int dim)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
int base_radius = get_base_radius(ce.world(), base_et);
|
int base_radius = get_base_radius(ce.world(), base_et);
|
||||||
base_radius = MAX(1, base_radius);
|
base_radius = MAX(1, base_radius);
|
||||||
int local_radius =
|
int local_radius = (int)((Math::sqrt(area) * 1.6f) / 2.0f) /
|
||||||
(int)((Math::sqrt(area) * 1.6f) / 2.0f) /
|
|
||||||
4; /* grid conversion */
|
4; /* grid conversion */
|
||||||
local_radius = MAX(1, local_radius);
|
local_radius = MAX(1, local_radius);
|
||||||
// int dim = base_radius + local_radius;
|
// int dim = base_radius + local_radius;
|
||||||
@@ -277,23 +279,21 @@ void BuildingLayoutGraph::graph_module::growth_module(flecs::world &ecs,
|
|||||||
size.grid_size - md * 2);
|
size.grid_size - md * 2);
|
||||||
Vector2i candidates[8];
|
Vector2i candidates[8];
|
||||||
get_dim_candidates(base, dim, &candidates[0]);
|
get_dim_candidates(base, dim, &candidates[0]);
|
||||||
for (j = 0; j < (int)(sizeof(candidates) /
|
for (j = 0;
|
||||||
sizeof(candidates[0]));
|
j < (int)(sizeof(candidates) / sizeof(candidates[0]));
|
||||||
j++) {
|
j++) {
|
||||||
print_line("base: " + itos(base.x) + ", " +
|
print_line("base: " + itos(base.x) + ", " +
|
||||||
itos(base.y));
|
itos(base.y));
|
||||||
print_line("possible candidate: " +
|
print_line(
|
||||||
itos(candidates[j].x) + ", " +
|
"possible candidate: " + itos(candidates[j].x) +
|
||||||
itos(candidates[j].y));
|
", " + itos(candidates[j].y));
|
||||||
if (!clip.has_point(candidates[j])) {
|
if (!clip.has_point(candidates[j])) {
|
||||||
print_line("clipped by grid field");
|
print_line("clipped by grid field");
|
||||||
print_line(clip.operator String());
|
print_line(clip.operator String());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!check_candidates_tolerance(
|
if (!check_candidates_tolerance(candidates[j])) {
|
||||||
candidates[j])) {
|
print_line("too close to existing positions");
|
||||||
print_line(
|
|
||||||
"too close to existing positions");
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!check_candidate(candidates[j])) {
|
if (!check_candidate(candidates[j])) {
|
||||||
@@ -301,9 +301,8 @@ void BuildingLayoutGraph::graph_module::growth_module(flecs::world &ecs,
|
|||||||
"too close to existing positions (rect)");
|
"too close to existing positions (rect)");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
print_line("valid candidate: " +
|
print_line("valid candidate: " + itos(candidates[j].x) +
|
||||||
itos(candidates[j].x) + ", " +
|
", " + itos(candidates[j].y));
|
||||||
itos(candidates[j].y));
|
|
||||||
accept_candidate(ce, candidates[j], area);
|
accept_candidate(ce, candidates[j], area);
|
||||||
}
|
}
|
||||||
if (accepted.size() > 0)
|
if (accepted.size() > 0)
|
||||||
@@ -313,49 +312,41 @@ void BuildingLayoutGraph::graph_module::growth_module(flecs::world &ecs,
|
|||||||
}
|
}
|
||||||
void filter_candidates(
|
void filter_candidates(
|
||||||
flecs::entity ce, float area,
|
flecs::entity ce, float area,
|
||||||
const WorldEditor::components::buildings_layout_grid_size
|
const WorldEditor::components::buildings_layout_grid_size &size)
|
||||||
&size)
|
|
||||||
{
|
{
|
||||||
if (positions.empty()) {
|
if (positions.empty()) {
|
||||||
/* starting at grid center */
|
/* starting at grid center */
|
||||||
Vector2i start_pos(size.grid_size / 2,
|
Vector2i start_pos(size.grid_size / 2,
|
||||||
size.grid_size / 2);
|
size.grid_size / 2);
|
||||||
positions.push_back(
|
positions.push_back(Pair<flecs::entity_t, Vector2i>(
|
||||||
Pair<flecs::entity_t, Vector2i>(
|
|
||||||
ce.id(), start_pos));
|
ce.id(), start_pos));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (1) {
|
while (1) {
|
||||||
int which = which_position();
|
int which = which_position();
|
||||||
const Vector2i &base = positions[which].second;
|
const Vector2i &base = positions[which].second;
|
||||||
flecs::entity_t base_et =
|
flecs::entity_t base_et = positions[which].first;
|
||||||
positions[which].first;
|
int base_radius = get_base_radius(ce.world(), base_et);
|
||||||
int base_radius =
|
|
||||||
get_base_radius(ce.world(), base_et);
|
|
||||||
base_radius = MAX(1, base_radius);
|
base_radius = MAX(1, base_radius);
|
||||||
int local_radius =
|
int local_radius =
|
||||||
(int)((Math::sqrt(area) * 1.6f) /
|
(int)((Math::sqrt(area) * 1.6f) / 2.0f) /
|
||||||
2.0f) /
|
|
||||||
4; /* grid conversion */
|
4; /* grid conversion */
|
||||||
local_radius = MAX(1, local_radius);
|
local_radius = MAX(1, local_radius);
|
||||||
int dim = base_radius + local_radius;
|
int dim = base_radius + local_radius;
|
||||||
dim = MAX(1, dim);
|
dim = MAX(1, dim);
|
||||||
process_candidates(ce, base, area, size,
|
process_candidates(ce, base, area, size, base_et, dim);
|
||||||
base_et, dim);
|
|
||||||
if (accepted.size() == 0) {
|
if (accepted.size() == 0) {
|
||||||
assert(positions.size() > 0);
|
assert(positions.size() > 0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
assert(accepted.size() > 0);
|
assert(accepted.size() > 0);
|
||||||
const Vector2i &selected =
|
const Vector2i &selected = accepted[which_selected()];
|
||||||
accepted[which_selected()];
|
|
||||||
assert(check_candidates_tolerance(selected));
|
assert(check_candidates_tolerance(selected));
|
||||||
Pair<flecs::entity_t, Vector2i> m(ce.id(),
|
Pair<flecs::entity_t, Vector2i> m(ce.id(), selected);
|
||||||
selected);
|
|
||||||
check_candidate(selected);
|
check_candidate(selected);
|
||||||
positions.push_back(m);
|
positions.push_back(m);
|
||||||
flecs::log::warn("add position: %d, %d",
|
flecs::log::warn("add position: %d, %d", selected.x,
|
||||||
selected.x, selected.y);
|
selected.y);
|
||||||
accepted.clear();
|
accepted.clear();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -378,8 +369,245 @@ void BuildingLayoutGraph::graph_module::growth_module(flecs::world &ecs,
|
|||||||
assert(which < (int)accepted.size());
|
assert(which < (int)accepted.size());
|
||||||
return which;
|
return which;
|
||||||
}
|
}
|
||||||
|
template <class T>
|
||||||
|
void place_region_cells(
|
||||||
|
T *obj, flecs::entity grid_floor_e,
|
||||||
|
const WorldEditor::components::buildings_layout_grid_floor &fl,
|
||||||
|
growth_regions &g)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < g.regions.size(); i++) {
|
||||||
|
int x, y;
|
||||||
|
Rect2i rect = g.regions[i].rect;
|
||||||
|
for (x = rect.position.x;
|
||||||
|
x <= rect.position.x + rect.size.x; x++)
|
||||||
|
for (y = rect.position.y;
|
||||||
|
y <= rect.position.y + rect.size.y; y++) {
|
||||||
|
int id = x + fl.grid_size * y;
|
||||||
|
if (!fl.cells.has(id)) {
|
||||||
|
flecs::entity seed_e =
|
||||||
|
grid_floor_e.world().entity(
|
||||||
|
g.regions[i]
|
||||||
|
.seed_et);
|
||||||
|
assert(seed_e.is_valid());
|
||||||
|
obj->queue_grow_cell(seed_e,
|
||||||
|
id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void print_can_grow(int state, growth_regions &g, int index,
|
||||||
|
const char *what)
|
||||||
|
{
|
||||||
|
const growth_regions::region ®ion = g.regions[index];
|
||||||
|
bool can = false;
|
||||||
|
if (!strcmp(what, "square"))
|
||||||
|
can = region.can_grow_square;
|
||||||
|
else if (!strcmp(what, "rect"))
|
||||||
|
can = region.can_grow;
|
||||||
|
|
||||||
|
if (can)
|
||||||
|
flecs::log::dbg(
|
||||||
|
"state: %d: index %d: region can still grow %s %d",
|
||||||
|
state, index, what, region.remains_area);
|
||||||
|
else
|
||||||
|
flecs::log::dbg(
|
||||||
|
"state: %d: index %d: region can't grow %s %d",
|
||||||
|
state, index, what, region.remains_area);
|
||||||
|
if (region.can_grow_region())
|
||||||
|
flecs::log::dbg(
|
||||||
|
"state %d: index %d: region can still continue",
|
||||||
|
state, index);
|
||||||
|
}
|
||||||
|
bool grow_state0(growth_regions &g, int index, const Rect2i &clip)
|
||||||
|
{
|
||||||
|
bool ok = true, ret = false;
|
||||||
|
Rect2i mrect;
|
||||||
|
growth_regions::region ®ion = g.regions.write[index];
|
||||||
|
mrect = region.rect;
|
||||||
|
assert(g.check_region(index, mrect));
|
||||||
|
|
||||||
|
mrect = mrect.grow(1);
|
||||||
|
ok = clip.encloses(mrect);
|
||||||
|
if (!ok)
|
||||||
|
flecs::log::dbg("state: %d: index %d: out of clip area",
|
||||||
|
0, index);
|
||||||
|
if (ok) {
|
||||||
|
ok = g.check_region(index, mrect);
|
||||||
|
if (!ok)
|
||||||
|
flecs::log::dbg(
|
||||||
|
"state: %d: index %d: check_region failed",
|
||||||
|
0, index);
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
ret = region.update_region_size(mrect);
|
||||||
|
if (!ret)
|
||||||
|
flecs::log::dbg(
|
||||||
|
"state: %d: index %d: update_region_size failed",
|
||||||
|
0, index);
|
||||||
|
}
|
||||||
|
print_can_grow(0, g, index, "square");
|
||||||
|
if (!ret)
|
||||||
|
flecs::log::dbg("state %d could not grow region %d: %d",
|
||||||
|
0, index, region.remains_area);
|
||||||
|
else
|
||||||
|
flecs::log::dbg("state %d could grow region %d: %d", 0,
|
||||||
|
index, region.remains_area);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
bool grow_state1(growth_regions &g, int index, const Rect2i &clip)
|
||||||
|
{
|
||||||
|
int d;
|
||||||
|
bool ret = false;
|
||||||
|
Rect2i mrect;
|
||||||
|
growth_regions::region ®ion = g.regions.write[index];
|
||||||
|
int count = 0;
|
||||||
|
for (d = 0; d < 4; d++) {
|
||||||
|
bool ok;
|
||||||
|
mrect = region.rect;
|
||||||
|
assert(g.check_region(index, mrect));
|
||||||
|
switch (d) {
|
||||||
|
case 0:
|
||||||
|
mrect.position.y -= 1;
|
||||||
|
mrect.size.y += 1;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
mrect.size.y += 1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
mrect.position.x -= 1;
|
||||||
|
mrect.size.x += 1;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
mrect.size.x += 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ok = clip.encloses(mrect);
|
||||||
|
if (ok)
|
||||||
|
ok = g.check_region(index, mrect);
|
||||||
|
if (ok) {
|
||||||
|
bool result = region.update_region_size(mrect);
|
||||||
|
if (result)
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count > 0) {
|
||||||
|
ret = true;
|
||||||
|
flecs::log::dbg(
|
||||||
|
"state %d could grow region %d: %d - %d out of %d times",
|
||||||
|
0, index, region.remains_area, count, 4);
|
||||||
|
}
|
||||||
|
print_can_grow(1, g, index, "rect");
|
||||||
|
if (!ret)
|
||||||
|
flecs::log::dbg(
|
||||||
|
"state %d could not grow region rect %d: %d", 0,
|
||||||
|
index, region.remains_area);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
void grow_region_rects(
|
||||||
|
T *obj, flecs::entity floor_e,
|
||||||
|
WorldEditor::components::buildings_layout_grid_floor &fl,
|
||||||
|
growth_regions &g)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
bool grown = true;
|
||||||
|
int state = 0;
|
||||||
|
if (g.complete)
|
||||||
|
return;
|
||||||
|
Rect2i clip(0, 0, fl.grid_size, fl.grid_size);
|
||||||
|
state = 0;
|
||||||
|
flecs::log::dbg("growing square");
|
||||||
|
while (grown) {
|
||||||
|
grown = false;
|
||||||
|
int count = 0;
|
||||||
|
for (i = 0; i < g.regions.size(); i++) {
|
||||||
|
growth_regions::region ®ion =
|
||||||
|
g.regions.write[i];
|
||||||
|
Rect2i mrect = region.rect;
|
||||||
|
flecs::log::dbg("grow_region_rects: region %d",
|
||||||
|
i);
|
||||||
|
if (!region.can_grow_region()) {
|
||||||
|
flecs::log::dbg(
|
||||||
|
"grow_region_rects: skip %d",
|
||||||
|
i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
mrect = region.rect;
|
||||||
|
bool result = false;
|
||||||
|
result = grow_state0(g, i, clip);
|
||||||
|
if (result)
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
if (count > 0) {
|
||||||
|
grown = true;
|
||||||
|
flecs::log::dbg("grown squares %d times of %d",
|
||||||
|
count, g.regions.size());
|
||||||
|
}
|
||||||
|
if (!grown)
|
||||||
|
flecs::log::dbg(
|
||||||
|
"grow_region_rects: could not grow more squares");
|
||||||
|
}
|
||||||
|
state = 1;
|
||||||
|
grown = true;
|
||||||
|
flecs::log::dbg("growing rect");
|
||||||
|
while (grown) {
|
||||||
|
grown = false;
|
||||||
|
int count = 0;
|
||||||
|
for (i = 0; i < g.regions.size(); i++) {
|
||||||
|
growth_regions::region ®ion =
|
||||||
|
g.regions.write[i];
|
||||||
|
Rect2i mrect = region.rect;
|
||||||
|
flecs::log::dbg("grow_region_rects: region %d",
|
||||||
|
i);
|
||||||
|
if (!region.can_grow_region()) {
|
||||||
|
flecs::log::dbg(
|
||||||
|
"grow_region_rects: skip %d",
|
||||||
|
i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
mrect = region.rect;
|
||||||
|
bool result = false;
|
||||||
|
result = grow_state1(g, i, clip);
|
||||||
|
if (result)
|
||||||
|
count++;
|
||||||
|
if (!result)
|
||||||
|
flecs::log::dbg(
|
||||||
|
"state %d could not grow region %d",
|
||||||
|
state, i);
|
||||||
|
else
|
||||||
|
flecs::log::dbg(
|
||||||
|
"state %d could grow region %d: %d",
|
||||||
|
state, i, region.remains_area);
|
||||||
|
}
|
||||||
|
if (count > 0) {
|
||||||
|
grown = true;
|
||||||
|
flecs::log::dbg("grown rects %d times of %d",
|
||||||
|
count, g.regions.size());
|
||||||
|
}
|
||||||
|
if (!grown)
|
||||||
|
flecs::log::dbg(
|
||||||
|
"grow_region_rects: could not grow any more rects");
|
||||||
|
}
|
||||||
|
flecs::log::dbg("grow_region_rects: complete");
|
||||||
|
g.complete = true;
|
||||||
|
flecs::log::dbg("grow_region_rects: %s: done",
|
||||||
|
floor_e.path().c_str());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void BuildingLayoutGraph::graph_module::growth_module(flecs::world &ecs,
|
||||||
|
const String &module_name)
|
||||||
|
{
|
||||||
|
ecs.component<growth_regions>();
|
||||||
|
flecs::entity GraphFilter = ecs.entity("GraphFilter")
|
||||||
|
.add(flecs::Phase)
|
||||||
|
.depends_on(flecs::OnUpdate);
|
||||||
|
GraphFilter.disable();
|
||||||
|
flecs::entity GraphGridPrepare = ecs.entity("GraphGridPrepare")
|
||||||
|
.add(flecs::Phase)
|
||||||
|
.depends_on(GraphSolve);
|
||||||
|
|
||||||
ecs.system<const WorldEditor::components::buildings_layout_grid_size>(
|
ecs.system<const WorldEditor::components::buildings_layout_grid_size>(
|
||||||
"CreateGrid")
|
"CreateGrid")
|
||||||
.kind(GraphSolve)
|
.kind(GraphSolve)
|
||||||
@@ -430,8 +658,16 @@ void BuildingLayoutGraph::graph_module::growth_module(flecs::world &ecs,
|
|||||||
grid.filter_candidates(ce, area.area,
|
grid.filter_candidates(ce, area.area,
|
||||||
size);
|
size);
|
||||||
});
|
});
|
||||||
grid.setup_floor(grid_e, me->get().second, size,
|
flecs::entity base_floor_e =
|
||||||
|
grid_e.world().entity(me->get().second);
|
||||||
|
flecs::entity grid_floor_e =
|
||||||
|
grid.get_grid_floor(grid_e,
|
||||||
|
base_floor_e);
|
||||||
|
create_floor_components(grid_floor_e,
|
||||||
|
base_floor_e, size);
|
||||||
|
grid.setup_floor(grid_floor_e, size.grid_size,
|
||||||
this);
|
this);
|
||||||
|
grid.place_regions(grid_floor_e, this);
|
||||||
|
|
||||||
me = me->next();
|
me = me->next();
|
||||||
}
|
}
|
||||||
@@ -455,6 +691,7 @@ void BuildingLayoutGraph::graph_module::growth_module(flecs::world &ecs,
|
|||||||
"update_layout_view", varray());
|
"update_layout_view", varray());
|
||||||
// assert(false);
|
// assert(false);
|
||||||
});
|
});
|
||||||
|
#if 0
|
||||||
|
|
||||||
ecs.system<WorldEditor::components::buildings_layout_grid_floor,
|
ecs.system<WorldEditor::components::buildings_layout_grid_floor,
|
||||||
growth_regions>("GrowFloorRectRegions")
|
growth_regions>("GrowFloorRectRegions")
|
||||||
@@ -463,175 +700,12 @@ void BuildingLayoutGraph::graph_module::growth_module(flecs::world &ecs,
|
|||||||
WorldEditor::components::buildings_layout_grid_floor
|
WorldEditor::components::buildings_layout_grid_floor
|
||||||
&fl,
|
&fl,
|
||||||
growth_regions &g) {
|
growth_regions &g) {
|
||||||
int i;
|
struct grid_misc grid;
|
||||||
bool grown = true;
|
grid.grow_region_rects(this, floor_e, fl, g);
|
||||||
int state = 0;
|
grid.place_region_cells(this, floor_e, fl, g);
|
||||||
while (1) {
|
|
||||||
while (grown) {
|
|
||||||
grown = false;
|
|
||||||
for (i = 0; i < g.regions.size(); i++) {
|
|
||||||
Rect2i mrect =
|
|
||||||
g.regions[i].rect;
|
|
||||||
if (state == 0) {
|
|
||||||
if (!g.regions[i]
|
|
||||||
.can_grow_square)
|
|
||||||
continue;
|
|
||||||
if (g.regions[i]
|
|
||||||
.remains_area <=
|
|
||||||
0) {
|
|
||||||
g.regions
|
|
||||||
.write[i]
|
|
||||||
.can_grow_square =
|
|
||||||
false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mrect = g.regions[i].rect;
|
|
||||||
int old_area = mrect.get_area();
|
|
||||||
if (state == 0) {
|
|
||||||
mrect = g.regions[i]
|
|
||||||
.rect;
|
|
||||||
|
|
||||||
assert(check_region(
|
|
||||||
floor_e, i,
|
|
||||||
mrect));
|
|
||||||
mrect = mrect.grow(1);
|
|
||||||
Rect2i clip(
|
|
||||||
0, 0,
|
|
||||||
fl.grid_size,
|
|
||||||
fl.grid_size);
|
|
||||||
if (!clip.encloses(
|
|
||||||
mrect))
|
|
||||||
continue;
|
|
||||||
bool ok = check_region(
|
|
||||||
floor_e, i,
|
|
||||||
mrect);
|
|
||||||
if (!ok)
|
|
||||||
continue;
|
|
||||||
int new_area =
|
|
||||||
mrect.get_area();
|
|
||||||
int area_diff =
|
|
||||||
new_area -
|
|
||||||
old_area;
|
|
||||||
if (area_diff > 0) {
|
|
||||||
g.regions
|
|
||||||
.write[i]
|
|
||||||
.rect =
|
|
||||||
mrect;
|
|
||||||
g.regions
|
|
||||||
.write[i]
|
|
||||||
.remains_area -=
|
|
||||||
area_diff;
|
|
||||||
grown = true;
|
|
||||||
}
|
|
||||||
} else if (state == 1) {
|
|
||||||
int d;
|
|
||||||
mrect = g.regions[i]
|
|
||||||
.rect;
|
|
||||||
if (g.regions[i]
|
|
||||||
.remains_area <=
|
|
||||||
0)
|
|
||||||
break;
|
|
||||||
bool ok = true;
|
|
||||||
for (d = 0; d < 4;
|
|
||||||
d++) {
|
|
||||||
mrect = g.regions[i]
|
|
||||||
.rect;
|
|
||||||
assert(check_region(
|
|
||||||
floor_e,
|
|
||||||
i,
|
|
||||||
mrect));
|
|
||||||
switch (d) {
|
|
||||||
case 0:
|
|
||||||
mrect.position
|
|
||||||
.y -=
|
|
||||||
1;
|
|
||||||
mrect.size
|
|
||||||
.y +=
|
|
||||||
1;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
mrect.size
|
|
||||||
.y +=
|
|
||||||
1;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
mrect.position
|
|
||||||
.x -=
|
|
||||||
1;
|
|
||||||
mrect.size
|
|
||||||
.x +=
|
|
||||||
1;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
mrect.size
|
|
||||||
.x +=
|
|
||||||
1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Rect2i clip(
|
|
||||||
0, 0,
|
|
||||||
fl.grid_size,
|
|
||||||
fl.grid_size);
|
|
||||||
if (!clip.encloses(
|
|
||||||
mrect)) {
|
|
||||||
ok = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ok = check_region(
|
|
||||||
floor_e,
|
|
||||||
i,
|
|
||||||
mrect);
|
|
||||||
if (ok) {
|
|
||||||
int new_area =
|
|
||||||
mrect.get_area();
|
|
||||||
int area_diff =
|
|
||||||
new_area -
|
|
||||||
old_area;
|
|
||||||
if (area_diff >
|
|
||||||
0) {
|
|
||||||
g.regions
|
|
||||||
.write[i]
|
|
||||||
.rect =
|
|
||||||
mrect;
|
|
||||||
g.regions
|
|
||||||
.write[i]
|
|
||||||
.remains_area -=
|
|
||||||
area_diff;
|
|
||||||
grown = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
state++;
|
|
||||||
grown = true;
|
|
||||||
if (state == 2)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
for (i = 0; i < g.regions.size(); i++) {
|
|
||||||
int x, y;
|
|
||||||
Rect2i rect = g.regions[i].rect;
|
|
||||||
for (x = rect.position.x;
|
|
||||||
x <= rect.position.x + rect.size.x; x++)
|
|
||||||
for (y = rect.position.y;
|
|
||||||
y <= rect.position.y + rect.size.y;
|
|
||||||
y++) {
|
|
||||||
int id = x + fl.grid_size * y;
|
|
||||||
if (!fl.cells.has(id)) {
|
|
||||||
flecs::entity seed_e =
|
|
||||||
floor_e.world().entity(
|
|
||||||
g.regions[i]
|
|
||||||
.seed_et);
|
|
||||||
assert(seed_e.is_valid());
|
|
||||||
queue_grow_cell(seed_e,
|
|
||||||
id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
#endif
|
||||||
|
#if 0
|
||||||
ecs.system<WorldEditor::components::buildings_layout_grid_floor>(
|
ecs.system<WorldEditor::components::buildings_layout_grid_floor>(
|
||||||
"GrowFloorRegions")
|
"GrowFloorRegions")
|
||||||
.kind(0)
|
.kind(0)
|
||||||
@@ -677,6 +751,8 @@ void BuildingLayoutGraph::graph_module::growth_module(flecs::world &ecs,
|
|||||||
" index: " + itos(index));
|
" index: " + itos(index));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
#endif
|
||||||
|
#if 0
|
||||||
ecs.system<const WorldEditor::components::buildings_layout_grid_cell>(
|
ecs.system<const WorldEditor::components::buildings_layout_grid_cell>(
|
||||||
"GrowRegions")
|
"GrowRegions")
|
||||||
.kind(0)
|
.kind(0)
|
||||||
@@ -711,11 +787,6 @@ void BuildingLayoutGraph::graph_module::growth_module(flecs::world &ecs,
|
|||||||
if (have_cell(floor_e, candidates[i]))
|
if (have_cell(floor_e, candidates[i]))
|
||||||
continue;
|
continue;
|
||||||
queue_grow_cell(e, candidates[i]);
|
queue_grow_cell(e, candidates[i]);
|
||||||
#if 0
|
|
||||||
String c_name = "cell_" + itos(candidates[i]);
|
|
||||||
flecs::entity c_e =
|
|
||||||
e.parent().lookup(c_name.ascii().ptr());
|
|
||||||
#endif
|
|
||||||
extended++;
|
extended++;
|
||||||
}
|
}
|
||||||
if (extended == 0)
|
if (extended == 0)
|
||||||
@@ -724,6 +795,7 @@ void BuildingLayoutGraph::graph_module::growth_module(flecs::world &ecs,
|
|||||||
" index: " + itos(index));
|
" index: " + itos(index));
|
||||||
e.world().defer_resume();
|
e.world().defer_resume();
|
||||||
});
|
});
|
||||||
|
#endif
|
||||||
ecs.system<WorldEditor::components::buildings_layout_grid_floor,
|
ecs.system<WorldEditor::components::buildings_layout_grid_floor,
|
||||||
WorldEditor::components::buildings_layout_grid_queue>(
|
WorldEditor::components::buildings_layout_grid_queue>(
|
||||||
"GrowCommitQueue")
|
"GrowCommitQueue")
|
||||||
@@ -751,40 +823,55 @@ void BuildingLayoutGraph::graph_module::growth_module(flecs::world &ecs,
|
|||||||
});
|
});
|
||||||
ecs.system("RunGrow")
|
ecs.system("RunGrow")
|
||||||
.kind(GraphFilter)
|
.kind(GraphFilter)
|
||||||
.run([module_name](flecs::iter &it) {
|
.run([module_name, this](flecs::iter &it) {
|
||||||
int i;
|
int i;
|
||||||
it.world().defer_suspend();
|
it.world().defer_suspend();
|
||||||
print_line("Running grow...");
|
flecs::log::dbg("Running grow...");
|
||||||
for (i = 0; i < 100; i++) {
|
flecs::query<WorldEditor::components::
|
||||||
it.world()
|
buildings_layout_grid_floor,
|
||||||
.system(it.world().lookup(
|
growth_regions>
|
||||||
(module_name +
|
q = it.world()
|
||||||
"::GrowFloorRectRegions")
|
.query_builder<
|
||||||
.ascii()
|
WorldEditor::components::
|
||||||
.ptr()))
|
buildings_layout_grid_floor,
|
||||||
.run();
|
growth_regions>()
|
||||||
it.world()
|
.build();
|
||||||
.system(it.world().lookup(
|
for (i = 0; i < 100; i++)
|
||||||
(module_name +
|
q.each([this](flecs::entity grid_floor_e,
|
||||||
"::GrowCommitQueue")
|
WorldEditor::components::
|
||||||
.ascii()
|
buildings_layout_grid_floor
|
||||||
.ptr()))
|
&fl,
|
||||||
.run();
|
growth_regions &g) {
|
||||||
}
|
struct grid_misc grid;
|
||||||
|
if (g.complete)
|
||||||
|
return;
|
||||||
|
grid.grow_region_rects(
|
||||||
|
this, grid_floor_e, fl, g);
|
||||||
|
grid.place_region_cells(
|
||||||
|
this, grid_floor_e, fl, g);
|
||||||
|
});
|
||||||
|
#if 0
|
||||||
|
q.each([this](flecs::entity grid_floor_e,
|
||||||
|
WorldEditor::components::
|
||||||
|
buildings_layout_grid_floor &fl,
|
||||||
|
growth_regions &g) {
|
||||||
|
g.complete = true;
|
||||||
|
});
|
||||||
|
#endif
|
||||||
#if 0
|
#if 0
|
||||||
it.world()
|
it.world()
|
||||||
.system(it.world().lookup(
|
.system(it.world().lookup(
|
||||||
(module_name + "::GrowFloorRegions")
|
(module_name + "::GrowFloorRectRegions")
|
||||||
.ascii()
|
.ascii()
|
||||||
.ptr()))
|
.ptr()))
|
||||||
.run();
|
.run();
|
||||||
|
#endif
|
||||||
it.world()
|
it.world()
|
||||||
.system(it.world().lookup(
|
.system(it.world().lookup(
|
||||||
(module_name + "::GrowCommitQueue")
|
(module_name + "::GrowCommitQueue")
|
||||||
.ascii()
|
.ascii()
|
||||||
.ptr()))
|
.ptr()))
|
||||||
.run();
|
.run();
|
||||||
#endif
|
|
||||||
it.world().defer_resume();
|
it.world().defer_resume();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,13 @@
|
|||||||
void BuildingLayoutGraph::graph_module::room_growth_module(
|
void BuildingLayoutGraph::graph_module::room_growth_module(
|
||||||
flecs::world &ecs, const String &module_name)
|
flecs::world &ecs, const String &module_name)
|
||||||
{
|
{
|
||||||
flecs::entity GraphFilter = ecs.entity("GraphFilter");
|
flecs::entity GraphFilter =
|
||||||
|
ecs.lookup((module_name + "::GraphFilter").ascii().ptr());
|
||||||
assert(GraphFilter.is_valid());
|
assert(GraphFilter.is_valid());
|
||||||
|
flecs::entity GraphGrowUnitAreas = ecs.entity("GraphGrowUnitAreas")
|
||||||
|
.add(flecs::Phase)
|
||||||
|
.depends_on(flecs::OnUpdate);
|
||||||
|
GraphGrowUnitAreas.disable();
|
||||||
flecs::entity GraphMarkData = ecs.entity("GraphMarkData")
|
flecs::entity GraphMarkData = ecs.entity("GraphMarkData")
|
||||||
.add(flecs::Phase)
|
.add(flecs::Phase)
|
||||||
.depends_on(flecs::OnUpdate);
|
.depends_on(flecs::OnUpdate);
|
||||||
@@ -16,8 +21,55 @@ void BuildingLayoutGraph::graph_module::room_growth_module(
|
|||||||
.add(flecs::Phase)
|
.add(flecs::Phase)
|
||||||
.depends_on(flecs::OnUpdate);
|
.depends_on(flecs::OnUpdate);
|
||||||
GraphProcessRooms.disable();
|
GraphProcessRooms.disable();
|
||||||
|
ecs.system<const WorldEditor::components::buildings_layout_unit>(
|
||||||
|
"AllocateUnitGrow")
|
||||||
|
.kind(GraphGrowUnitAreas)
|
||||||
|
.each([](flecs::entity ec,
|
||||||
|
const WorldEditor::components::buildings_layout_unit
|
||||||
|
&unit) {
|
||||||
|
ec.world()
|
||||||
|
.query_builder<const WorldEditor::components::
|
||||||
|
buildings_layout_zone>()
|
||||||
|
.build()
|
||||||
|
.each([](flecs::entity e,
|
||||||
|
const WorldEditor::components::
|
||||||
|
buildings_layout_zone &zone) {
|
||||||
|
// assert(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
ecs.system("CheckGrow").kind(GraphFilter).run([module_name](flecs::iter &it) {
|
ecs.system("CheckGrow").kind(GraphFilter).run([module_name](flecs::iter &it) {
|
||||||
|
int failed_zones = 0, total_zones = 0;
|
||||||
|
it.world()
|
||||||
|
.query_builder<const WorldEditor::components::
|
||||||
|
buildings_layout_zone>()
|
||||||
|
.build()
|
||||||
|
.each([&failed_zones, &total_zones](
|
||||||
|
flecs::entity ec,
|
||||||
|
const WorldEditor::components::
|
||||||
|
buildings_layout_zone &zone) {
|
||||||
|
int count = 0;
|
||||||
|
ec.world()
|
||||||
|
.query_builder<
|
||||||
|
const WorldEditor::components::
|
||||||
|
buildings_layout_grid_cell>()
|
||||||
|
.with<WorldEditor::components::belongs>(
|
||||||
|
ec)
|
||||||
|
.build()
|
||||||
|
.each([&count](
|
||||||
|
flecs::entity e,
|
||||||
|
const WorldEditor::components::
|
||||||
|
buildings_layout_grid_cell
|
||||||
|
&cell) {
|
||||||
|
count++;
|
||||||
|
});
|
||||||
|
if (count == 0)
|
||||||
|
failed_zones++;
|
||||||
|
total_zones++;
|
||||||
|
});
|
||||||
|
if (failed_zones > 0)
|
||||||
|
flecs::log::err("failed to allocate zones: %d/%d",
|
||||||
|
failed_zones, total_zones);
|
||||||
flecs::query<const WorldEditor::components::
|
flecs::query<const WorldEditor::components::
|
||||||
buildings_layout_grid_floor>
|
buildings_layout_grid_floor>
|
||||||
q = it.world()
|
q = it.world()
|
||||||
@@ -35,7 +87,7 @@ void BuildingLayoutGraph::graph_module::room_growth_module(
|
|||||||
count_left += MAX(0, fl.size_left);
|
count_left += MAX(0, fl.size_left);
|
||||||
});
|
});
|
||||||
// assert(false);
|
// assert(false);
|
||||||
if (count_run > 0 && count_left <= 0) {
|
if (count_run > 0 && count_left <= 0 && failed_zones == 0) {
|
||||||
it.world()
|
it.world()
|
||||||
.lookup((module_name + "::GraphFilter")
|
.lookup((module_name + "::GraphFilter")
|
||||||
.ascii()
|
.ascii()
|
||||||
@@ -48,6 +100,20 @@ void BuildingLayoutGraph::graph_module::room_growth_module(
|
|||||||
.ptr())
|
.ptr())
|
||||||
.enable();
|
.enable();
|
||||||
print_line("Mark started...");
|
print_line("Mark started...");
|
||||||
|
} else if (count_run > 0 && count_left <= 0 &&
|
||||||
|
failed_zones > 0) {
|
||||||
|
it.world()
|
||||||
|
.lookup((module_name + "::GraphFilter")
|
||||||
|
.ascii()
|
||||||
|
.ptr())
|
||||||
|
.disable();
|
||||||
|
print_line("Grow done");
|
||||||
|
it.world()
|
||||||
|
.lookup((module_name + "::GraphGrowUnitAreas")
|
||||||
|
.ascii()
|
||||||
|
.ptr())
|
||||||
|
.enable();
|
||||||
|
print_line("Grow unit started...");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ecs.system<const WorldEditor::components::buildings_layout_grid_cell>(
|
ecs.system<const WorldEditor::components::buildings_layout_grid_cell>(
|
||||||
|
|||||||
Reference in New Issue
Block a user