Now layout build works fine
This commit is contained in:
735
src/modules/stream/ui/grow_job.cpp
Normal file
735
src/modules/stream/ui/grow_job.cpp
Normal file
@@ -0,0 +1,735 @@
|
||||
#include "base_data.h"
|
||||
#include "world_editor.h"
|
||||
#include "grid_misc.h"
|
||||
#include "graph_module.h"
|
||||
#include "queries.h"
|
||||
#include "region_tree.h"
|
||||
#include "grow_job.h"
|
||||
|
||||
static inline int get_floor_index(flecs::entity e)
|
||||
{
|
||||
return e.get<WorldEditor::components::buildings_layout_floor_index>()
|
||||
->index;
|
||||
}
|
||||
|
||||
static inline flecs::entity get_grid_floor(flecs::entity grid_e,
|
||||
flecs::entity graph_floor_e)
|
||||
{
|
||||
assert(grid_e.is_valid());
|
||||
assert(graph_floor_e.is_valid());
|
||||
int floor_index = get_floor_index(graph_floor_e);
|
||||
String floor_name = "floor_" + itos(floor_index);
|
||||
// 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;
|
||||
}
|
||||
|
||||
grow_job_queue::grow_job_queue(
|
||||
flecs::entity grid_e, struct subregions &subregions,
|
||||
const WorldEditor::components::buildings_layout_grid_size &size,
|
||||
const String &module_name)
|
||||
: grid_e(grid_e)
|
||||
, grid_size(size.grid_size)
|
||||
, subregions(subregions)
|
||||
, module_name(module_name)
|
||||
{
|
||||
const List<Pair<int, flecs::entity_t> >::Element *me;
|
||||
List<Pair<flecs::entity_t, flecs::entity_t> > job_create_queue;
|
||||
me = size.floors.front();
|
||||
while (me) {
|
||||
// graph entity
|
||||
job_create_queue.push_back(
|
||||
{ me->get().second, me->get().second });
|
||||
flecs::entity_t base_floor_et =
|
||||
job_create_queue.front()->get().second;
|
||||
flecs::entity base_floor_e =
|
||||
grid_e.world().entity(base_floor_et);
|
||||
flecs::entity grid_floor_e =
|
||||
get_grid_floor(grid_e, base_floor_e);
|
||||
grid_floor_e.get_mut<growth_regions>()->job_list =
|
||||
List<grow_job>();
|
||||
me = me->next();
|
||||
}
|
||||
while (!job_create_queue.empty()) {
|
||||
// graph entity
|
||||
flecs::entity_t et = job_create_queue.front()->get().first;
|
||||
// parent graph entity
|
||||
flecs::entity_t base_floor_et =
|
||||
job_create_queue.front()->get().second;
|
||||
job_create_queue.pop_front();
|
||||
flecs::entity base_floor_e =
|
||||
grid_e.world().entity(base_floor_et);
|
||||
flecs::log::dbg("job_queue: base_floor: %s",
|
||||
base_floor_e.path().c_str());
|
||||
flecs::entity grid_floor_e =
|
||||
get_grid_floor(grid_e, base_floor_e);
|
||||
flecs::log::dbg("job_queue: grid_floor: %s",
|
||||
grid_floor_e.path().c_str());
|
||||
assert(!subregions.sub_subregions.empty());
|
||||
if (subregions.sub_subregions.has(et) &&
|
||||
!subregions.sub_subregions[et].empty()) {
|
||||
flecs::log::dbg(
|
||||
"subregions for: %s",
|
||||
grid_e.world().entity(et).path().c_str());
|
||||
struct grow_job job;
|
||||
if (grid_floor_e.get<growth_regions>()->job_list.empty())
|
||||
job.job_type = grow_job::INITIAL;
|
||||
else
|
||||
job.job_type = grow_job::COMMON;
|
||||
job.parent_id = et;
|
||||
job.base_floor_id = base_floor_et;
|
||||
job.grid_floor_id = grid_floor_e.id();
|
||||
job.subregions =
|
||||
subregions.sub_subregions[job.parent_id];
|
||||
grid_floor_e.get_mut<growth_regions>()
|
||||
->job_list.push_back(job);
|
||||
List<Pair<flecs::entity, float> >::Element *se =
|
||||
job.subregions.front();
|
||||
while (se) {
|
||||
job_create_queue.push_back(
|
||||
{ se->get().first.id(),
|
||||
base_floor_et });
|
||||
se = se->next();
|
||||
}
|
||||
grid_floor_e.modified<growth_regions>();
|
||||
} else
|
||||
flecs::log::dbg(
|
||||
"no subregions for: %s",
|
||||
grid_e.world().entity(et).path().c_str());
|
||||
}
|
||||
}
|
||||
void grow_job_queue::job_initial(struct grow_job *job)
|
||||
{
|
||||
int i, j;
|
||||
flecs::entity base_floor_e = grid_e.world().entity(job->base_floor_id);
|
||||
flecs::entity grid_floor_e = grid_e.world().entity(job->grid_floor_id);
|
||||
flecs::log::dbg("create: base_floor: %s", base_floor_e.path().c_str());
|
||||
flecs::log::dbg("create: grid_floor: %s", grid_floor_e.path().c_str());
|
||||
growth_regions *g = grid_floor_e.get_mut<growth_regions>();
|
||||
RegionRect2i clip_rect(1, 1, grid_size - 2, grid_size - 2);
|
||||
const List<Pair<flecs::entity, float> > &subregions = job->subregions;
|
||||
List<struct region> initial_regions;
|
||||
#if 0
|
||||
assert(g->regions.size() == 0);
|
||||
#endif
|
||||
if (subregions.size() == 0) {
|
||||
flecs::log::err("nothing to do");
|
||||
return;
|
||||
}
|
||||
grid_floor_e.set<region_tree>(
|
||||
{ { job->base_floor_id, job->base_floor_id, job->base_floor_id,
|
||||
clip_rect.grow(-1), grid_size * grid_size, false, false,
|
||||
true },
|
||||
Vector<struct region_tree *>(),
|
||||
nullptr });
|
||||
struct region_tree *rtree = grid_floor_e.get_mut<region_tree>();
|
||||
create_region_list(rtree, subregions, initial_regions);
|
||||
grid_floor_e.modified<region_tree>();
|
||||
grid_floor_e.get_mut<region_tree>()->split(grid_floor_e,
|
||||
initial_regions);
|
||||
assert(rtree->check(grid_floor_e));
|
||||
grid_floor_e.modified<region_tree>();
|
||||
grid_floor_e.get<region_tree>()->dump(grid_floor_e);
|
||||
grid_floor_e.get_mut<region_tree>()->grow(grid_floor_e);
|
||||
grid_floor_e.modified<region_tree>();
|
||||
grid_floor_e.get<region_tree>()->dump(grid_floor_e);
|
||||
// grid_floor_e.get<region_tree>()->place(grid_floor_e);
|
||||
List<RegionRect2i> rects;
|
||||
List<RegionRect2i>::Element *e, *e1;
|
||||
grid_floor_e.get<region_tree>()->get_rects(&rects);
|
||||
e = rects.front();
|
||||
bool ok = true;
|
||||
while (e) {
|
||||
e1 = rects.front();
|
||||
while (e1) {
|
||||
if (e->get() == e1->get()) {
|
||||
e1 = e1->next();
|
||||
continue;
|
||||
}
|
||||
if (e->get().intersects(e1->get()))
|
||||
ok = false;
|
||||
if (e->get().encloses(e1->get()))
|
||||
ok = false;
|
||||
if (e1->get().intersects(e->get()))
|
||||
ok = false;
|
||||
if (e1->get().encloses(e->get()))
|
||||
ok = false;
|
||||
if (!ok)
|
||||
break;
|
||||
e1 = e1->next();
|
||||
}
|
||||
e = e->next();
|
||||
}
|
||||
|
||||
#if 0
|
||||
while (fe) {
|
||||
flecs::entity ce = fe->get().first;
|
||||
float area = fe->get().second;
|
||||
flecs::log::warn("generating positions for: %s",
|
||||
ce.path().c_str());
|
||||
job->grid.filter_candidates(ce, area, clip_rect);
|
||||
fe = fe->next();
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
job->grid.place_regions(grid_floor_e);
|
||||
|
||||
flecs::log::dbg("Running grow...");
|
||||
queries.get_qr().each(
|
||||
[this](flecs::entity grid_floor_e,
|
||||
WorldEditor::components::buildings_layout_grid_floor &fl,
|
||||
growth_regions &g) {
|
||||
struct grid_misc grd;
|
||||
if (g.complete)
|
||||
return;
|
||||
grd.grow_region_rects(grid_floor_e, fl, g);
|
||||
grd.place_region_cells(grid_floor_e, fl, g);
|
||||
});
|
||||
queries.get_qr().each(
|
||||
[](flecs::entity grid_floor_e,
|
||||
WorldEditor::components::buildings_layout_grid_floor &fl,
|
||||
growth_regions &g) {
|
||||
int i;
|
||||
for (i = 0; i < (int)g.regions.size(); i++)
|
||||
g.regions.write[i].complete = true;
|
||||
g.complete = true;
|
||||
});
|
||||
grid_e.world()
|
||||
.system(grid_e.world().lookup(
|
||||
(module_name + "::GrowCommitQueue").ascii().ptr()))
|
||||
.run();
|
||||
queries.get_mark_cells().each([](flecs::entity e,
|
||||
const WorldEditor::components::
|
||||
buildings_layout_grid_cell
|
||||
&cell) {
|
||||
int grid_size =
|
||||
e.parent()
|
||||
.get<WorldEditor::components::
|
||||
buildings_layout_grid_floor>()
|
||||
->grid_size;
|
||||
int i;
|
||||
Vector2i position(cell.index % grid_size,
|
||||
cell.index / grid_size);
|
||||
Vector2 west(position.x - 1, position.y);
|
||||
Vector2 north(position.x, position.y - 1);
|
||||
Vector2 east(position.x + 1, position.y);
|
||||
Vector2 south(position.x, position.y + 1);
|
||||
int west_id = west.x + grid_size * west.y;
|
||||
int north_id = north.x + grid_size * north.y;
|
||||
int east_id = east.x + grid_size * east.y;
|
||||
int south_id = south.x + grid_size * south.y;
|
||||
std::vector<int> neighbors = { west_id, north_id, east_id,
|
||||
south_id };
|
||||
bool outside = false;
|
||||
bool border = false;
|
||||
for (i = 0; i < (int)neighbors.size(); i++) {
|
||||
int id = neighbors[i];
|
||||
print_line("id=" + itos(id));
|
||||
if (!e.parent()
|
||||
.get<WorldEditor::components::
|
||||
buildings_layout_grid_floor>()
|
||||
->cells.has(id)) {
|
||||
outside = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < (int)neighbors.size(); i++) {
|
||||
int id = neighbors[i];
|
||||
print_line("id=" + itos(id));
|
||||
String neighbor_name = "cell_" + itos(id);
|
||||
flecs::entity neighbor_e =
|
||||
e.parent().lookup(neighbor_name.ascii().ptr());
|
||||
if (!neighbor_e.is_valid())
|
||||
continue;
|
||||
const WorldEditor::components::buildings_layout_grid_cell
|
||||
*neighbor_cell = neighbor_e.get<
|
||||
WorldEditor::components::
|
||||
buildings_layout_grid_cell>();
|
||||
if (cell.type != neighbor_cell->type) {
|
||||
border = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (outside)
|
||||
e.add<WorldEditor::components::outside_wall>();
|
||||
else
|
||||
e.add<WorldEditor::components::final_cell>();
|
||||
if (border)
|
||||
e.add<WorldEditor::components::border>();
|
||||
print_line("outside: " + itos(outside));
|
||||
print_line("position: " + (position.operator String()));
|
||||
print_line("grid size: " + itos(grid_size));
|
||||
print_line("tile index: " + itos(cell.index));
|
||||
});
|
||||
flecs::log::dbg("initial: region count: %d", g->regions.size());
|
||||
assert(g->regions.size() > 0);
|
||||
#endif
|
||||
assert(rtree->check(grid_floor_e));
|
||||
}
|
||||
void grow_job_queue::job_common(struct grow_job *job)
|
||||
{
|
||||
int i, j;
|
||||
make_random r(172);
|
||||
flecs::entity base_floor_e = grid_e.world().entity(job->base_floor_id);
|
||||
flecs::entity grid_floor_e = grid_e.world().entity(job->grid_floor_id);
|
||||
flecs::log::dbg("create: base_floor: %s", base_floor_e.path().c_str());
|
||||
flecs::log::dbg("create: grid_floor: %s", grid_floor_e.path().c_str());
|
||||
flecs::entity parent_e = grid_e.world().entity(job->parent_id);
|
||||
growth_regions *g = grid_floor_e.get_mut<growth_regions>();
|
||||
const List<Pair<flecs::entity, float> > &subregions = job->subregions;
|
||||
const List<Pair<flecs::entity, float> >::Element *fe =
|
||||
subregions.front();
|
||||
|
||||
struct region_tree *base_rtree = grid_floor_e.get_mut<region_tree>(),
|
||||
*rtree;
|
||||
List<struct region> region_list;
|
||||
base_rtree->dump(grid_floor_e);
|
||||
flecs::log::warn("search for: %s %lx", parent_e.path().c_str(),
|
||||
job->parent_id);
|
||||
rtree = base_rtree->find(job->parent_id);
|
||||
if (!rtree) {
|
||||
g->job_list.push_back(*job);
|
||||
flecs::log::warn("delay job fo %s (%d jobs)",
|
||||
parent_e.path().c_str(), g->job_list.size());
|
||||
return;
|
||||
}
|
||||
create_region_list(rtree, subregions, region_list);
|
||||
assert(base_rtree->check(grid_floor_e));
|
||||
rtree->split(grid_floor_e, region_list);
|
||||
assert(base_rtree->check(grid_floor_e));
|
||||
grid_floor_e.modified<region_tree>();
|
||||
rtree->dump(grid_floor_e);
|
||||
assert(base_rtree->check(grid_floor_e));
|
||||
rtree->grow(grid_floor_e);
|
||||
assert(base_rtree->check(grid_floor_e));
|
||||
rtree->dump(grid_floor_e);
|
||||
grid_floor_e.modified<region_tree>();
|
||||
|
||||
#if 0
|
||||
flecs::log::dbg("common: region count: %d", g->regions.size());
|
||||
assert(g->regions.size() > 0);
|
||||
bool restart = false, found = false;
|
||||
RegionRect2i clip_rect(0, 0, grid_size, grid_size);
|
||||
for (i = 0; i < (int)g->regions.size(); i++) {
|
||||
flecs::log::dbg("region %d: %s", i,
|
||||
grid_e.world()
|
||||
.entity(g->regions[i].region_et)
|
||||
.path()
|
||||
.c_str());
|
||||
}
|
||||
int region_index = -1;
|
||||
for (i = 0; i < (int)g->regions.size(); i++) {
|
||||
if (g->regions[i].region_et == job->parent_id) {
|
||||
flecs::log::warn("parent is in regions %d", i);
|
||||
region_index = i;
|
||||
if (!g->regions[i].complete) {
|
||||
g->job_list.push_back(*job);
|
||||
restart = true;
|
||||
flecs::log::err(
|
||||
"parent is in regions %d incomplete",
|
||||
i);
|
||||
flecs::log::warn("delay job fo %s (%d jobs)",
|
||||
grid_e.world()
|
||||
.entity(job->parent_id)
|
||||
.path()
|
||||
.c_str(),
|
||||
g->job_list.size());
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
// no parent region yet
|
||||
g->job_list.push_back(*job);
|
||||
flecs::log::warn("delay job fo %s (%d jobs)",
|
||||
parent_e.path().c_str(), g->job_list.size());
|
||||
restart = true;
|
||||
}
|
||||
if (restart)
|
||||
return;
|
||||
#endif
|
||||
#if 0
|
||||
for (i = 0; i < g->regions.size(); i++)
|
||||
flecs::log::warn(
|
||||
"before: region %d: %s", i,
|
||||
(g->regions[i].rect.operator String()).ascii().ptr());
|
||||
// growth_regions::region parent_region = g->regions[region_index];
|
||||
// const List<Pair<flecs::entity, float> >::Element *fe =
|
||||
// subregions.front();
|
||||
List<Pair<flecs::entity, float> > region_list = subregions;
|
||||
g->split_region(grid_floor_e, region_index, region_list);
|
||||
#endif
|
||||
// g->regions.remove(region_index);
|
||||
// clip_rect = parent_region.rect;
|
||||
// int parent_region_index = g->parent_regions.size();
|
||||
// g->parent_regions.push_back(parent_region);
|
||||
/*
|
||||
while (fe) {
|
||||
flecs::entity ce = fe->get().first;
|
||||
float area = fe->get().second;
|
||||
flecs::log::warn("generating positions for: %s",
|
||||
ce.path().c_str());
|
||||
job->grid.filter_candidates(ce, area, clip_rect);
|
||||
fe = fe->next();
|
||||
}
|
||||
job->grid.place_regions_common(parent_e, grid_floor_e,
|
||||
parent_region_index);
|
||||
*/
|
||||
#if 0
|
||||
for (i = 0; i < g->regions.size(); i++)
|
||||
flecs::log::warn(
|
||||
"after: region %d: %s", i,
|
||||
(g->regions[i].rect.operator String()).ascii().ptr());
|
||||
flecs::log::dbg("Running grow...");
|
||||
g->grow_regions(grid_floor_e);
|
||||
#endif
|
||||
#if 0
|
||||
// FIXME: fix this
|
||||
queries.get_qr().each(
|
||||
[this, parent_e](
|
||||
flecs::entity grid_floor_e,
|
||||
WorldEditor::components::buildings_layout_grid_floor &fl,
|
||||
growth_regions &g) {
|
||||
if (g.complete)
|
||||
return;
|
||||
g.grow_regions(grid_floor_e);
|
||||
});
|
||||
#endif
|
||||
#if 0
|
||||
for (i = 0; i < g->regions.size(); i++)
|
||||
flecs::log::warn(
|
||||
"after2: region %d: %s", i,
|
||||
(g->regions[i].rect.operator String()).ascii().ptr());
|
||||
#endif
|
||||
#if 0
|
||||
queries.get_qr().each(
|
||||
[this, parent_e](
|
||||
flecs::entity grid_floor_e,
|
||||
WorldEditor::components::buildings_layout_grid_floor &fl,
|
||||
growth_regions &g) {
|
||||
struct grid_misc grd;
|
||||
// if (g.complete)
|
||||
// return;
|
||||
//grd.grow_region_rects(grid_floor_e, fl, g);
|
||||
grd.update_region_cells(grid_floor_e, parent_e, fl, g);
|
||||
assert(false);
|
||||
});
|
||||
#endif
|
||||
#if 0
|
||||
update_region_cells(grid_floor_e);
|
||||
for (i = 0; i < (int)g->regions.size(); i++)
|
||||
g->regions.write[i].complete = true;
|
||||
g->complete = true;
|
||||
#endif
|
||||
commit_common_queue();
|
||||
// assert(false);
|
||||
}
|
||||
void grow_job_queue::commit_common_queue()
|
||||
{
|
||||
grid_e.world()
|
||||
.query_builder<
|
||||
WorldEditor::components::buildings_layout_grid_floor,
|
||||
WorldEditor::components::buildings_layout_grid_queue>()
|
||||
.each([this](flecs::entity e,
|
||||
WorldEditor::components::buildings_layout_grid_floor
|
||||
&fl,
|
||||
WorldEditor::components::buildings_layout_grid_queue
|
||||
&queue) {
|
||||
List<Pair<flecs::entity_t, int> >::Element *me =
|
||||
queue.queue.front();
|
||||
while (me) {
|
||||
flecs::entity seed_e =
|
||||
e.world().entity(me->get().first);
|
||||
int id = me->get().second;
|
||||
if (!fl.cells.has(id)) {
|
||||
flecs::log::err("bad cell %d", id);
|
||||
assert(false);
|
||||
}
|
||||
// fl.cells.insert(id);
|
||||
flecs::entity floor_e = seed_e.parent();
|
||||
String c_name = "cell_" + itos(id);
|
||||
flecs::entity c_e =
|
||||
floor_e.lookup(c_name.ascii().ptr());
|
||||
if (c_e.is_valid() &&
|
||||
c_e.has<WorldEditor::components::
|
||||
buildings_layout_grid_cell>()) {
|
||||
// flecs::log::dbg("cell: %s: %s",
|
||||
// e.path().c_str(),
|
||||
// c_e.path().c_str());
|
||||
String type =
|
||||
seed_e.get<WorldEditor::components::
|
||||
buildings_layout_grid_cell>()
|
||||
->type;
|
||||
c_e.set<WorldEditor::components::
|
||||
buildings_layout_grid_cell>(
|
||||
{ type, id });
|
||||
seed_e.each<
|
||||
WorldEditor::components::belongs>(
|
||||
[&c_e](flecs::entity second) {
|
||||
c_e.add<WorldEditor::components::
|
||||
belongs>(
|
||||
second);
|
||||
});
|
||||
seed_e.each<WorldEditor::components::
|
||||
belongs_room>(
|
||||
[&c_e](flecs::entity second) {
|
||||
c_e.add<WorldEditor::components::
|
||||
belongs_room>(
|
||||
second);
|
||||
});
|
||||
floor_e.modified<
|
||||
WorldEditor::components::
|
||||
buildings_layout_grid_floor>();
|
||||
} else {
|
||||
flecs::log::err("bad cell %s",
|
||||
c_name.ascii().ptr());
|
||||
assert(false);
|
||||
}
|
||||
me = me->next();
|
||||
}
|
||||
queue.queue.clear();
|
||||
e.remove<WorldEditor::components::
|
||||
buildings_layout_grid_queue>();
|
||||
});
|
||||
}
|
||||
void grow_job_queue::create_region_list(
|
||||
region_tree *rtree, const List<Pair<flecs::entity, float> > &subregions,
|
||||
List<struct region> ®ion_list)
|
||||
{
|
||||
int i, j;
|
||||
const List<Pair<flecs::entity, float> >::Element *fe =
|
||||
subregions.front();
|
||||
bool restart = false, found = false;
|
||||
make_random r(172);
|
||||
RegionRect2i clip_rect = rtree->region.rect;
|
||||
Vector2i current_position = clip_rect.get_center();
|
||||
Vector2i velocity;
|
||||
|
||||
Vector<flecs::entity> regions;
|
||||
LocalVector<Vector2i> positions;
|
||||
Vector<int> distances;
|
||||
LocalVector<float> areas;
|
||||
// Drunk walk implementation
|
||||
int speed = MAX(1, grid_size * grid_size / 2 / subregions.size());
|
||||
int bad_count = 0;
|
||||
while (fe) {
|
||||
Vector<Vector2i> position_candidates;
|
||||
if (positions.empty()) {
|
||||
int target_distance =
|
||||
(int)(Math::sqrt(fe->get().second) * 0.7f) + 1;
|
||||
positions.push_back(current_position);
|
||||
distances.push_back(target_distance);
|
||||
regions.push_back(fe->get().first);
|
||||
areas.push_back(fe->get().second);
|
||||
fe = fe->next();
|
||||
if (!fe)
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < (int)positions.size(); i++) {
|
||||
int which = r.get() % 12;
|
||||
switch (which) {
|
||||
case 1:
|
||||
velocity = { 0, 1 };
|
||||
break;
|
||||
case 3:
|
||||
velocity = { 1, 0 };
|
||||
break;
|
||||
case 5:
|
||||
velocity = { 0, -1 };
|
||||
break;
|
||||
case 7:
|
||||
velocity = { -1, 0 };
|
||||
break;
|
||||
}
|
||||
if (clip_rect.has_point(current_position + velocity)) {
|
||||
position_candidates.push_back(current_position +
|
||||
velocity);
|
||||
current_position += velocity;
|
||||
}
|
||||
}
|
||||
int target_distance =
|
||||
(int)(Math::sqrt(fe->get().second) * 0.7f) + 1;
|
||||
assert(fe);
|
||||
if (bad_count > 100)
|
||||
target_distance = 1;
|
||||
bool any_match = false;
|
||||
for (i = 0; i < position_candidates.size(); i++) {
|
||||
bool bad = false;
|
||||
assert(fe);
|
||||
for (j = 0; j < (int)positions.size(); j++) {
|
||||
Vector2i l =
|
||||
position_candidates[i] - positions[j];
|
||||
int distance =
|
||||
l.x * l.x + l.y * l.y - distances[j];
|
||||
if (distance < target_distance) {
|
||||
bad = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(fe);
|
||||
if (!bad) {
|
||||
assert(fe);
|
||||
positions.push_back(position_candidates[i]);
|
||||
distances.push_back(target_distance);
|
||||
regions.push_back(fe->get().first);
|
||||
areas.push_back(fe->get().second);
|
||||
any_match = true;
|
||||
bad_count = 0;
|
||||
if (fe) {
|
||||
fe = fe->next();
|
||||
if (fe)
|
||||
target_distance =
|
||||
(int)(Math::sqrt(
|
||||
fe->get()
|
||||
.second) *
|
||||
0.7f) +
|
||||
1;
|
||||
}
|
||||
}
|
||||
if (!fe)
|
||||
break;
|
||||
}
|
||||
if (!any_match) {
|
||||
flecs::log::err(
|
||||
"No match found: %s: %s",
|
||||
(clip_rect.operator String()).ascii().ptr(),
|
||||
(current_position.operator String())
|
||||
.ascii()
|
||||
.ptr());
|
||||
bad_count++;
|
||||
}
|
||||
if (bad_count >= 100) {
|
||||
position_candidates.clear();
|
||||
int x, y;
|
||||
for (x = clip_rect.position.x;
|
||||
x < clip_rect.position.x + clip_rect.size.x; x++)
|
||||
for (y = clip_rect.position.y;
|
||||
y <
|
||||
clip_rect.position.y + clip_rect.size.y;
|
||||
y++) {
|
||||
position_candidates.push_back(
|
||||
Vector2i(x, y));
|
||||
}
|
||||
bad_count = 0;
|
||||
for (i = 0; i < position_candidates.size(); i++) {
|
||||
bool bad = false;
|
||||
assert(fe);
|
||||
for (j = 0; j < (int)positions.size(); j++) {
|
||||
Vector2i l = position_candidates[i] -
|
||||
positions[j];
|
||||
int distance = l.x * l.x + l.y * l.y -
|
||||
distances[j];
|
||||
if (distance > 0) {
|
||||
bad = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(fe);
|
||||
if (!bad) {
|
||||
assert(fe);
|
||||
positions.push_back(
|
||||
position_candidates[i]);
|
||||
distances.push_back(target_distance);
|
||||
regions.push_back(fe->get().first);
|
||||
areas.push_back(fe->get().second);
|
||||
any_match = true;
|
||||
bad_count = 0;
|
||||
if (fe)
|
||||
fe = fe->next();
|
||||
}
|
||||
if (!fe)
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(bad_count < 2000);
|
||||
}
|
||||
flecs::log::dbg("grid_size %d", grid_size);
|
||||
for (i = 0; i < (int)positions.size(); i++) {
|
||||
struct region region;
|
||||
flecs::log::dbg("region: %s", regions[i].path().c_str());
|
||||
flecs::log::dbg("position: %d, %d", positions[i].x,
|
||||
positions[i].y);
|
||||
region.complete = false;
|
||||
region.can_grow = true;
|
||||
region.can_grow_square = true;
|
||||
region.parent = rtree->region.region_et;
|
||||
region.rect = RegionRect2i(positions[i], Vector2i(1, 1));
|
||||
region.region_et = regions[i].id();
|
||||
region.remains_area = MAX(1, (areas[i] / 16));
|
||||
/* setting seed uninitialized */
|
||||
region_list.push_back(region);
|
||||
}
|
||||
}
|
||||
void grow_job_queue::iterate()
|
||||
{
|
||||
assert(grid_e.is_valid());
|
||||
assert(this);
|
||||
flecs::query<growth_regions> q =
|
||||
grid_e.world().query_builder<growth_regions>().build();
|
||||
q.each([this](flecs::entity e, growth_regions &g) {
|
||||
flecs::log::warn("pre floor: %s", e.path().c_str());
|
||||
});
|
||||
q.each([this](flecs::entity e, growth_regions &g) {
|
||||
flecs::log::warn("floor: %s", e.path().c_str());
|
||||
flecs::log::warn("job count: %d", g.job_list.size());
|
||||
while (!g.job_list.empty()) {
|
||||
List<struct grow_job>::Element *job_e =
|
||||
g.job_list.front();
|
||||
assert(job_e);
|
||||
flecs::entity base_floor_e = grid_e.world().entity(
|
||||
job_e->get().base_floor_id);
|
||||
assert(base_floor_e.is_valid());
|
||||
flecs::entity grid_floor_e = grid_e.world().entity(
|
||||
job_e->get().grid_floor_id);
|
||||
assert(grid_floor_e.is_valid());
|
||||
flecs::log::dbg("inerate: create: base_floor: %s",
|
||||
base_floor_e.path().c_str());
|
||||
flecs::log::dbg("iterate: create: grid_floor: %s",
|
||||
grid_floor_e.path().c_str());
|
||||
switch (job_e->get().job_type) {
|
||||
case grow_job::INITIAL:
|
||||
flecs::log::dbg("initial");
|
||||
job_initial(&job_e->get());
|
||||
{
|
||||
const region_tree *rtree =
|
||||
e.get<region_tree>();
|
||||
assert(!rtree ||
|
||||
(rtree &&
|
||||
rtree->check(grid_floor_e)));
|
||||
}
|
||||
break;
|
||||
case grow_job::COMMON:
|
||||
flecs::log::dbg("common");
|
||||
job_common(&job_e->get());
|
||||
{
|
||||
const region_tree *rtree =
|
||||
e.get<region_tree>();
|
||||
assert(!rtree ||
|
||||
(rtree &&
|
||||
rtree->check(grid_floor_e)));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
g.job_list.pop_front();
|
||||
// if (common_count > 0)
|
||||
// break;
|
||||
}
|
||||
g.job_list.clear();
|
||||
flecs::query<region_tree> qm =
|
||||
grid_e.world().query_builder<region_tree>().build();
|
||||
qm.each([this](flecs::entity em, region_tree &rt) {
|
||||
assert(rt.check(em));
|
||||
});
|
||||
qm.each([this](flecs::entity em, region_tree &rt) {
|
||||
rt.place(em);
|
||||
});
|
||||
flecs::log::dbg(
|
||||
"processed jobs (created region initial positions): %d",
|
||||
g.job_list.size());
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user