// Copyright Matt Overby 2020. // Distributed under the MIT License. #ifndef ADMMPD_BVH_H_ #define ADMMPD_BVH_H_ 1 #include "admmpd_bvh_traverse.h" #include #include #include namespace admmpd { template class AABBTree { protected: typedef Eigen::AlignedBox AABB; typedef Eigen::Matrix VecType; public: // Removes all BVH data void clear(); // Initializes the BVH with a list of leaf bounding boxes. // Sorts each split by largest axis. void init(const std::vector &leaves); // Recomputes the bounding boxes of leaf and parent // nodes but does not sort the tree. void update(const std::vector &leaves); // Traverse the tree. Returns result of traverser bool traverse(Traverser &traverser) const; // Traverse the tree with function pointers instead of class: // void traverse( // const AABB &left_aabb, bool &go_left, // const AABB &right_aabb, bool &go_right, // bool &go_left_first); // bool stop_traversing( const AABB &aabb, int prim ); bool traverse( std::function t, std::function s) const; struct Node { AABB aabb; Node *left, *right; std::vector prims; VecType normal; T angle; bool is_leaf() const { return prims.size()>0; } Node() : left(nullptr), right(nullptr) {} ~Node() { if(left){ delete left; } if(right){ delete right; } } }; // Return ptr to the root node // Becomes invalidated after init() std::shared_ptr root() { return m_root; } protected: std::shared_ptr m_root; void create_children( Node *node, std::vector &queue, const std::vector &leaves); void update_children( Node *node, const std::vector &leaves); bool traverse_children( const Node *node, Traverser &traverser ) const; }; // class AABBtree // Octree is actually a quadtree if DIM=2 template class Octree { protected: typedef Eigen::AlignedBox AABB; typedef Eigen::Matrix VecType; typedef Eigen::Matrix MatrixXT; static const int nchild = std::pow(2,DIM); public: // Removes all BVH data void clear(); // Creates the Octree up to depth with smart subdivision // (only create children if it contains prims) and does not // create a cell if it is outside the mesh. // ** Assumes a closed mesh and only defined for 3D void init(const MatrixXT *V, const Eigen::MatrixXi *F, int stopdepth); // Returns bounding box of the root node AABB bounds() const; struct Node { VecType center; T halfwidth; Node *children[4*DIM]; std::vector prims; // includes childen bool is_leaf() const; AABB bounds() const; Node(); ~Node(); }; // Return ptr to the root node // Becomes invalidated after init() std::shared_ptr root() { return m_root; } protected: std::shared_ptr m_root; Node* create_children( const VecType ¢er, T halfwidth, int stopdepth, const MatrixXT *V, const Eigen::MatrixXi *F, const std::vector &queue, const std::vector &boxes); }; // class Octree } // namespace admmpd #endif // ADMMPD_BVH_H_