A demo for mesh-voxel conversion
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

177 lines
4.0 KiB

#pragma once
#include <vector>
#include <cassert>
template<typename T>
class Vec3 {
public:
Vec3(T a_, T b_, T c_) : a(a_), b(b_), c(c_) {}
Vec3() : a(0), b(0), c(0) {}
union { T x, a; };
union { T y, b; };
union { T z, c; };
T operator[](int i) const {
if (i == 0) {
return a;
} else if (i == 1) {
return b;
} else if (i == 2) {
return c;
}
return a;
}
T &operator[](int i) {
if (i == 0) {
return a;
} else if (i == 1) {
return b;
} else if (i == 2) {
return c;
}
return a;
}
Vec3 operator+(const Vec3 &other) const {
return {a + other.a, b + other.b, c + other.c};
}
Vec3 operator/(const float w) const {
return {a / w, b / w, c / w};
}
Vec3 operator-(const Vec3 &other) const {
return {a - other.a, b - other.b, c - other.c};
}
Vec3 operator*(const float &w) const {
return {a * w, b * w, c * w};
}
float length() const {
return sqrt(a * a + b * b + c * c);
}
Vec3 norm() const {
return *this / length();
}
Vec3 cross(const Vec3 &other) const {
return {b * other.c - c * other.b, c * other.a - a * other.c, a * other.b - b * other.a};
}
float dot(const Vec3 &other) const {
return a * other.a + b * other.b + c * other.c;
}
bool operator==(const Vec3& other) const {
return x == other.x && y == other.y && z == other.z;
}
};
// 为 Vec3 创建哈希函数
namespace std {
template<typename T>
struct hash<Vec3<T>> {
size_t operator()(const Vec3<T>& vec) const {
return hash<T>()(vec.x) ^ hash<T>()(vec.y) ^ hash<T>()(vec.z);
}
};
}
typedef Vec3<float> Vec3f;
typedef Vec3<unsigned int> Vec3u;
class AABB {
public:
Vec3f min = {std::numeric_limits<float>::max(), std::numeric_limits<float>::max(),
std::numeric_limits<float>::max()};
Vec3f max = {std::numeric_limits<float>::lowest(), std::numeric_limits<float>::lowest(),
std::numeric_limits<float>::lowest()};
Vec3f center() const {
return (min + max) / 2;
}
Vec3f size() const {
return max - min;
}
AABB operator+(const Vec3f& v) const {
return {min + v, max + v};
}
};
class Mesh {
public:
std::vector<Vec3f> vertices;
std::vector<Vec3u> faces;
// 获得指定面的 AABB
AABB getAABB(const std::vector<size_t>& faceIndices) const {
AABB aabb;
for (const size_t &idx: faceIndices) {
const Vec3u &face = faces[idx];
for (int i = 0; i < 3; ++i) {
const Vec3f &v = vertices[face[i]];
for (int j = 0; j < 3; ++j) {
aabb.min[j] = std::min(aabb.min[j], v[j]);
aabb.max[j] = std::max(aabb.max[j], v[j]);
}
}
}
return aabb;
}
AABB getAABB() const {
AABB aabb;
for (const Vec3f &v: vertices) {
for (int j = 0; j < 3; ++j) {
aabb.min[j] = std::min(aabb.min[j], v[j]);
aabb.max[j] = std::max(aabb.max[j], v[j]);
}
}
return aabb;
}
};
//class LineSegment {
//public:
// Vec3f start;
// Vec3f end;
//
// /**
// * @brief Construct a new Line Segment object
// * @param s start point
// * @param e end point
// * @param r radius
// */
// LineSegment(const Vec3f &s, const Vec3f &e, const float r = 0) : start(s), end(e) {
// length = (end - start).length();
// dir = (end - start).norm();
// }
//
// float getLength() const {
// return length;
// }
//
// Vec3f getDir() const {
// return dir;
// }
//
//private:
// float length;
// Vec3f dir;
//};
class Ray {
public:
Vec3f start;
Vec3f dir;
Ray(const Vec3f &s, const Vec3f &d) : start(s), dir(d) {
dir = dir.norm();
}
};