Shrinking is broken
This commit is contained in:
@@ -140,7 +140,7 @@ entries=[ {
|
||||
"type": "zone",
|
||||
"zone_type": 0
|
||||
}, {
|
||||
"children": [ 54, 55, 56, 57, 58 ],
|
||||
"children": [ 54, 55, 56, 57 ],
|
||||
"commands": [ ],
|
||||
"index": 18,
|
||||
"name": "zone_3",
|
||||
@@ -148,7 +148,7 @@ entries=[ {
|
||||
"type": "zone",
|
||||
"zone_type": 1
|
||||
}, {
|
||||
"children": [ 59, 60 ],
|
||||
"children": [ 58, 59 ],
|
||||
"commands": [ ],
|
||||
"index": 19,
|
||||
"name": "zone_0",
|
||||
@@ -156,7 +156,7 @@ entries=[ {
|
||||
"type": "zone",
|
||||
"zone_type": 0
|
||||
}, {
|
||||
"children": [ 61, 62 ],
|
||||
"children": [ 60, 61 ],
|
||||
"commands": [ ],
|
||||
"index": 20,
|
||||
"name": "zone_1",
|
||||
@@ -304,7 +304,7 @@ entries=[ {
|
||||
"type": "room",
|
||||
"window": true
|
||||
}, {
|
||||
"children": [ 63, 64, 65 ],
|
||||
"children": [ 62, 63, 64 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 35,
|
||||
"name": "zone_0",
|
||||
@@ -312,7 +312,7 @@ entries=[ {
|
||||
"type": "zone",
|
||||
"zone_type": 0
|
||||
}, {
|
||||
"children": [ 66, 67 ],
|
||||
"children": [ 65, 66 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 36,
|
||||
"name": "zone_1",
|
||||
@@ -330,7 +330,7 @@ entries=[ {
|
||||
"type": "room",
|
||||
"window": true
|
||||
}, {
|
||||
"children": [ 68 ],
|
||||
"children": [ 67 ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 38,
|
||||
"name": "stair_0",
|
||||
@@ -340,7 +340,7 @@ entries=[ {
|
||||
"type": "room",
|
||||
"window": true
|
||||
}, {
|
||||
"children": [ 69, 70, 71 ],
|
||||
"children": [ 68, 69, 70 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 39,
|
||||
"name": "zone_0",
|
||||
@@ -348,7 +348,7 @@ entries=[ {
|
||||
"type": "zone",
|
||||
"zone_type": 0
|
||||
}, {
|
||||
"children": [ 72, 73 ],
|
||||
"children": [ 71, 72 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 40,
|
||||
"name": "zone_1",
|
||||
@@ -356,7 +356,7 @@ entries=[ {
|
||||
"type": "zone",
|
||||
"zone_type": 1
|
||||
}, {
|
||||
"children": [ 74 ],
|
||||
"children": [ 73 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 41,
|
||||
"name": "zone_0",
|
||||
@@ -364,7 +364,7 @@ entries=[ {
|
||||
"type": "zone",
|
||||
"zone_type": 0
|
||||
}, {
|
||||
"children": [ 75, 76 ],
|
||||
"children": [ 74, 75 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 42,
|
||||
"name": "zone_1",
|
||||
@@ -372,7 +372,7 @@ entries=[ {
|
||||
"type": "zone",
|
||||
"zone_type": 1
|
||||
}, {
|
||||
"children": [ 77 ],
|
||||
"children": [ 76 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 43,
|
||||
"name": "zone_0",
|
||||
@@ -380,7 +380,7 @@ entries=[ {
|
||||
"type": "zone",
|
||||
"zone_type": 0
|
||||
}, {
|
||||
"children": [ 78 ],
|
||||
"children": [ 77 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 44,
|
||||
"name": "zone_1",
|
||||
@@ -388,7 +388,7 @@ entries=[ {
|
||||
"type": "zone",
|
||||
"zone_type": 1
|
||||
}, {
|
||||
"children": [ 79 ],
|
||||
"children": [ 78 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 45,
|
||||
"name": "zone_0",
|
||||
@@ -396,7 +396,7 @@ entries=[ {
|
||||
"type": "zone",
|
||||
"zone_type": 0
|
||||
}, {
|
||||
"children": [ 80 ],
|
||||
"children": [ 79 ],
|
||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||
"index": 46,
|
||||
"name": "zone_1",
|
||||
@@ -517,16 +517,6 @@ entries=[ {
|
||||
"children": [ ],
|
||||
"commands": [ ],
|
||||
"index": 58,
|
||||
"name": "enterance_1",
|
||||
"order": 5,
|
||||
"room_area": 16.0,
|
||||
"room_type": 304,
|
||||
"type": "room",
|
||||
"window": true
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ ],
|
||||
"index": 59,
|
||||
"name": "wc_0",
|
||||
"order": 1,
|
||||
"room_area": 0.0,
|
||||
@@ -536,7 +526,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ ],
|
||||
"index": 60,
|
||||
"index": 59,
|
||||
"name": "bathroom_0",
|
||||
"order": 2,
|
||||
"room_area": 64.0,
|
||||
@@ -546,7 +536,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ ],
|
||||
"index": 61,
|
||||
"index": 60,
|
||||
"name": "studio_0",
|
||||
"order": 1,
|
||||
"room_area": 144.0,
|
||||
@@ -556,7 +546,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ ],
|
||||
"index": 62,
|
||||
"index": 61,
|
||||
"name": "enterance_0",
|
||||
"order": 2,
|
||||
"room_area": 0.0,
|
||||
@@ -566,7 +556,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 63,
|
||||
"index": 62,
|
||||
"name": "bathroom_0",
|
||||
"order": 0,
|
||||
"room_area": 16.0,
|
||||
@@ -576,7 +566,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 64,
|
||||
"index": 63,
|
||||
"name": "wc_0",
|
||||
"order": 1,
|
||||
"room_area": 16.0,
|
||||
@@ -586,7 +576,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 65,
|
||||
"index": 64,
|
||||
"name": "bedroom_0",
|
||||
"order": 2,
|
||||
"room_area": 36.0,
|
||||
@@ -596,7 +586,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 66,
|
||||
"index": 65,
|
||||
"name": "living_room_0",
|
||||
"order": 0,
|
||||
"room_area": 36.0,
|
||||
@@ -606,7 +596,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 67,
|
||||
"index": 66,
|
||||
"name": "kitchen_0",
|
||||
"order": 1,
|
||||
"room_area": 16.0,
|
||||
@@ -614,17 +604,17 @@ entries=[ {
|
||||
"type": "room",
|
||||
"window": true
|
||||
}, {
|
||||
"children": [ 81, 82 ],
|
||||
"children": [ 80, 81 ],
|
||||
"commands": [ ],
|
||||
"floor_index": 1,
|
||||
"index": 68,
|
||||
"index": 67,
|
||||
"name": "floor_0",
|
||||
"order": 0,
|
||||
"type": "floor"
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 69,
|
||||
"index": 68,
|
||||
"name": "wc_0",
|
||||
"order": 0,
|
||||
"room_area": 16.0,
|
||||
@@ -634,7 +624,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 70,
|
||||
"index": 69,
|
||||
"name": "bathroom_0",
|
||||
"order": 1,
|
||||
"room_area": 16.0,
|
||||
@@ -644,7 +634,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 71,
|
||||
"index": 70,
|
||||
"name": "bedroom_0",
|
||||
"order": 2,
|
||||
"room_area": 64.0,
|
||||
@@ -654,7 +644,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 72,
|
||||
"index": 71,
|
||||
"name": "kitchen_0",
|
||||
"order": 0,
|
||||
"room_area": 16.0,
|
||||
@@ -664,7 +654,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 73,
|
||||
"index": 72,
|
||||
"name": "living_room_0",
|
||||
"order": 1,
|
||||
"room_area": 144.0,
|
||||
@@ -674,7 +664,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 74,
|
||||
"index": 73,
|
||||
"name": "bathroom_0",
|
||||
"order": 0,
|
||||
"room_area": 16.0,
|
||||
@@ -684,7 +674,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 75,
|
||||
"index": 74,
|
||||
"name": "kitchen_0",
|
||||
"order": 0,
|
||||
"room_area": 64.0,
|
||||
@@ -694,7 +684,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 76,
|
||||
"index": 75,
|
||||
"name": "living_room_0",
|
||||
"order": 1,
|
||||
"room_area": 64.0,
|
||||
@@ -704,7 +694,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 77,
|
||||
"index": 76,
|
||||
"name": "wc_0",
|
||||
"order": 0,
|
||||
"room_area": 16.0,
|
||||
@@ -714,7 +704,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 78,
|
||||
"index": 77,
|
||||
"name": "living_room_0",
|
||||
"order": 0,
|
||||
"room_area": 64.0,
|
||||
@@ -724,7 +714,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 79,
|
||||
"index": 78,
|
||||
"name": "bathroom_0",
|
||||
"order": 0,
|
||||
"room_area": 16.0,
|
||||
@@ -734,7 +724,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ [ 5, [ ] ] ],
|
||||
"index": 80,
|
||||
"index": 79,
|
||||
"name": "living_room_0",
|
||||
"order": 0,
|
||||
"room_area": 64.0,
|
||||
@@ -742,24 +732,24 @@ entries=[ {
|
||||
"type": "room",
|
||||
"window": true
|
||||
}, {
|
||||
"children": [ 83 ],
|
||||
"children": [ 82 ],
|
||||
"commands": [ ],
|
||||
"index": 81,
|
||||
"index": 80,
|
||||
"name": "zone_0",
|
||||
"order": 0,
|
||||
"type": "zone",
|
||||
"zone_type": 1
|
||||
}, {
|
||||
"children": [ 84, 85 ],
|
||||
"children": [ 83, 84 ],
|
||||
"commands": [ ],
|
||||
"index": 82,
|
||||
"index": 81,
|
||||
"name": "unit_0",
|
||||
"order": 0,
|
||||
"type": "unit"
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ ],
|
||||
"index": 83,
|
||||
"index": 82,
|
||||
"name": "storage_room_0",
|
||||
"order": 0,
|
||||
"room_area": 64.0,
|
||||
@@ -767,17 +757,17 @@ entries=[ {
|
||||
"type": "room",
|
||||
"window": true
|
||||
}, {
|
||||
"children": [ 86 ],
|
||||
"children": [ 85 ],
|
||||
"commands": [ ],
|
||||
"index": 84,
|
||||
"index": 83,
|
||||
"name": "zone_0",
|
||||
"order": 0,
|
||||
"type": "zone",
|
||||
"zone_type": 0
|
||||
}, {
|
||||
"children": [ 87 ],
|
||||
"children": [ 86 ],
|
||||
"commands": [ ],
|
||||
"index": 85,
|
||||
"index": 84,
|
||||
"name": "zone_1",
|
||||
"order": 0,
|
||||
"type": "zone",
|
||||
@@ -785,7 +775,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ ],
|
||||
"index": 86,
|
||||
"index": 85,
|
||||
"name": "wc_0",
|
||||
"order": 0,
|
||||
"room_area": 16.0,
|
||||
@@ -795,7 +785,7 @@ entries=[ {
|
||||
}, {
|
||||
"children": [ ],
|
||||
"commands": [ ],
|
||||
"index": 87,
|
||||
"index": 86,
|
||||
"name": "living_room_0",
|
||||
"order": 0,
|
||||
"room_area": 16.0,
|
||||
|
||||
Submodule src/flecs updated: 57ebed1083...0c70671515
Submodule src/godot updated: 7fbb30e55b...cd92ad0f69
Submodule src/meshoptimizer updated: 20787cc054...20b26f9874
@@ -1007,6 +1007,12 @@ void BuildingLayoutGraphUI::draw_2d_grid_view(Control *draw)
|
||||
true);
|
||||
mcount++;
|
||||
});
|
||||
if (fc.has<WorldEditor::components::path>())
|
||||
draw->draw_circle(
|
||||
Vector2(dx + 0.5f * dsize,
|
||||
dy + 0.5f * dsize),
|
||||
dsize * 0.12f,
|
||||
Color(0.3f, 0.3f, 1.0f, 1.0f));
|
||||
print_line(
|
||||
"draw cell: (" + itos(x) + ", " +
|
||||
itos(y) + ") (" + String::num(dx) +
|
||||
|
||||
@@ -404,8 +404,8 @@ void graph_module::zones_graph_module(flecs::world &ecs,
|
||||
else
|
||||
xr = xr.grow(1);
|
||||
int xarea = xr.size.x * xr.size.y * 16;
|
||||
sum += MAX(xarea, MIN_ROOM_SIZE) * 10 /
|
||||
8;
|
||||
sum += MAX(xarea, MIN_ROOM_SIZE) * 35 /
|
||||
80;
|
||||
assert(sum >= 0.0f);
|
||||
count_rooms++;
|
||||
}
|
||||
|
||||
@@ -475,9 +475,19 @@ void grow_job_queue::iterate()
|
||||
assert(this);
|
||||
flecs::query<growth_regions> q =
|
||||
grid_e.world().query_builder<growth_regions>().build();
|
||||
#if 0
|
||||
flecs::query<region_tree> qm =
|
||||
grid_e.world().query_builder<region_tree>().build();
|
||||
#endif
|
||||
q.each([this](flecs::entity e, growth_regions &g) {
|
||||
flecs::log::warn("pre floor: %s", e.path().c_str());
|
||||
});
|
||||
#if 0
|
||||
qm.each([this](flecs::entity em, region_tree &rt) {
|
||||
rt.dump(em);
|
||||
assert(rt.check(em));
|
||||
});
|
||||
#endif
|
||||
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());
|
||||
@@ -522,21 +532,29 @@ void grow_job_queue::iterate()
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
{
|
||||
const region_tree *rtree = e.get<region_tree>();
|
||||
assert(rtree);
|
||||
assert(rtree->check(grid_floor_e));
|
||||
}
|
||||
g.job_list.pop_front();
|
||||
// if (common_count > 0)
|
||||
// break;
|
||||
}
|
||||
flecs::log::dbg(
|
||||
"processed jobs (created region initial positions): %d",
|
||||
g.job_list.size());
|
||||
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.shrink_rooms(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());
|
||||
});
|
||||
}
|
||||
@@ -560,6 +560,7 @@ void growth_module::mark_doors(flecs::world &&ecs_)
|
||||
[&room_e](flecs::entity re) {
|
||||
room_e = re;
|
||||
});
|
||||
cell_e.add<WorldEditor::components::path>();
|
||||
flecs::entity next_cell_e =
|
||||
data[ke->get()].id2entity[path[k + 1]];
|
||||
next_cell_e.each<
|
||||
@@ -567,6 +568,7 @@ void growth_module::mark_doors(flecs::world &&ecs_)
|
||||
[&next_room_e](flecs::entity re) {
|
||||
next_room_e = re;
|
||||
});
|
||||
next_cell_e.add<WorldEditor::components::path>();
|
||||
if (room_e.is_valid() &&
|
||||
next_room_e.is_valid()) {
|
||||
if (exits.has(room_e.id()) &&
|
||||
|
||||
@@ -63,6 +63,7 @@ void region_tree::split(flecs::entity grid_floor_e,
|
||||
count++;
|
||||
e = e->next();
|
||||
}
|
||||
assert(base_rtree->check(grid_floor_e));
|
||||
}
|
||||
|
||||
const region_tree *region_tree::find(flecs::entity_t which) const
|
||||
@@ -136,6 +137,7 @@ void region_tree::grow(flecs::entity grid_floor_e, bool limited)
|
||||
const struct region_tree *base_rtree = grid_floor_e.get<region_tree>();
|
||||
assert(base_rtree);
|
||||
make_random r(11365);
|
||||
assert(base_rtree->check(grid_floor_e));
|
||||
#ifdef TESTS
|
||||
flecs::log::warn("grow");
|
||||
#endif
|
||||
@@ -176,6 +178,7 @@ void region_tree::grow(flecs::entity grid_floor_e, bool limited)
|
||||
return hash_one_uint64((uint64_t)ptr);
|
||||
}
|
||||
};
|
||||
Vector2i pos = get_global_center();
|
||||
while (1) {
|
||||
e = special_grow_list.front();
|
||||
int count = 0;
|
||||
@@ -187,29 +190,64 @@ void region_tree::grow(flecs::entity grid_floor_e, bool limited)
|
||||
e = e->next();
|
||||
continue;
|
||||
}
|
||||
Vector2i dir = pos - item->region.rect.position;
|
||||
struct region backup = item->region;
|
||||
RegionRect2i parent_rect = item->parent->region.rect;
|
||||
switch (variant) {
|
||||
case 0:
|
||||
if (dir.x > 0)
|
||||
item->region.rect.position.x =
|
||||
parent_rect.position.x +
|
||||
parent_rect.size.x - 1;
|
||||
else if (dir.x < 0)
|
||||
item->region.rect.position.x =
|
||||
parent_rect.position.x;
|
||||
if (dir.y > 0)
|
||||
item->region.rect.position.y =
|
||||
parent_rect.position.y +
|
||||
parent_rect.size.y - 1;
|
||||
else if (dir.y < 0)
|
||||
item->region.rect.position.y =
|
||||
parent_rect.position.y;
|
||||
break;
|
||||
case 1:
|
||||
if (dir.x > 0)
|
||||
item->region.rect.position.x =
|
||||
parent_rect.position.x +
|
||||
parent_rect.size.x - 1;
|
||||
else if (dir.x < 0)
|
||||
item->region.rect.position.x =
|
||||
parent_rect.position.x;
|
||||
break;
|
||||
case 2:
|
||||
if (dir.y > 0)
|
||||
item->region.rect.position.y =
|
||||
parent_rect.position.y +
|
||||
parent_rect.size.y - 1;
|
||||
else if (dir.y < 0)
|
||||
item->region.rect.position.y =
|
||||
parent_rect.position.y;
|
||||
break;
|
||||
case 3:
|
||||
item->region.rect.position.x =
|
||||
parent_rect.position.x +
|
||||
parent_rect.size.x - 1;
|
||||
break;
|
||||
case 1:
|
||||
case 4:
|
||||
item->region.rect.position.x =
|
||||
parent_rect.position.x;
|
||||
break;
|
||||
case 2:
|
||||
case 5:
|
||||
item->region.rect.position.y =
|
||||
parent_rect.position.y +
|
||||
parent_rect.size.y - 1;
|
||||
break;
|
||||
case 3:
|
||||
case 6:
|
||||
item->region.rect.position.y =
|
||||
parent_rect.position.y;
|
||||
break;
|
||||
}
|
||||
if (variant > 3) {
|
||||
if (variant > 6) {
|
||||
do {
|
||||
item->region.rect.position.x =
|
||||
parent_rect.position.x +
|
||||
@@ -363,6 +401,7 @@ void region_tree::grow(flecs::entity grid_floor_e, bool limited)
|
||||
queue.clear();
|
||||
assert(base_rtree->check(grid_floor_e));
|
||||
}
|
||||
assert(base_rtree->check(grid_floor_e));
|
||||
}
|
||||
|
||||
bool region_tree::check(flecs::entity grid_floor_e) const
|
||||
@@ -407,6 +446,7 @@ bool region_tree::check(flecs::entity grid_floor_e) const
|
||||
float aspect = (float)check_regions[i].size.x /
|
||||
(float)check_regions[i].size.y;
|
||||
if (aspect < 0.25f || aspect > 4.0f) {
|
||||
flecs::log::err("bad aspect ratio");
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
@@ -456,6 +496,219 @@ bool region_tree::check(flecs::entity grid_floor_e) const
|
||||
return ok;
|
||||
}
|
||||
|
||||
// TODO: calculate if rooms touch each other and shrink smaller one
|
||||
void region_tree::shrink_rooms(flecs::entity grid_floor_e)
|
||||
{
|
||||
int i, accepted = 0;
|
||||
assert(!parent);
|
||||
dump(grid_floor_e);
|
||||
List<struct region_tree *> queue, shrinkable;
|
||||
List<struct region_tree *> left_rooms, right_rooms, forward_rooms,
|
||||
backward_rooms, inside_rooms;
|
||||
List<struct region_tree *>::Element *rp, *rp1, *rp2;
|
||||
struct touching_result {
|
||||
struct region_tree *first;
|
||||
struct region_tree *second;
|
||||
int how;
|
||||
};
|
||||
const struct region_tree *base_rtree = grid_floor_e.get<region_tree>();
|
||||
assert(base_rtree);
|
||||
assert(base_rtree->check(grid_floor_e));
|
||||
List<struct touching_result> touching;
|
||||
int grid_size = grid_floor_e
|
||||
.get<WorldEditor::components::
|
||||
buildings_layout_grid_floor>()
|
||||
->grid_size;
|
||||
queue.push_back(this);
|
||||
while (!queue.empty()) {
|
||||
const struct region_tree *item = queue.front()->get();
|
||||
queue.pop_front();
|
||||
if (item->region.can_grow)
|
||||
return;
|
||||
if (item->is_leaf() && item->region.can_move)
|
||||
return;
|
||||
for (i = 0; i < (int)item->children.size(); i++)
|
||||
queue.push_back(item->children[i]);
|
||||
}
|
||||
queue.clear();
|
||||
queue.push_back(this);
|
||||
while (!queue.empty()) {
|
||||
struct region_tree *item = queue.front()->get();
|
||||
queue.pop_front();
|
||||
int acceptable = 0;
|
||||
if (item->is_shrinkable())
|
||||
acceptable = 0xf;
|
||||
flecs::log::dbg("acceptable: %d", acceptable);
|
||||
if ((acceptable & 0xf) == 0xf) {
|
||||
shrinkable.push_back(item);
|
||||
accepted++;
|
||||
int rx, px, ry, py;
|
||||
rx = item->region.rect.position.x;
|
||||
px = item->parent->region.rect.position.x;
|
||||
if (rx == px) {
|
||||
left_rooms.push_back(item);
|
||||
acceptable |= (1 << 4);
|
||||
}
|
||||
rx = item->region.rect.position.x +
|
||||
item->region.rect.size.x - 1;
|
||||
px = item->parent->region.rect.position.x +
|
||||
item->parent->region.rect.size.x - 1;
|
||||
if (rx == px) {
|
||||
right_rooms.push_back(item);
|
||||
acceptable |= (1 << 5);
|
||||
}
|
||||
ry = item->region.rect.position.y;
|
||||
py = item->parent->region.rect.position.y;
|
||||
if (ry == py) {
|
||||
forward_rooms.push_back(item);
|
||||
acceptable |= (1 << 6);
|
||||
}
|
||||
ry = item->region.rect.position.y +
|
||||
item->region.rect.size.y - 1;
|
||||
py = item->parent->region.rect.position.y +
|
||||
item->parent->region.rect.size.y - 1;
|
||||
if (ry == py) {
|
||||
backward_rooms.push_back(item);
|
||||
acceptable |= (1 << 7);
|
||||
}
|
||||
if ((acceptable & 0xf0) == 0)
|
||||
inside_rooms.push_back(item);
|
||||
flecs::log::dbg("acceptable: %d", acceptable);
|
||||
}
|
||||
for (i = 0; i < (int)item->children.size(); i++)
|
||||
queue.push_back(item->children[i]);
|
||||
}
|
||||
#if 0
|
||||
rp1 = rooms.front();
|
||||
while (rp1) {
|
||||
rp2 = rooms.front();
|
||||
while (rp2) {
|
||||
if (rp1 == rp2) {
|
||||
rp2 = rp2->next();
|
||||
continue;
|
||||
}
|
||||
int style = rp1->get()->what_touching(rp2->get());
|
||||
struct region_tree *item1 = rp1->get(),
|
||||
*item2 = rp2->get();
|
||||
if (style & TOUCH_RIGHT) {
|
||||
if (shrinkable.find(item2)) {
|
||||
if (!right_rooms.find(item2))
|
||||
right_rooms.push_back(item2);
|
||||
} else if (shrinkable.find(item1)) {
|
||||
if (!left_rooms.find(item1))
|
||||
left_rooms.push_back(item1);
|
||||
}
|
||||
}
|
||||
if (style & TOUCH_LEFT) {
|
||||
if (shrinkable.find(item2)) {
|
||||
if (!left_rooms.find(item2))
|
||||
left_rooms.push_back(item2);
|
||||
} else if (shrinkable.find(item1)) {
|
||||
if (!right_rooms.find(item1))
|
||||
right_rooms.push_back(item1);
|
||||
}
|
||||
}
|
||||
if (style & TOUCH_FORWARD) {
|
||||
if (shrinkable.find(item2)) {
|
||||
if (!forward_rooms.find(item2))
|
||||
forward_rooms.push_back(item2);
|
||||
} else if (shrinkable.find(item1)) {
|
||||
if (!backward_rooms.find(item1))
|
||||
backward_rooms.push_back(item1);
|
||||
}
|
||||
}
|
||||
if (style & TOUCH_BACKWARD) {
|
||||
if (shrinkable.find(item2)) {
|
||||
if (!backward_rooms.find(item2))
|
||||
backward_rooms.push_back(item2);
|
||||
} else if (shrinkable.find(item1)) {
|
||||
if (!forward_rooms.find(item1))
|
||||
forward_rooms.push_back(item1);
|
||||
}
|
||||
}
|
||||
rp2 = rp2->next();
|
||||
}
|
||||
rp1 = rp1->next();
|
||||
}
|
||||
#endif
|
||||
int shrunk = 0;
|
||||
int shrink_mode = SHRINK_LEFT_ROOM;
|
||||
while (1) {
|
||||
switch (shrink_mode) {
|
||||
case SHRINK_LEFT_ROOM:
|
||||
rp = left_rooms.front();
|
||||
break;
|
||||
case SHRINK_RIGHT_ROOM:
|
||||
rp = right_rooms.front();
|
||||
break;
|
||||
case SHRINK_FORWARD_ROOM:
|
||||
rp = forward_rooms.front();
|
||||
break;
|
||||
case SHRINK_BACKWARD_ROOM:
|
||||
rp = backward_rooms.front();
|
||||
break;
|
||||
case SHRINK_INSIDE_ROOM:
|
||||
rp = inside_rooms.front();
|
||||
break;
|
||||
}
|
||||
while (rp) {
|
||||
struct region backup = rp->get()->region;
|
||||
List<struct region_tree *> neighbors;
|
||||
switch (shrink_mode) {
|
||||
case SHRINK_LEFT_ROOM:
|
||||
get_neighbors(grid_floor_e, RIGHT, &neighbors);
|
||||
if (neighbors.size() > 0) {
|
||||
rp->get()->region.rect.size.x -= 1;
|
||||
shrunk++;
|
||||
}
|
||||
break;
|
||||
case SHRINK_RIGHT_ROOM:
|
||||
get_neighbors(grid_floor_e, LEFT, &neighbors);
|
||||
if (neighbors.size() > 0) {
|
||||
rp->get()->region.rect.position.x += 1;
|
||||
rp->get()->region.rect.size.x -= 1;
|
||||
shrunk++;
|
||||
}
|
||||
break;
|
||||
case SHRINK_FORWARD_ROOM:
|
||||
get_neighbors(grid_floor_e, BACKWARD,
|
||||
&neighbors);
|
||||
if (neighbors.size() > 0) {
|
||||
rp->get()->region.rect.size.y -= 1;
|
||||
shrunk++;
|
||||
}
|
||||
break;
|
||||
case SHRINK_BACKWARD_ROOM:
|
||||
get_neighbors(grid_floor_e, FORWARD,
|
||||
&neighbors);
|
||||
if (neighbors.size() > 0) {
|
||||
rp->get()->region.rect.position.y += 1;
|
||||
rp->get()->region.rect.size.y -= 1;
|
||||
shrunk++;
|
||||
}
|
||||
break;
|
||||
case SHRINK_INSIDE_ROOM:
|
||||
// TODO: check neighbors
|
||||
rp->get()->region.rect =
|
||||
rp->get()->region.rect.grow(-1);
|
||||
shrunk++;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
if (!base_rtree->check(grid_floor_e))
|
||||
rp->get()->region = backup;
|
||||
assert(base_rtree->check(grid_floor_e));
|
||||
rp = rp->next();
|
||||
}
|
||||
if (shrink_mode >= SHRINK_INSIDE_ROOM)
|
||||
break;
|
||||
shrink_mode++;
|
||||
}
|
||||
assert(base_rtree->check(grid_floor_e));
|
||||
// assert(accepted == 0 || shrunk > 0);
|
||||
grid_floor_e.modified<region_tree>();
|
||||
}
|
||||
void region_tree::place(flecs::entity grid_floor_e) const
|
||||
{
|
||||
int i, j, k;
|
||||
@@ -568,10 +821,13 @@ void region_tree::place(flecs::entity grid_floor_e) const
|
||||
|
||||
void region_tree::move(flecs::entity grid_floor_e)
|
||||
{
|
||||
if (!parent)
|
||||
return;
|
||||
struct region_tree *base_rtree = grid_floor_e.get_mut<region_tree>();
|
||||
assert(base_rtree);
|
||||
List<struct region_tree *> queue;
|
||||
List<struct region_tree *> movables;
|
||||
List<struct region_tree *> movables_sorted;
|
||||
int count = 0;
|
||||
Vector2i center;
|
||||
queue.push_back(base_rtree);
|
||||
@@ -595,37 +851,97 @@ void region_tree::move(flecs::entity grid_floor_e)
|
||||
flecs::log::dbg("center: %d %d", center.x, center.y);
|
||||
while (!movables.empty()) {
|
||||
struct region_tree *item = movables.front()->get();
|
||||
Vector2i dir = item->region.rect.get_center() - center;
|
||||
int d = dir.x * dir.x + dir.y * dir.y;
|
||||
movables.pop_front();
|
||||
List<struct region_tree *>::Element *e = movables.front();
|
||||
bool ok = true;
|
||||
while (e) {
|
||||
struct region_tree *check = e->get();
|
||||
Vector2i dir2 =
|
||||
check->region.rect.get_center() - center;
|
||||
int d2 = dir2.x * dir2.x + dir2.y * dir2.y;
|
||||
if (d2 > d) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
e = e->next();
|
||||
}
|
||||
if (ok)
|
||||
movables_sorted.push_back(item);
|
||||
else
|
||||
movables.push_back(item);
|
||||
}
|
||||
flecs::log::dbg("sorting done");
|
||||
int fail_count = 0;
|
||||
while (!movables_sorted.empty()) {
|
||||
struct region_tree *item = movables_sorted.front()->get();
|
||||
if (!item->region.can_move)
|
||||
continue;
|
||||
Vector2i dir = item->region.rect.get_center() - center, dir1,
|
||||
dir2;
|
||||
if (dir.x * dir.x > dir.y * dir.y) {
|
||||
dir1.x = CLAMP(dir.x, -1, 1);
|
||||
dir1.y = 0;
|
||||
} else if (dir.x * dir.x < dir.y * dir.y) {
|
||||
dir1.x = 0;
|
||||
dir1.y = CLAMP(dir.y, -1, 1);
|
||||
}
|
||||
dir2.x = CLAMP(dir.x, -1, 1);
|
||||
dir2.y = CLAMP(dir.y, -1, 1);
|
||||
flecs::log::dbg("direction: %d %d", dir.x, dir.y);
|
||||
RegionRect2i backup = item->region.rect;
|
||||
item->region.rect.position += dir1;
|
||||
if (base_rtree->check(grid_floor_e)) {
|
||||
queue.push_back(item);
|
||||
continue;
|
||||
} else {
|
||||
item->region.rect = backup;
|
||||
item->region.rect.position += dir2;
|
||||
if (base_rtree->check(grid_floor_e)) {
|
||||
queue.push_back(item);
|
||||
continue;
|
||||
Vector2i gcenter = item->get_global_center();
|
||||
Vector2i dir = item->parent->region.rect.get_center() -
|
||||
(center * 2 + gcenter * 4);
|
||||
int flag1 = (item->region.rect.position.x +
|
||||
item->region.rect.position.y) &
|
||||
(1 << 1);
|
||||
int flag2 = (item->region.rect.position.x +
|
||||
item->region.rect.position.y) &
|
||||
(1 << 2);
|
||||
if (dir.x == 0 && dir.y == 0) {
|
||||
if (flag1) {
|
||||
dir.x = 0;
|
||||
if (flag2)
|
||||
dir.y = 1;
|
||||
else
|
||||
dir.y = -1;
|
||||
} else {
|
||||
item->region.rect = backup;
|
||||
item->region.can_move = false;
|
||||
if (flag2)
|
||||
dir.x = 1;
|
||||
else
|
||||
dir.x = -1;
|
||||
dir.y = 0;
|
||||
}
|
||||
}
|
||||
Vector2i mdir1, mdir2;
|
||||
mdir1.x = CLAMP(dir.x, -1, 1);
|
||||
mdir1.y = 0;
|
||||
mdir2.x = 0;
|
||||
mdir2.y = CLAMP(dir.y, -1, 1);
|
||||
flecs::log::dbg("direction: %d %d", dir.x, dir.y);
|
||||
flecs::log::dbg("direction1: %d %d", mdir1.x, mdir1.y);
|
||||
flecs::log::dbg("direction2: %d %d", mdir2.x, mdir2.y);
|
||||
flecs::log::dbg("position: %d %d", item->region.rect.position.x,
|
||||
item->region.rect.position.y);
|
||||
RegionRect2i backup = item->region.rect;
|
||||
item->region.rect.position += mdir1;
|
||||
flecs::log::dbg("updated position: %d %d",
|
||||
item->region.rect.position.x,
|
||||
item->region.rect.position.y);
|
||||
bool ok1 = false, ok2 = false;
|
||||
if (base_rtree->check(grid_floor_e)) {
|
||||
fail_count = 0;
|
||||
flecs::log::dbg("can still move");
|
||||
ok1 = true;
|
||||
} else {
|
||||
ok1 = false;
|
||||
item->region.rect = backup;
|
||||
item->region.rect.position += mdir2;
|
||||
if (base_rtree->check(grid_floor_e))
|
||||
ok2 = true;
|
||||
else
|
||||
ok2 = false;
|
||||
}
|
||||
if (!ok1 && !ok2) {
|
||||
fail_count++;
|
||||
item->region.rect = backup;
|
||||
if (fail_count > 10) {
|
||||
item->region.can_move = false;
|
||||
movables_sorted.pop_front();
|
||||
flecs::log::dbg("can't move, going to next");
|
||||
fail_count = 0;
|
||||
}
|
||||
} else
|
||||
continue;
|
||||
}
|
||||
grid_floor_e.modified<region_tree>();
|
||||
}
|
||||
@@ -702,7 +1018,156 @@ bool region_tree::is_special() const
|
||||
{
|
||||
return flag_special;
|
||||
}
|
||||
bool region_tree::is_touching(const struct region_tree *other) const
|
||||
{
|
||||
int flags = what_touching(other);
|
||||
return (flags > 0);
|
||||
}
|
||||
|
||||
void region_tree::get_room_nodes(
|
||||
List<const struct region_tree *> *node_list) const
|
||||
{
|
||||
List<const struct region_tree *> queue;
|
||||
queue.push_back(this);
|
||||
while (!queue.empty()) {
|
||||
int i;
|
||||
const struct region_tree *item = queue.front()->get();
|
||||
queue.pop_front();
|
||||
if (item->is_leaf() && item->is_a_room()) {
|
||||
node_list->push_back(item);
|
||||
}
|
||||
for (i = 0; i < (int)item->children.size(); i++)
|
||||
queue.push_back(item->children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void region_tree::get_room_nodes(List<struct region_tree *> *node_list)
|
||||
{
|
||||
List<struct region_tree *> queue;
|
||||
queue.push_back(this);
|
||||
while (!queue.empty()) {
|
||||
int i;
|
||||
struct region_tree *item = queue.front()->get();
|
||||
queue.pop_front();
|
||||
if (item->is_leaf() && item->is_a_room()) {
|
||||
node_list->push_back(item);
|
||||
}
|
||||
for (i = 0; i < (int)item->children.size(); i++)
|
||||
queue.push_back(item->children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void region_tree::get_neighbors(flecs::entity grid_floor_e, int direction,
|
||||
List<struct region_tree *> *neighbors) const
|
||||
{
|
||||
List<struct region_tree *> rooms;
|
||||
List<struct region_tree *>::Element *el;
|
||||
struct region_tree *base_rtree = grid_floor_e.get_mut<region_tree>();
|
||||
assert(base_rtree);
|
||||
base_rtree->get_room_nodes(&rooms);
|
||||
RegionRect2i neighbor_rect = region.rect;
|
||||
neighbors->clear();
|
||||
switch (direction) {
|
||||
case LEFT:
|
||||
neighbor_rect.position.x -= 1;
|
||||
neighbor_rect.size.x = 1;
|
||||
break;
|
||||
case RIGHT:
|
||||
neighbor_rect.position.x += region.rect.size.x;
|
||||
neighbor_rect.size.x = 1;
|
||||
break;
|
||||
case FORWARD:
|
||||
neighbor_rect.position.y -= 1;
|
||||
neighbor_rect.size.y = 1;
|
||||
break;
|
||||
case BACKWARD:
|
||||
neighbor_rect.position.y += region.rect.size.y;
|
||||
neighbor_rect.size.y = 1;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
el = rooms.front();
|
||||
while (el) {
|
||||
if (el->get() == this) {
|
||||
el = el->next();
|
||||
continue;
|
||||
}
|
||||
bool neighbor = false;
|
||||
if (neighbor_rect == el->get()->region.rect)
|
||||
neighbor = true;
|
||||
if (neighbor_rect.encloses(el->get()->region.rect))
|
||||
neighbor = true;
|
||||
if (neighbor_rect.intersects(el->get()->region.rect))
|
||||
neighbor = true;
|
||||
if (el->get()->region.rect.encloses(neighbor_rect))
|
||||
neighbor = true;
|
||||
if (el->get()->region.rect.intersects(neighbor_rect))
|
||||
neighbor = true;
|
||||
if (neighbor)
|
||||
neighbors->push_back(el->get());
|
||||
el = el->next();
|
||||
}
|
||||
}
|
||||
|
||||
int region_tree::what_touching(const region_tree *other) const
|
||||
{
|
||||
int i;
|
||||
RegionRect2i right = region.rect, left = region.rect,
|
||||
forward = region.rect, backward = region.rect;
|
||||
right.position.x = region.rect.position.x + region.rect.size.x;
|
||||
left.position.x = region.rect.position.x - region.rect.size.x;
|
||||
forward.position.y = region.rect.position.y - region.rect.size.y;
|
||||
backward.position.y = region.rect.position.y + region.rect.size.y;
|
||||
int flags = 0;
|
||||
RegionRect2i rects[] = { right, left, forward, backward };
|
||||
for (i = 0; i < (int)sizeof(rects) / (int)sizeof(rects[0]); i++) {
|
||||
if (other->region.rect == rects[i])
|
||||
flags |= (1 << i);
|
||||
if (other->region.rect.encloses(rects[i]))
|
||||
flags |= (1 << i);
|
||||
if (other->region.rect.intersects(rects[i]))
|
||||
flags |= (1 << i);
|
||||
if (rects[i].encloses(other->region.rect))
|
||||
flags |= (1 << i);
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
bool region_tree::is_shrinkable() const
|
||||
{
|
||||
int acceptable = 0;
|
||||
if (region.rect.size.x > 2)
|
||||
acceptable |= (1 << 0);
|
||||
if (region.rect.size.y > 2)
|
||||
acceptable |= (1 << 1);
|
||||
if (is_leaf())
|
||||
acceptable |= (1 << 2);
|
||||
if (parent)
|
||||
acceptable |= (1 << 3);
|
||||
return (acceptable & 0xf) == 0xf;
|
||||
}
|
||||
|
||||
Vector2i region_tree::get_global_center() const
|
||||
{
|
||||
Vector2i center;
|
||||
int i;
|
||||
const struct region_tree *r = this;
|
||||
while (r->parent)
|
||||
r = r->parent;
|
||||
for (i = 0; i < r->children.size(); i++)
|
||||
center += r->children[i]->region.rect.get_center();
|
||||
return center;
|
||||
}
|
||||
Vector2i region_tree::get_center() const
|
||||
{
|
||||
return region.rect.get_center();
|
||||
}
|
||||
int region_tree::area() const
|
||||
{
|
||||
return region.rect.get_area();
|
||||
}
|
||||
bool region_tree::check_candidate(int i, const RegionRect2i &candidate) const
|
||||
{
|
||||
int j;
|
||||
|
||||
@@ -22,6 +22,7 @@ struct region_tree {
|
||||
void grow(flecs::entity grid_floor_e, bool limited = true);
|
||||
bool check(flecs::entity grid_floor_e) const;
|
||||
void place(flecs::entity grid_floor_e) const;
|
||||
void shrink_rooms(flecs::entity grid_floor_e);
|
||||
void move(flecs::entity grid_floor_e);
|
||||
void get_rects(List<RegionRect2i> *rect_list) const;
|
||||
void get_leaf_nodes(List<const struct region_tree *> *node_list) const;
|
||||
@@ -29,6 +30,35 @@ struct region_tree {
|
||||
bool is_a_room(flecs::entity grid_floor_e) const;
|
||||
bool is_a_room() const;
|
||||
bool is_special() const;
|
||||
bool is_touching(const struct region_tree *other) const;
|
||||
enum {
|
||||
TOUCH_RIGHT = 1,
|
||||
TOUCH_LEFT = 2,
|
||||
TOUCH_FORWARD = 4,
|
||||
TOUCH_BACKWARD = 8,
|
||||
};
|
||||
enum {
|
||||
SHRINK_LEFT_ROOM = 1, // shrink right side
|
||||
SHRINK_RIGHT_ROOM, // shrink left side
|
||||
SHRINK_FORWARD_ROOM, // shrink "upper" side
|
||||
SHRINK_BACKWARD_ROOM, // shrink "lower" side
|
||||
SHRINK_INSIDE_ROOM, // shrink "inside" room (all sides?)
|
||||
};
|
||||
enum {
|
||||
LEFT = 1,
|
||||
RIGHT,
|
||||
FORWARD,
|
||||
BACKWARD,
|
||||
};
|
||||
void get_room_nodes(List<const struct region_tree *> *node_list) const;
|
||||
void get_room_nodes(List<struct region_tree *> *node_list);
|
||||
void get_neighbors(flecs::entity grid_floor_e, int direction,
|
||||
List<struct region_tree *> *neighbors) const;
|
||||
int what_touching(const struct region_tree *other) const;
|
||||
bool is_shrinkable() const;
|
||||
Vector2i get_global_center() const;
|
||||
Vector2i get_center() const;
|
||||
int area() const;
|
||||
|
||||
private:
|
||||
bool check_candidate(int i, const RegionRect2i &candidate) const;
|
||||
|
||||
@@ -119,6 +119,7 @@ public:
|
||||
List<Pair<int, flecs::entity_t> > floors;
|
||||
int growth_size;
|
||||
};
|
||||
struct path {};
|
||||
struct belongs {};
|
||||
struct border {};
|
||||
struct belongs_room {};
|
||||
|
||||
Reference in New Issue
Block a user