#pragma once #include #include #include #include #include #include #include #include #include using std::tr1::shared_ptr; struct BvhTreeData { QVector4D bound; GLuint leftSon, rightSon; void show() { printf("Bvh: (%lf, %lf) (%lf, %lf): %d %d\n", bound.x(), bound.y(), bound.z(), bound.w(), leftSon, rightSon); } BvhTreeData() : leftSon(0), rightSon(0) {} ~BvhTreeData() {} }; // BvhTree 节点 struct BvhNode { GLuint lab; bool isLeaf; QVector4D bound; shared_ptr child[2]; static bool x_compare(BvhTreeData a, BvhTreeData b) { return a.bound.x() < b.bound.x(); } static bool y_compare(BvhTreeData a, BvhTreeData b) { return a.bound.y() < b.bound.y(); } GLuint getLeftSon(int k) { if (isLeaf) { return 0x80000000+child[0]->lab; } return child[0]->lab; } GLuint getRightSon(int k) { if (isLeaf) { return child[1]->lab; } return child[1]->lab; } BvhNode() { child[0] = child[1] = NULL; isLeaf = false; lab = 0; } int maximumBound() { return (std::fabs(bound.x() - bound.w()) < std::fabs(bound.y() - bound.z())); } ~BvhNode() {} }; typedef std::tr1::shared_ptr BvhPtr; class BvhTree { private: GLuint tot; BvhPtr root; static QVector4D calcBound(BvhTreeData initBound[], int l, int r); static QVector4D Union(QVector4D a, QVector4D b); BvhPtr subBvhTree(BvhTreeData initBound[], int l, int r); void traverseBvhTree(BvhPtr now, std::vector& children, std::vector& bounds); public: BvhTree() { tot = 0; root = NULL; } // 根据底层包围盒生成bvh树 void buildBvhTree(BvhTreeData initBound[], int len); // 获得 Bvh (rootBvh部分)的 children 数组,包围盒数组 vector 传输 void getBvhArray(std::vector& children, std::vector& bounds); // 获得 BvhTree 中节点总数 GLuint getBvhNodeNum(); };