diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/BvhTree.cpp b/ArchitectureColoredPainting/src/Renderer/Painting/BvhTree.cpp index 3de220a..82edf94 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/BvhTree.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Painting/BvhTree.cpp @@ -6,9 +6,6 @@ GLuint BvhTree::getBvhNodeNum() { void BvhTree::buildBvhTree(BvhTreeData initBound[], int len, GLuint transformParam) { tot = 0; transform = transformParam; - for (int i = 0; i < len; i++) { - initBound->bound = initBound->boundWithRotation(); - } root = subBvhTree(initBound, 0, len-1); } @@ -21,6 +18,17 @@ QVector4D BvhTree::Union(QVector4D a, QVector4D b) { ); } +QVector4D BvhTree::merge(BvhPtr lp, BvhPtr rp) { + QVector4D a = lp->bound, b = rp->bound; + if (lp->isLeaf) { + a = BvhTreeData::boundWithRotation(a, lp->getRightSon()); + } + if (rp->isLeaf) { + b = BvhTreeData::boundWithRotation(b, rp->getRightSon()); + } + return Union(a, b); +} + QVector4D BvhTree::calcBound(BvhTreeData initBound[], int l, int r) { QVector4D res = initBound[l].bound; for (int i = l + 1; i <= r; i++) { @@ -54,13 +62,13 @@ BvhPtr BvhTree::subBvhTree(BvhTreeData initBound[], int l, int r) { int mid = (l + r) >> 1; p->child[0] = subBvhTree(initBound, l, mid); p->child[1] = subBvhTree(initBound, mid+1, r); - p->bound = Union(p->child[0]->bound, p->child[1]->bound); + p->bound = merge(p->child[0], p->child[1]); return p; } void BvhTree::traverseBvhTree(BvhPtr now, std::vector& children, std::vector& bounds) { - children.push_back(now->getLeftSon(0)); - children.push_back(now->getRightSon(1)); + children.push_back(now->getLeftSon()); + children.push_back(now->getRightSon()); bounds.push_back(now->bound); if (now->isLeaf) return; traverseBvhTree(now->child[0], children, bounds); diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/BvhTree.h b/ArchitectureColoredPainting/src/Renderer/Painting/BvhTree.h index 4abc27f..de37d18 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/BvhTree.h +++ b/ArchitectureColoredPainting/src/Renderer/Painting/BvhTree.h @@ -20,15 +20,22 @@ namespace Renderer bound.x(), bound.y(), bound.z(), bound.w(), leftSon, rightSon); } - QVector4D boundWithRotation() { - double angle = (rightSon & ((1 << 16) - 1)) / static_cast((1 << 16)) * acos(-1); - double px = bound.x() * cos(angle) + bound.y() * sin(angle), py = bound.y() * cos(angle) - bound.x() * sin(angle); - double qx = bound.z() * cos(angle) + bound.w() * sin(angle), qy = bound.w() * cos(angle) - bound.z() * sin(angle); + static QVector4D boundWithRotation(QVector4D bound, GLuint rightSon) { + double angle = (rightSon & ((1 << 16) - 1)) / static_cast((1 << 16)) * 2 * acos(-1); + double centerX = (bound.x() + bound.z()) / 2, centerY = (bound.y() + bound.w()) / 2; + double xCosMin = std::min((bound.x() - centerX) * cos(angle), (bound.z() - centerX) * cos(angle)), + xCosMax = std::max((bound.x() - centerX) * cos(angle), (bound.z() - centerX) * cos(angle)); + double xSinMin = std::min((bound.x() - centerX) * sin(angle), (bound.z() - centerX) * sin(angle)), + xSinMax = std::max((bound.x() - centerX) * sin(angle), (bound.z() - centerX) * sin(angle)); + double yCosMin = std::min((bound.y() - centerY) * cos(angle), (bound.w() - centerY) * cos(angle)), + yCosMax = std::max((bound.y() - centerY) * cos(angle), (bound.w() - centerY) * cos(angle)); + double ySinMin = std::min((bound.y() - centerY) * sin(angle), (bound.w() - centerY) * sin(angle)), + ySinMax = std::max((bound.y() - centerY) * sin(angle), (bound.w() - centerY) * sin(angle)); return QVector4D( - std::min(px, qx), - std::min(py, qy), - std::max(px, qx), - std::max(py, qy) + xCosMin - ySinMax + centerX, + yCosMin + xSinMin + centerY, + xCosMax - ySinMin + centerX, + yCosMax + xSinMax + centerY ); } BvhTreeData(QVector4D bound, GLuint leftSon, GLuint rightSon) @@ -49,13 +56,13 @@ namespace Renderer static bool y_compare(BvhTreeData a, BvhTreeData b) { return a.bound.y() < b.bound.y(); } - GLuint getLeftSon(int k) { + GLuint getLeftSon() { if (isLeaf) { return 0x80000000 + child[0]->lab; } return child[0]->lab; } - GLuint getRightSon(int k) { + GLuint getRightSon() { if (isLeaf) { return child[1]->lab; } @@ -84,6 +91,7 @@ namespace Renderer 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); + QVector4D merge(BvhPtr lp, BvhPtr rp); public: BvhTree() { tot = 0;