92 lines
2.2 KiB
C++
Executable File
92 lines
2.2 KiB
C++
Executable File
#pragma once
|
|
|
|
#include "glm/glm.hpp"
|
|
|
|
#include <limits>
|
|
#include <algorithm>
|
|
#include <span>
|
|
#include <array>
|
|
|
|
struct aabb
|
|
{
|
|
using vector_type = glm::vec3;
|
|
using scalar_type = vector_type::value_type;
|
|
using index_type = vector_type::length_type;
|
|
|
|
static constexpr auto default_min = std::numeric_limits<scalar_type>::max();
|
|
static constexpr auto default_max =-std::numeric_limits<scalar_type>::max();
|
|
|
|
vector_type min { default_min, default_min, default_min };
|
|
vector_type max { default_max, default_max, default_max };
|
|
|
|
[[nodiscard]] vector_type size() const
|
|
{
|
|
return max - min;
|
|
}
|
|
|
|
[[nodiscard]] vector_type center() const
|
|
{
|
|
return min + 0.5f * size();
|
|
}
|
|
|
|
[[nodiscard]] vector_type closest_point_inside(const vector_type& point) const {
|
|
return {
|
|
std::clamp(point.x, min.x, max.x),
|
|
std::clamp(point.y, min.y, max.y),
|
|
std::clamp(point.z, min.z, max.z)
|
|
};
|
|
}
|
|
|
|
aabb& add_aabb(const aabb& other)
|
|
{
|
|
for (index_type i{}; i != min.length(); ++i)
|
|
{
|
|
min[i] = std::min(min[i], other.min[i]);
|
|
max[i] = std::max(max[i], other.max[i]);
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
aabb& add_point(const auto& point)
|
|
{
|
|
for (index_type i{}; i != min.length(); ++i)
|
|
{
|
|
min[i] = std::min(min[i], point[i]);
|
|
max[i] = std::max(max[i], point[i]);
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
template<typename T>
|
|
aabb& add_points(std::span<const T> points)
|
|
{
|
|
for (const auto& point : points)
|
|
{
|
|
add_point(point);
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
aabb& join(const aabb& other)
|
|
{
|
|
min = glm::min(min, other.min);
|
|
max = glm::max(max, other.max);
|
|
return *this;
|
|
}
|
|
|
|
[[nodiscard]] aabb transformed(const glm::mat4x4& matrix) const
|
|
{
|
|
const auto vertices = std::array{
|
|
vector_type{ matrix * glm::vec4{ min.x, min.y, min.z, 1 } },
|
|
vector_type{ matrix * glm::vec4{ min.x, min.y, max.z, 1 } },
|
|
vector_type{ matrix * glm::vec4{ min.x, max.y, min.z, 1 } },
|
|
vector_type{ matrix * glm::vec4{ min.x, max.y, max.z, 1 } },
|
|
vector_type{ matrix * glm::vec4{ max.x, min.y, min.z, 1 } },
|
|
vector_type{ matrix * glm::vec4{ max.x, min.y, max.z, 1 } },
|
|
vector_type{ matrix * glm::vec4{ max.x, max.y, min.z, 1 } },
|
|
vector_type{ matrix * glm::vec4{ max.x, max.y, max.z, 1 } }
|
|
};
|
|
return aabb{}.add_points<vector_type>(vertices);
|
|
}
|
|
};
|