Skip to content

Commit 71a49ba

Browse files
committed
w
1 parent 802995c commit 71a49ba

File tree

5 files changed

+72
-54
lines changed

5 files changed

+72
-54
lines changed

editor/tests/hole-test.cpp

+2-4
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ constexpr auto colors = std::array{
5858

5959
void hole_test::draw_ui(app& a, float)
6060
{
61-
using crr = cut_rectangle_result<Int>;
61+
using crr = CutResult<Int>;
6262
using bbox = typename crr::bbox;
6363
const auto& m = a.main();
6464
const auto width = Math::min(ImGui::GetWindowSize().x, 400.f);
@@ -110,8 +110,6 @@ void hole_test::draw_ui(app& a, float)
110110
to_imvec2(center + (Vector2(st.pos) + Vector2(st.size)*.5f)* mult), red, 0, 0, 1); // hole
111111
}
112112

113-
constexpr auto rmin = Int{-tile_size_xy/2}, rmax = Int{(tile_size_xy+1)/2};
114-
const bool found = res.size != 1 || res.array[0].min != Vector2i{rmin} || res.array[0].max != Vector2i{rmax};
115113
const auto label_width = ImGui::CalcTextSize("MMMMMM").x;
116114

117115
ImGui::NewLine();
@@ -135,7 +133,7 @@ void hole_test::draw_ui(app& a, float)
135133
}
136134
{
137135
label_left("found", buf, label_width);
138-
ImGui::Text("%s", found ? "true" : "false");
136+
ImGui::Text("%s", res.found ? "true" : "false");
139137
}
140138

141139
ImGui::Unindent(style.FramePadding.x);

src/chunk-collision.cpp

+49-26
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
#include "chunk.hpp"
22
#include "ground-atlas.hpp"
33
#include "object.hpp"
4+
#include "world.hpp"
45
#include "src/RTree-search.hpp"
56
#include "rect-intersects.hpp"
7+
#include "hole.hpp"
68
#include "src/chunk-scenery.hpp"
79
#include "src/tile-bbox.hpp"
810
#include "src/hole.hpp"
@@ -32,13 +34,6 @@ constexpr object_id make_id(collision_type type, pass_mode p, object_id id)
3234
return std::bit_cast<object_id>(make_id_(type, p, id));
3335
}
3436

35-
struct Data
36-
{
37-
object_id id;
38-
Vector2 min, max;
39-
};
40-
41-
#if 0
4237
template<bool IsNeighbor>
4338
void add_holes_from(chunk::RTree& rtree, chunk& c, Vector2b chunk_offset)
4439
{
@@ -65,35 +60,55 @@ void add_holes_from(chunk::RTree& rtree, chunk& c, Vector2b chunk_offset)
6560
}
6661
}
6762

68-
void filter_through_holes(chunk::RTree& rtree, Data bbox, unsigned stack)
63+
#if 0
64+
void filter_through_holes(chunk::RTree& rtree, object_id id, Vector2 min, Vector2 max, unsigned stack = 0)
6965
{
70-
using Rect = typename chunk::RTree::Rect;
71-
Vector2 hmin, hmax;
66+
start:
67+
CutResult<float>::rect hole;
7268
bool ret = true;
73-
rtree.Search(bbox.min.data(), bbox.max.data(), [&](uint64_t data, const Rect& r) {
69+
rtree.Search(min.data(), max.data(), [&](uint64_t data, const chunk::RTree::Rect& r) {
7470
[[maybe_unused]] auto x = std::bit_cast<collision_data>(data);
7571
if (x.pass == (uint64_t)pass_mode::pass && x.tag == (uint64_t)collision_type::none)
7672
{
77-
hmin = Vector2(r.m_min[0], r.m_min[1]);
78-
hmax = Vector2(r.m_max[0], r.m_max[1]);
79-
return ret = false;
73+
CutResult<float>::rect holeʹ {
74+
.min = { r.m_min[0], r.m_min[1] },
75+
.max = { r.m_max[0], r.m_max[1] },
76+
};
77+
if (rect_intersects(holeʹ.min, holeʹ.max, min, max))
78+
{
79+
hole = holeʹ;
80+
return ret = false;
81+
}
8082
}
8183
return true;
8284
});
8385

8486
if (ret) [[likely]]
85-
rtree.Insert(bbox.min.data(), bbox.max.data(), bbox.id);
87+
rtree.Insert(min.data(), max.data(), id);
8688
else
8789
{
88-
//auto res = cut_rectangle_result<float>::cut();
89-
//for (auto i = 0uz; i < )
90-
fm_assert(++stack <= 4096);
91-
}
90+
auto res = CutResult<float>::cut(min, max, hole.min, hole.max);
91+
if (!res.found)
92+
{
93+
rtree.Insert(min.data(), max.data(), id);
94+
}
95+
else if (res.size == 1)
96+
{
97+
min = res.array[0].min;
98+
max = res.array[0].max;
99+
goto start;
100+
}
101+
else
102+
{
103+
fm_assert(stack <= 1024);
104+
for (auto i = 0uz; i < res.size; i++)
105+
filter_through_holes(rtree, id, res.array[i].min, res.array[i].max, stack+1);
106+
}}
92107
}
93108
#else
94-
void filter_through_holes(chunk::RTree& rtree, Data bbox, unsigned)
109+
void filter_through_holes(chunk::RTree& rtree, object_id id, Vector2 min, Vector2 max, unsigned = 0)
95110
{
96-
rtree.Insert(bbox.min.data(), bbox.max.data(), bbox.id);
111+
rtree.Insert(min.data(), max.data(), id);
97112
}
98113
#endif
99114

@@ -109,13 +124,21 @@ void chunk::ensure_passability() noexcept
109124

110125
_rtree->RemoveAll();
111126

127+
{
128+
add_holes_from<false>(*_rtree, *this, {});
129+
const auto nbs = _world->neighbors(_coord);
130+
for (auto i = 0u; i < 8; i++)
131+
if (nbs[i])
132+
add_holes_from<true>(*_rtree, *nbs[i], world::neighbor_offsets[i]);
133+
}
134+
112135
for (auto i = 0uz; i < TILE_COUNT; i++)
113136
{
114137
if (const auto* atlas = ground_atlas_at(i))
115138
{
116139
auto [min, max] = whole_tile(i);
117140
auto id = make_id(collision_type::geometry, atlas->pass_mode(), i+1);
118-
filter_through_holes(*_rtree, {id, min, max}, 0);
141+
filter_through_holes(*_rtree, id, min, max);
119142
}
120143
}
121144
for (auto i = 0uz; i < TILE_COUNT; i++)
@@ -125,25 +148,25 @@ void chunk::ensure_passability() noexcept
125148
{
126149
auto [min, max] = wall_north(i, (float)atlas->info().depth);
127150
auto id = make_id(collision_type::geometry, atlas->info().passability, TILE_COUNT+i+1);
128-
filter_through_holes(*_rtree, {id, min, max}, 0);
151+
filter_through_holes(*_rtree, id, min, max);
129152

130153
if (tile.wall_west_atlas())
131154
{
132155
auto [min, max] = wall_pillar(i, (float)atlas->info().depth);
133-
filter_through_holes(*_rtree, {id, min, max}, 0);
156+
filter_through_holes(*_rtree, id, min, max);
134157
}
135158
}
136159
if (const auto* atlas = tile.wall_west_atlas().get())
137160
{
138161
auto [min, max] = wall_west(i, (float)atlas->info().depth);
139162
auto id = make_id(collision_type::geometry, atlas->info().passability, TILE_COUNT*2+i+1);
140-
filter_through_holes(*_rtree, {id, min, max}, 0);
163+
filter_through_holes(*_rtree, id, min, max);
141164
}
142165
}
143166
for (const std::shared_ptr<object>& s : objects())
144167
if (!s->is_dynamic())
145168
if (bbox box; _bbox_for_scenery(*s, box))
146-
filter_through_holes(*_rtree, {std::bit_cast<object_id>(box.data), Vector2(box.start), Vector2(box.end)}, 0);
169+
filter_through_holes(*_rtree, std::bit_cast<object_id>(box.data), Vector2(box.start), Vector2(box.end));
147170

148171
//for (auto [id, min, max] : vec) _rtree->Insert(min.data(), max.data(), id);
149172
//arrayResize(vec, 0); arrayResize(vec2, 0); // done with holes

src/hole-cut.cpp

+14-18
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
namespace floormat {
1616
namespace {
1717

18-
template<typename T> using crr = cut_rectangle_result<T>;
19-
template<typename T> using bbox = typename cut_rectangle_result<T>::bbox;
20-
template<typename T> using rect = typename cut_rectangle_result<T>::rect;
18+
template<typename T> using Cr = CutResult<T>;
19+
template<typename T> using bbox = typename Cr<T>::bbox;
20+
template<typename T> using rect = typename Cr<T>::rect;
2121

2222
enum shift : uint8_t { __ = 0, x0 = 1 << 0, x1 = 1 << 1, y0 = 1 << 2, y1 = 1 << 3, };
2323
enum class location : uint8_t { R0, R1, H0, H1, };
@@ -151,12 +151,13 @@ constexpr bool check_empty(Vec2ʹ<T> r0, Vec2ʹ<T> r1, Vec2ʹ<T> h0, Vec2ʹ<T> h
151151
}
152152

153153
template<typename T>
154-
constexpr cut_rectangle_result<T> cut_rectangle(Vec2ʹ<T> r0, Vec2ʹ<T> r1, Vec2ʹ<T> h0, Vec2ʹ<T> h1)
154+
constexpr Cr<T> cut_rectangle(Vec2ʹ<T> r0, Vec2ʹ<T> r1, Vec2ʹ<T> h0, Vec2ʹ<T> h1)
155155
{
156156
if (check_empty<T>(r0, r1, h0, h1))
157157
return {
158-
.size = 1,
159158
.array = {{ { r0, r1 }, }},
159+
.size = 1,
160+
.found = false,
160161
};
161162

162163
const bool sx = h0.x() <= r0.x();
@@ -168,9 +169,10 @@ constexpr cut_rectangle_result<T> cut_rectangle(Vec2ʹ<T> r0, Vec2ʹ<T> r1, Vec2
168169
CORRADE_ASSUME(val < 16);
169170
const auto elt = elements[val];
170171
const auto sz = elt.size;
171-
cut_rectangle_result<T> res = {
172-
.size = sz,
172+
Cr<T> res = {
173173
.array = {},
174+
.size = sz,
175+
.found = true,
174176
};
175177

176178
for (auto i = 0u; i < 8; i++)
@@ -180,7 +182,7 @@ constexpr cut_rectangle_result<T> cut_rectangle(Vec2ʹ<T> r0, Vec2ʹ<T> r1, Vec2
180182
}
181183

182184
template<typename T>
183-
constexpr cut_rectangle_result<T> cut_rectangle(bbox<T> input, bbox<T> hole)
185+
constexpr Cr<T> cut_rectangle(bbox<T> input, bbox<T> hole)
184186
{
185187
using Vec2 = Vec2ʹ<T>;
186188

@@ -197,16 +199,10 @@ constexpr cut_rectangle_result<T> cut_rectangle(bbox<T> input, bbox<T> hole)
197199

198200
} // namespace
199201

200-
template struct cut_rectangle_result<Int>;
201-
template struct cut_rectangle_result<float>;
202-
203-
template<typename T> crr<T> cut_rectangle_result<T>::cut(bbox input, bbox hole) { return cut_rectangle<T>(input, hole); }
204-
template<typename T> crr<T> cut_rectangle_result<T>::cut(Vec2 r0, Vec2 r1, Vec2 h0, Vec2 h1) { return cut_rectangle<T>(r0, r1, h0, h1); }
205-
206-
template cut_rectangle_result<Int> cut_rectangle_result<Int>::cut(bbox input, bbox hole);
207-
template cut_rectangle_result<float> cut_rectangle_result<float>::cut(bbox input, bbox hole);
202+
template<typename T> Cr<T> CutResult<T>::cut(bbox input, bbox hole) { return cut_rectangle<T>(input, hole); }
203+
template<typename T> Cr<T> CutResult<T>::cut(Vec2 r0, Vec2 r1, Vec2 h0, Vec2 h1) { return cut_rectangle<T>(r0, r1, h0, h1); }
208204

209-
template cut_rectangle_result<Int> cut_rectangle_result<Int>::cut(Vector2i r0, Vector2i r1, Vector2i h0, Vector2i h1);
210-
template cut_rectangle_result<float> cut_rectangle_result<float>::cut(Vector2 r0, Vector2 r1, Vector2 h0, Vector2 h1);
205+
template struct CutResult<Int>;
206+
template struct CutResult<float>;
211207

212208
} // namespace floormat

src/hole.hpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -56,17 +56,18 @@ struct hole final : object
5656
};
5757

5858
template<typename T>
59-
struct cut_rectangle_result // todo rename
59+
struct CutResult
6060
{
6161
using Vec2 = VectorTypeFor<2, T>;
6262
struct bbox { Vec2 position; Vector2ub bbox_size; };
6363
struct rect { Vec2 min, max; };
6464

65-
static cut_rectangle_result cut(bbox input, bbox hole);
66-
static cut_rectangle_result cut(Vec2 r0, Vec2 r1, Vec2 h0, Vec2 h1);
65+
static CutResult cut(bbox input, bbox hole);
66+
static CutResult cut(Vec2 r0, Vec2 r1, Vec2 h0, Vec2 h1);
6767

68-
uint8_t size = 0;
6968
std::array<rect, 8> array;
69+
uint8_t size = 0;
70+
bool found = false;
7071
};
7172

7273
} // namespace floormat

test/hole.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
namespace floormat {
55
namespace {
66

7-
using bbox = cut_rectangle_result<Int>::bbox;
7+
using bbox = CutResult<Int>::bbox;
88

99
auto cut(bbox rect, bbox hole, Vector2i offset)
1010
{
1111
auto rectʹ = bbox { rect.position + offset, rect.bbox_size };
1212
auto holeʹ = bbox { hole.position + offset, hole.bbox_size };
13-
return cut_rectangle_result<Int>::cut(rectʹ, holeʹ).size;
13+
return CutResult<Int>::cut(rectʹ, holeʹ).size;
1414
}
1515

1616
void test1(Vector2i offset)

0 commit comments

Comments
 (0)