2021-11-03 22:57:48 +03:00
|
|
|
//
|
|
|
|
// Created by Иван Ильин on 04.11.2021.
|
|
|
|
//
|
|
|
|
|
2021-11-06 00:28:55 +03:00
|
|
|
#include <set>
|
2021-11-06 11:01:58 +03:00
|
|
|
#include <cmath>
|
2021-11-04 04:30:58 +03:00
|
|
|
|
2021-11-03 22:57:48 +03:00
|
|
|
#include "HitBox.h"
|
2021-11-06 00:28:55 +03:00
|
|
|
#include "../Consts.h"
|
|
|
|
|
|
|
|
bool HitBox::Vec3DLess::operator()(const Vec3D& lhs, const Vec3D& rhs) const noexcept {
|
|
|
|
if (fabs(lhs.x() - rhs.x()) >= Consts::EPS)
|
|
|
|
return lhs.x() < rhs.x();
|
|
|
|
else if (fabs(lhs.y() - rhs.y()) >= Consts::EPS)
|
|
|
|
return lhs.y() < rhs.y();
|
|
|
|
else if (fabs(lhs.z() - rhs.z()) >= Consts::EPS)
|
|
|
|
return lhs.z() < rhs.z();
|
|
|
|
else
|
|
|
|
return false;
|
2021-11-03 22:57:48 +03:00
|
|
|
}
|
|
|
|
|
2021-11-09 22:54:20 +03:00
|
|
|
HitBox::HitBox(const Mesh& mesh, bool useSimpleBox) {
|
|
|
|
if (useSimpleBox) {
|
|
|
|
generateSimple(mesh);
|
|
|
|
} else {
|
|
|
|
generateDetailed(mesh);
|
|
|
|
}
|
2021-11-03 22:57:48 +03:00
|
|
|
}
|
|
|
|
|
2021-11-09 22:54:20 +03:00
|
|
|
void HitBox::generateSimple(const Mesh &mesh) {
|
2021-11-03 22:57:48 +03:00
|
|
|
double maxX = -std::numeric_limits<double>::max();
|
|
|
|
double maxY = -std::numeric_limits<double>::max();
|
|
|
|
double maxZ = -std::numeric_limits<double>::max();
|
|
|
|
|
|
|
|
double minX = std::numeric_limits<double>::max();
|
|
|
|
double minY = std::numeric_limits<double>::max();
|
|
|
|
double minZ = std::numeric_limits<double>::max();
|
|
|
|
|
|
|
|
for(const auto& t : mesh.triangles()) {
|
|
|
|
for(int i = 0; i < 3; i++) {
|
2021-11-05 00:05:06 +03:00
|
|
|
auto point = Vec3D(t[i]);
|
2021-11-03 22:57:48 +03:00
|
|
|
if(point.x() > maxX) {
|
|
|
|
maxX = point.x();
|
|
|
|
}
|
|
|
|
if(point.y() > maxY) {
|
|
|
|
maxY = point.y();
|
|
|
|
}
|
|
|
|
if(point.z() > maxZ) {
|
|
|
|
maxZ = point.z();
|
|
|
|
}
|
|
|
|
|
|
|
|
if(point.x() < minX) {
|
|
|
|
minX = point.x();
|
|
|
|
}
|
|
|
|
if(point.y() < minY) {
|
|
|
|
minY = point.y();
|
|
|
|
}
|
|
|
|
if(point.z() < minZ) {
|
|
|
|
minZ = point.z();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-09 22:54:20 +03:00
|
|
|
_hitBox.emplace_back(minX, minY, minZ);
|
|
|
|
_hitBox.emplace_back(minX, maxY, minZ);
|
|
|
|
_hitBox.emplace_back(maxX, minY, minZ);
|
|
|
|
_hitBox.emplace_back(maxX, maxY, minZ);
|
2021-11-03 22:57:48 +03:00
|
|
|
|
2021-11-09 22:54:20 +03:00
|
|
|
_hitBox.emplace_back(minX, minY, maxZ);
|
|
|
|
_hitBox.emplace_back(minX, maxY, maxZ);
|
|
|
|
_hitBox.emplace_back(maxX, minY, maxZ);
|
|
|
|
_hitBox.emplace_back(maxX, maxY, maxZ);
|
|
|
|
}
|
|
|
|
|
|
|
|
void HitBox::generateDetailed(const Mesh &mesh) {
|
|
|
|
// we dont need to add the same points in hit box
|
|
|
|
std::set<Vec3D, HitBox::Vec3DLess> points;
|
|
|
|
|
|
|
|
for (const auto& t : mesh.triangles())
|
|
|
|
for (int i = 0; i < 3; i++)
|
|
|
|
points.insert(Vec3D(t[i]));
|
2021-11-03 22:57:48 +03:00
|
|
|
|
2021-11-09 22:54:20 +03:00
|
|
|
_hitBox.reserve(points.size());
|
|
|
|
for (const auto& it : points)
|
|
|
|
_hitBox.push_back(it);
|
|
|
|
_hitBox.shrink_to_fit();
|
2021-11-03 22:57:48 +03:00
|
|
|
}
|