Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
CityDoctor
CityDoctor2
Commits
44154e1d
Commit
44154e1d
authored
Apr 29, 2026
by
Numanoglu
Browse files
Clean up BVH tree API
parent
cd89dc71
Pipeline
#12397
passed with stage
in 1 minute and 58 seconds
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/bht/BoundingVolumeHierarchyBuilder.java
View file @
44154e1d
...
@@ -146,6 +146,8 @@ final class BoundingVolumeHierarchyBuilder<E> {
...
@@ -146,6 +146,8 @@ final class BoundingVolumeHierarchyBuilder<E> {
private
boolean
shouldStop
(
List
<
BvhBuildItem
<
E
>>
items
,
int
depth
,
AABB
totalAabb
)
{
private
boolean
shouldStop
(
List
<
BvhBuildItem
<
E
>>
items
,
int
depth
,
AABB
totalAabb
)
{
return
items
.
size
()
<=
config
.
getMaxLeafSize
()
return
items
.
size
()
<=
config
.
getMaxLeafSize
()
||
depth
>=
config
.
getMaxDepth
()
||
depth
>=
config
.
getMaxDepth
()
// Very flat bounds are kept as one terminal group to avoid repeated
// ineffective spatial splits on effectively lower-dimensional data.
||
totalAabb
.
isDegenerate
(
config
.
getDegenerateTolerance
());
||
totalAabb
.
isDegenerate
(
config
.
getDegenerateTolerance
());
}
}
...
@@ -156,6 +158,8 @@ final class BoundingVolumeHierarchyBuilder<E> {
...
@@ -156,6 +158,8 @@ final class BoundingVolumeHierarchyBuilder<E> {
}
}
Node
<
E
>
leafGroup
=
new
Node
<>(
null
,
totalAabb
);
Node
<
E
>
leafGroup
=
new
Node
<>(
null
,
totalAabb
);
// A terminal group keeps its aggregate AABB for pruning, while the children
// remain the actual element leaves returned by queries.
for
(
BvhBuildItem
<
E
>
item
:
items
)
{
for
(
BvhBuildItem
<
E
>
item
:
items
)
{
leafGroup
.
getChildren
().
add
(
new
Node
<>(
item
.
element
,
item
.
aabb
));
leafGroup
.
getChildren
().
add
(
new
Node
<>(
item
.
element
,
item
.
aabb
));
}
}
...
...
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/bht/BoundingVolumeHierarchyTree.java
View file @
44154e1d
...
@@ -6,12 +6,9 @@ import java.util.Objects;
...
@@ -6,12 +6,9 @@ import java.util.Objects;
import
java.util.function.Function
;
import
java.util.function.Function
;
import
java.util.function.Predicate
;
import
java.util.function.Predicate
;
import
de.hft.stuttgart.citydoctor2.datastructure.ConcretePolygon
;
public
class
BoundingVolumeHierarchyTree
<
E
>
{
public
class
BoundingVolumeHierarchyTree
<
E
>
{
private
Node
<
E
>
root
;
private
final
Node
<
E
>
root
;
private
final
Function
<
E
,
AABB
>
aabbFunction
;
static
final
int
DEFAULT_MIN_DEPTH
=
4
;
static
final
int
DEFAULT_MIN_DEPTH
=
4
;
static
final
int
DEFAULT_MAX_DEPTH
=
32
;
static
final
int
DEFAULT_MAX_DEPTH
=
32
;
...
@@ -21,7 +18,6 @@ public class BoundingVolumeHierarchyTree<E> {
...
@@ -21,7 +18,6 @@ public class BoundingVolumeHierarchyTree<E> {
private
BoundingVolumeHierarchyTree
(
Builder
<
E
>
builder
)
{
private
BoundingVolumeHierarchyTree
(
Builder
<
E
>
builder
)
{
Objects
.
requireNonNull
(
builder
,
"builder"
);
Objects
.
requireNonNull
(
builder
,
"builder"
);
this
.
aabbFunction
=
Objects
.
requireNonNull
(
builder
.
getAabbFunction
(),
"aabbFunction"
);
this
.
root
=
new
BoundingVolumeHierarchyBuilder
<>(
builder
).
buildRoot
();
this
.
root
=
new
BoundingVolumeHierarchyBuilder
<>(
builder
).
buildRoot
();
}
}
...
@@ -110,14 +106,11 @@ public class BoundingVolumeHierarchyTree<E> {
...
@@ -110,14 +106,11 @@ public class BoundingVolumeHierarchyTree<E> {
return
root
;
return
root
;
}
}
public
void
setRoot
(
Node
<
E
>
root
)
{
this
.
root
=
root
;
}
/**
/**
* Returns all elements whose node AABBs overlap or touch the query AABB.
* Returns all elements whose node AABBs overlap or touch the query AABB.
*/
*/
public
List
<
E
>
getAllIntersectingElements
(
AABB
query
)
{
public
List
<
E
>
getAllIntersectingElements
(
AABB
query
)
{
Objects
.
requireNonNull
(
query
,
"query"
);
List
<
E
>
result
=
new
ArrayList
<>();
List
<
E
>
result
=
new
ArrayList
<>();
collectMatchingElements
(
collectMatchingElements
(
root
,
root
,
...
@@ -133,6 +126,7 @@ public class BoundingVolumeHierarchyTree<E> {
...
@@ -133,6 +126,7 @@ public class BoundingVolumeHierarchyTree<E> {
* missed when their parent node AABB extends beyond the container.
* missed when their parent node AABB extends beyond the container.
*/
*/
public
List
<
E
>
getAllElementsContainedIn
(
AABB
container
)
{
public
List
<
E
>
getAllElementsContainedIn
(
AABB
container
)
{
Objects
.
requireNonNull
(
container
,
"container"
);
List
<
E
>
result
=
new
ArrayList
<>();
List
<
E
>
result
=
new
ArrayList
<>();
collectMatchingElements
(
collectMatchingElements
(
root
,
root
,
...
@@ -161,14 +155,13 @@ public class BoundingVolumeHierarchyTree<E> {
...
@@ -161,14 +155,13 @@ public class BoundingVolumeHierarchyTree<E> {
}
}
}
}
public
static
AABB
getAggregateAABB
(
List
<
ConcretePolygon
>
polygons
)
{
public
static
<
E
>
AABB
getAggregateAABB
(
List
<
E
>
elements
,
Function
<
E
,
AABB
>
aabbFunc
)
{
if
(
polygons
.
size
()
==
1
)
{
Objects
.
requireNonNull
(
elements
,
"elements"
);
return
AABB
.
of
(
polygons
.
get
(
0
));
Objects
.
requireNonNull
(
aabbFunc
,
"aabbFunc"
);
if
(
elements
.
isEmpty
())
{
throw
new
IllegalArgumentException
(
"elements must not be empty"
);
}
}
return
getAggregateAABB
(
polygons
,
AABB:
:
of
);
}
public
static
<
E
>
AABB
getAggregateAABB
(
List
<
E
>
elements
,
Function
<
E
,
AABB
>
aabbFunc
)
{
double
minX
=
Double
.
POSITIVE_INFINITY
;
double
minX
=
Double
.
POSITIVE_INFINITY
;
double
minY
=
Double
.
POSITIVE_INFINITY
;
double
minY
=
Double
.
POSITIVE_INFINITY
;
double
minZ
=
Double
.
POSITIVE_INFINITY
;
double
minZ
=
Double
.
POSITIVE_INFINITY
;
...
@@ -177,7 +170,7 @@ public class BoundingVolumeHierarchyTree<E> {
...
@@ -177,7 +170,7 @@ public class BoundingVolumeHierarchyTree<E> {
double
maxZ
=
Double
.
NEGATIVE_INFINITY
;
double
maxZ
=
Double
.
NEGATIVE_INFINITY
;
for
(
E
e
:
elements
)
{
for
(
E
e
:
elements
)
{
AABB
aabb
=
aabbFunc
.
apply
(
e
);
AABB
aabb
=
Objects
.
requireNonNull
(
aabbFunc
.
apply
(
e
),
"aabbFunc returned null"
);
minX
=
Math
.
min
(
minX
,
aabb
.
getMinX
());
minX
=
Math
.
min
(
minX
,
aabb
.
getMinX
());
minY
=
Math
.
min
(
minY
,
aabb
.
getMinY
());
minY
=
Math
.
min
(
minY
,
aabb
.
getMinY
());
minZ
=
Math
.
min
(
minZ
,
aabb
.
getMinZ
());
minZ
=
Math
.
min
(
minZ
,
aabb
.
getMinZ
());
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment