55 lines
1.5 KiB
C++
55 lines
1.5 KiB
C++
|
|
#pragma once
|
||
|
|
#include "vde/core/point.h"
|
||
|
|
#include <algorithm>
|
||
|
|
#include <limits>
|
||
|
|
|
||
|
|
namespace vde::core {
|
||
|
|
|
||
|
|
template <typename T>
|
||
|
|
class AABB {
|
||
|
|
public:
|
||
|
|
AABB() : min_(Point3D::Constant(std::numeric_limits<T>::max())),
|
||
|
|
max_(Point3D::Constant(std::numeric_limits<T>::lowest())) {}
|
||
|
|
|
||
|
|
AABB(const Point3D& min, const Point3D& max) : min_(min), max_(max) {}
|
||
|
|
|
||
|
|
void expand(const Point3D& p) {
|
||
|
|
min_ = min_.cwiseMin(p);
|
||
|
|
max_ = max_.cwiseMax(p);
|
||
|
|
}
|
||
|
|
|
||
|
|
void expand(const AABB& other) {
|
||
|
|
min_ = min_.cwiseMin(other.min_);
|
||
|
|
max_ = max_.cwiseMax(other.max_);
|
||
|
|
}
|
||
|
|
|
||
|
|
[[nodiscard]] Point3D center() const { return (min_ + max_) * 0.5; }
|
||
|
|
[[nodiscard]] Vector3D extent() const { return max_ - min_; }
|
||
|
|
[[nodiscard]] T surface_area() const {
|
||
|
|
Vector3D e = extent();
|
||
|
|
return 2.0 * (e.x() * e.y() + e.y() * e.z() + e.z() * e.x());
|
||
|
|
}
|
||
|
|
[[nodiscard]] T volume() const {
|
||
|
|
Vector3D e = extent();
|
||
|
|
return e.x() * e.y() * e.z();
|
||
|
|
}
|
||
|
|
[[nodiscard]] bool contains(const Point3D& p) const {
|
||
|
|
return (p.array() >= min_.array()).all() && (p.array() <= max_.array()).all();
|
||
|
|
}
|
||
|
|
[[nodiscard]] bool intersects(const AABB& other) const {
|
||
|
|
return (min_.array() <= other.max_.array()).all()
|
||
|
|
&& (max_.array() >= other.min_.array()).all();
|
||
|
|
}
|
||
|
|
|
||
|
|
[[nodiscard]] const Point3D& min() const { return min_; }
|
||
|
|
[[nodiscard]] const Point3D& max() const { return max_; }
|
||
|
|
|
||
|
|
private:
|
||
|
|
Point3D min_, max_;
|
||
|
|
};
|
||
|
|
|
||
|
|
using AABB3D = AABB<double>;
|
||
|
|
using AABB3f = AABB<float>;
|
||
|
|
|
||
|
|
} // namespace vde::core
|