2022-08-07 18:46:39 +08:00
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <QOpenGLTexture>
|
|
|
|
|
#include <QOpenGLContext>
|
|
|
|
|
#include <QTextCodec>
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
#include <QVector4D>
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <memory>
|
|
|
|
|
#include <vector>
|
|
|
|
|
#include <cmath>
|
|
|
|
|
|
2022-09-06 22:16:04 +08:00
|
|
|
|
using std::tr1::shared_ptr;
|
2022-09-30 23:45:42 +08:00
|
|
|
|
|
|
|
|
|
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() {}
|
|
|
|
|
};
|
2022-08-07 18:46:39 +08:00
|
|
|
|
// BvhTree <20>ڵ<EFBFBD>
|
|
|
|
|
struct BvhNode {
|
|
|
|
|
GLuint lab;
|
2022-09-30 23:45:42 +08:00
|
|
|
|
bool isLeaf;
|
2022-08-07 18:46:39 +08:00
|
|
|
|
QVector4D bound;
|
2022-09-06 22:16:04 +08:00
|
|
|
|
shared_ptr<BvhNode> child[2];
|
2022-09-30 23:45:42 +08:00
|
|
|
|
static bool x_compare(BvhTreeData a, BvhTreeData b) {
|
|
|
|
|
return a.bound.x() < b.bound.x();
|
2022-08-07 18:46:39 +08:00
|
|
|
|
}
|
2022-09-30 23:45:42 +08:00
|
|
|
|
static bool y_compare(BvhTreeData a, BvhTreeData b) {
|
|
|
|
|
return a.bound.y() < b.bound.y();
|
2022-08-07 18:46:39 +08:00
|
|
|
|
}
|
2022-08-07 22:25:33 +08:00
|
|
|
|
GLuint getLeftSon(int k) {
|
2022-09-30 23:45:42 +08:00
|
|
|
|
if (isLeaf) {
|
|
|
|
|
return 0x80000000+child[0]->lab;
|
2022-08-07 22:25:33 +08:00
|
|
|
|
}
|
2022-09-30 23:45:42 +08:00
|
|
|
|
return child[0]->lab;
|
2022-08-07 22:25:33 +08:00
|
|
|
|
}
|
|
|
|
|
GLuint getRightSon(int k) {
|
2022-09-30 23:45:42 +08:00
|
|
|
|
if (isLeaf) {
|
|
|
|
|
return child[1]->lab;
|
2022-08-07 22:25:33 +08:00
|
|
|
|
}
|
2022-09-30 23:45:42 +08:00
|
|
|
|
return child[1]->lab;
|
2022-08-07 18:46:39 +08:00
|
|
|
|
}
|
|
|
|
|
BvhNode() {
|
|
|
|
|
child[0] = child[1] = NULL;
|
2022-09-30 23:45:42 +08:00
|
|
|
|
isLeaf = false;
|
|
|
|
|
lab = 0;
|
2022-08-07 18:46:39 +08:00
|
|
|
|
}
|
|
|
|
|
int maximumBound() {
|
|
|
|
|
return (std::fabs(bound.x() - bound.w()) < std::fabs(bound.y() - bound.z()));
|
|
|
|
|
}
|
|
|
|
|
~BvhNode() {}
|
|
|
|
|
};
|
|
|
|
|
|
2022-09-30 23:45:42 +08:00
|
|
|
|
typedef std::tr1::shared_ptr<BvhNode> BvhPtr;
|
2022-09-06 22:16:04 +08:00
|
|
|
|
|
2022-08-07 18:46:39 +08:00
|
|
|
|
class BvhTree
|
|
|
|
|
{
|
2022-09-06 22:16:04 +08:00
|
|
|
|
|
2022-08-07 18:46:39 +08:00
|
|
|
|
private:
|
|
|
|
|
GLuint tot;
|
2022-09-30 23:45:42 +08:00
|
|
|
|
BvhPtr root;
|
|
|
|
|
static QVector4D calcBound(BvhTreeData initBound[], int l, int r);
|
2022-08-07 18:46:39 +08:00
|
|
|
|
static QVector4D Union(QVector4D a, QVector4D b);
|
2022-09-30 23:45:42 +08:00
|
|
|
|
BvhPtr subBvhTree(BvhTreeData initBound[], int l, int r);
|
|
|
|
|
void traverseBvhTree(BvhPtr now, std::vector<GLuint>& children, std::vector<QVector4D>& bounds);
|
2022-08-07 18:46:39 +08:00
|
|
|
|
public:
|
|
|
|
|
BvhTree() {
|
|
|
|
|
tot = 0;
|
|
|
|
|
root = NULL;
|
|
|
|
|
}
|
|
|
|
|
// <20><><EFBFBD>ݵײ<DDB5><D7B2><EFBFBD>Χ<EFBFBD><CEA7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>bvh<76><68>
|
2022-09-30 23:45:42 +08:00
|
|
|
|
void buildBvhTree(BvhTreeData initBound[], int len);
|
2022-08-07 18:46:39 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD> Bvh <20><>rootBvh<76><68><EFBFBD>֣<EFBFBD><D6A3><EFBFBD> children <20><><EFBFBD>飬<EFBFBD><E9A3AC>Χ<EFBFBD><CEA7><EFBFBD><EFBFBD><EFBFBD><EFBFBD> vector <20><><EFBFBD><EFBFBD>
|
|
|
|
|
void getBvhArray(std::vector<GLuint>& children, std::vector<QVector4D>& bounds);
|
2022-08-07 22:25:33 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD> BvhTree <20>нڵ<D0BD><DAB5><EFBFBD><EFBFBD><EFBFBD>
|
2022-08-07 18:46:39 +08:00
|
|
|
|
GLuint getBvhNodeNum();
|
|
|
|
|
};
|
|
|
|
|
|