Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/manifold/src/tree2d.h
9903 views
1
// Copyright 2025 The Manifold Authors.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#pragma once
16
17
#include "manifold/common.h"
18
#include "manifold/optional_assert.h"
19
#include "manifold/polygon.h"
20
#include "manifold/vec_view.h"
21
22
namespace manifold {
23
24
void BuildTwoDTreeImpl(VecView<PolyVert> points, bool sortX);
25
26
void BuildTwoDTree(VecView<PolyVert> points);
27
28
template <typename F>
29
void QueryTwoDTree(VecView<PolyVert> points, Rect r, F f) {
30
if (points.size() <= 8) {
31
for (const auto& p : points)
32
if (r.Contains(p.pos)) f(p);
33
return;
34
}
35
Rect current;
36
current.min = vec2(-std::numeric_limits<double>::infinity());
37
current.max = vec2(std::numeric_limits<double>::infinity());
38
39
int level = 0;
40
VecView<PolyVert> currentView = points;
41
std::array<Rect, 64> rectStack;
42
std::array<VecView<PolyVert>, 64> viewStack;
43
std::array<int, 64> levelStack;
44
int stackPointer = 0;
45
46
while (1) {
47
if (currentView.size() <= 8) {
48
for (const auto& p : currentView)
49
if (r.Contains(p.pos)) f(p);
50
if (--stackPointer < 0) break;
51
level = levelStack[stackPointer];
52
currentView = viewStack[stackPointer];
53
current = rectStack[stackPointer];
54
continue;
55
}
56
57
// these are conceptual left/right trees
58
Rect left = current;
59
Rect right = current;
60
const PolyVert middle = currentView[currentView.size() / 2];
61
if (level % 2 == 0)
62
left.max.x = right.min.x = middle.pos.x;
63
else
64
left.max.y = right.min.y = middle.pos.y;
65
66
if (r.Contains(middle.pos)) f(middle);
67
if (left.DoesOverlap(r)) {
68
if (right.DoesOverlap(r)) {
69
DEBUG_ASSERT(stackPointer < 64, logicErr, "Stack overflow");
70
rectStack[stackPointer] = right;
71
viewStack[stackPointer] = currentView.view(currentView.size() / 2 + 1);
72
levelStack[stackPointer] = level + 1;
73
stackPointer++;
74
}
75
current = left;
76
currentView = currentView.view(0, currentView.size() / 2);
77
level++;
78
} else {
79
current = right;
80
currentView = currentView.view(currentView.size() / 2 + 1);
81
level++;
82
}
83
}
84
}
85
} // namespace manifold
86
87