#pragma once #include #include template 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 struct hash> { size_t operator()(const Vec3& vec) const { return hash()(vec.x) ^ hash()(vec.y) ^ hash()(vec.z); } }; } typedef Vec3 Vec3f; typedef Vec3 Vec3u; class AABB { public: Vec3f min = {std::numeric_limits::max(), std::numeric_limits::max(), std::numeric_limits::max()}; Vec3f max = {std::numeric_limits::lowest(), std::numeric_limits::lowest(), std::numeric_limits::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 vertices; std::vector faces; // 获得指定面的 AABB AABB getAABB(const std::vector& 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(); } };