summaryrefslogtreecommitdiff
path: root/core/math/bvh_abb.h
diff options
context:
space:
mode:
Diffstat (limited to 'core/math/bvh_abb.h')
-rw-r--r--core/math/bvh_abb.h64
1 files changed, 38 insertions, 26 deletions
diff --git a/core/math/bvh_abb.h b/core/math/bvh_abb.h
index 009032d34d..8a44f1c4da 100644
--- a/core/math/bvh_abb.h
+++ b/core/math/bvh_abb.h
@@ -32,7 +32,7 @@
#define BVH_ABB_H
// special optimized version of axis aligned bounding box
-template <class Bounds = AABB, class Point = Vector3>
+template <class BOUNDS = AABB, class POINT = Vector3>
struct BVH_ABB {
struct ConvexHull {
// convex hulls (optional)
@@ -43,8 +43,8 @@ struct BVH_ABB {
};
struct Segment {
- Point from;
- Point to;
+ POINT from;
+ POINT to;
};
enum IntersectResult {
@@ -54,47 +54,47 @@ struct BVH_ABB {
};
// we store mins with a negative value in order to test them with SIMD
- Point min;
- Point neg_max;
+ POINT min;
+ POINT neg_max;
bool operator==(const BVH_ABB &o) const { return (min == o.min) && (neg_max == o.neg_max); }
bool operator!=(const BVH_ABB &o) const { return (*this == o) == false; }
- void set(const Point &_min, const Point &_max) {
+ void set(const POINT &_min, const POINT &_max) {
min = _min;
neg_max = -_max;
}
// to and from standard AABB
- void from(const Bounds &p_aabb) {
+ void from(const BOUNDS &p_aabb) {
min = p_aabb.position;
neg_max = -(p_aabb.position + p_aabb.size);
}
- void to(Bounds &r_aabb) const {
+ void to(BOUNDS &r_aabb) const {
r_aabb.position = min;
r_aabb.size = calculate_size();
}
void merge(const BVH_ABB &p_o) {
- for (int axis = 0; axis < Point::AXIS_COUNT; ++axis) {
+ for (int axis = 0; axis < POINT::AXIS_COUNT; ++axis) {
neg_max[axis] = MIN(neg_max[axis], p_o.neg_max[axis]);
min[axis] = MIN(min[axis], p_o.min[axis]);
}
}
- Point calculate_size() const {
+ POINT calculate_size() const {
return -neg_max - min;
}
- Point calculate_centre() const {
- return Point((calculate_size() * 0.5) + min);
+ POINT calculate_centre() const {
+ return POINT((calculate_size() * 0.5) + min);
}
real_t get_proximity_to(const BVH_ABB &p_b) const {
- const Point d = (min - neg_max) - (p_b.min - p_b.neg_max);
+ const POINT d = (min - neg_max) - (p_b.min - p_b.neg_max);
real_t proximity = 0.0;
- for (int axis = 0; axis < Point::AXIS_COUNT; ++axis) {
+ for (int axis = 0; axis < POINT::AXIS_COUNT; ++axis) {
proximity += Math::abs(d[axis]);
}
return proximity;
@@ -104,7 +104,7 @@ struct BVH_ABB {
return (get_proximity_to(p_a) < get_proximity_to(p_b) ? 0 : 1);
}
- uint32_t find_cutting_planes(const BVH_ABB::ConvexHull &p_hull, uint32_t *p_plane_ids) const {
+ uint32_t find_cutting_planes(const typename BVH_ABB::ConvexHull &p_hull, uint32_t *p_plane_ids) const {
uint32_t count = 0;
for (int n = 0; n < p_hull.num_planes; n++) {
@@ -162,7 +162,7 @@ struct BVH_ABB {
}
bool intersects_convex_partial(const ConvexHull &p_hull) const {
- Bounds bb;
+ BOUNDS bb;
to(bb);
return bb.intersects_convex_shape(p_hull.planes, p_hull.num_planes, p_hull.points, p_hull.num_points);
}
@@ -182,7 +182,7 @@ struct BVH_ABB {
bool is_within_convex(const ConvexHull &p_hull) const {
// use half extents routine
- Bounds bb;
+ BOUNDS bb;
to(bb);
return bb.inside_convex_shape(p_hull.planes, p_hull.num_planes);
}
@@ -197,12 +197,12 @@ struct BVH_ABB {
}
bool intersects_segment(const Segment &p_s) const {
- Bounds bb;
+ BOUNDS bb;
to(bb);
return bb.intersects_segment(p_s.from, p_s.to);
}
- bool intersects_point(const Point &p_pt) const {
+ bool intersects_point(const POINT &p_pt) const {
if (_any_lessthan(-p_pt, neg_max)) {
return false;
}
@@ -212,6 +212,7 @@ struct BVH_ABB {
return true;
}
+ // Very hot in profiling, make sure optimized
bool intersects(const BVH_ABB &p_o) const {
if (_any_morethan(p_o.min, -neg_max)) {
return false;
@@ -222,6 +223,17 @@ struct BVH_ABB {
return true;
}
+ // for pre-swizzled tester (this object)
+ bool intersects_swizzled(const BVH_ABB &p_o) const {
+ if (_any_lessthan(min, p_o.min)) {
+ return false;
+ }
+ if (_any_lessthan(neg_max, p_o.neg_max)) {
+ return false;
+ }
+ return true;
+ }
+
bool is_other_within(const BVH_ABB &p_o) const {
if (_any_lessthan(p_o.neg_max, neg_max)) {
return false;
@@ -232,20 +244,20 @@ struct BVH_ABB {
return true;
}
- void grow(const Point &p_change) {
+ void grow(const POINT &p_change) {
neg_max -= p_change;
min -= p_change;
}
void expand(real_t p_change) {
- Point change;
+ POINT change;
change.set_all(p_change);
grow(change);
}
// Actually surface area metric.
float get_area() const {
- Point d = calculate_size();
+ POINT d = calculate_size();
return 2.0f * (d.x * d.y + d.y * d.z + d.z * d.x);
}
@@ -254,8 +266,8 @@ struct BVH_ABB {
min = neg_max;
}
- bool _any_morethan(const Point &p_a, const Point &p_b) const {
- for (int axis = 0; axis < Point::AXIS_COUNT; ++axis) {
+ bool _any_morethan(const POINT &p_a, const POINT &p_b) const {
+ for (int axis = 0; axis < POINT::AXIS_COUNT; ++axis) {
if (p_a[axis] > p_b[axis]) {
return true;
}
@@ -263,8 +275,8 @@ struct BVH_ABB {
return false;
}
- bool _any_lessthan(const Point &p_a, const Point &p_b) const {
- for (int axis = 0; axis < Point::AXIS_COUNT; ++axis) {
+ bool _any_lessthan(const POINT &p_a, const POINT &p_b) const {
+ for (int axis = 0; axis < POINT::AXIS_COUNT; ++axis) {
if (p_a[axis] < p_b[axis]) {
return true;
}