You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
143 lines
5.3 KiB
143 lines
5.3 KiB
//
|
|
// Created by 14727 on 2022/12/11.
|
|
//
|
|
|
|
#include "device/Nurbs/bvh.cuh"
|
|
|
|
__device__ __host__ int getStartIdxOfLayerN(int layer) {
|
|
if (layer == 1) return 0;
|
|
int num = 1;
|
|
// 找规律得出
|
|
for (int i = 2; i < layer; i++) {
|
|
num = num * 4 + 1;
|
|
}
|
|
return num;
|
|
}
|
|
|
|
__device__ int d_getChildNodeIdx(int ix, int iy) {
|
|
int idx = 0;
|
|
while(ix > 0) {
|
|
int log2XCeil = int(__log2f(ix));
|
|
idx += int(pow(4, log2XCeil));
|
|
ix -= int(pow(2, log2XCeil));
|
|
}
|
|
while(iy > 0) {
|
|
int log2XCeil = int(__log2f(iy));
|
|
idx += 2 * int(pow(4, log2XCeil));
|
|
iy -= int(pow(2, log2XCeil));
|
|
}
|
|
return idx;
|
|
}
|
|
|
|
__host__ int h_getChildNodeIdx(int ix, int iy){
|
|
int idx = 0;
|
|
while(ix > 0) {
|
|
int log2XCeil = int(log2f(ix));
|
|
idx += int(pow(4, log2XCeil));
|
|
ix -= int(pow(2, log2XCeil));
|
|
}
|
|
while(iy > 0) {
|
|
int log2XCeil = int(log2f(iy));
|
|
idx += 2 * int(pow(4, log2XCeil));
|
|
iy -= int(pow(2, log2XCeil));
|
|
}
|
|
return idx;
|
|
}
|
|
|
|
__global__ void
|
|
g_buildBvh(const float *k, int level, const float *evaluatedPoints, float lastKnot_u, float lastKnot_v,
|
|
int sampleCnt_u, int sampleCnt_v, BVHNode *BVH) {
|
|
// 假设还是二维grid和二维的block
|
|
int ix = blockIdx.x * blockDim.x + threadIdx.x;
|
|
int iy = blockIdx.y * blockDim.y + threadIdx.y;
|
|
if (ix >= sampleCnt_u - 1 || iy >= sampleCnt_v - 1) {
|
|
return;
|
|
}
|
|
float singleStepVal_u = lastKnot_u / (sampleCnt_u - 1);
|
|
float singleStepVal_v = lastKnot_v / (sampleCnt_v - 1);
|
|
|
|
float u = singleStepVal_u * ix, v = singleStepVal_v * iy;
|
|
|
|
int bias = d_getChildNodeIdx(ix, iy); // 每层的节点在总数组中的编号相对该层第一个节点的偏置
|
|
for (int step = 1; step <= sampleCnt_u - 1 || step <= sampleCnt_v - 1; step = step * 2, --level) {
|
|
|
|
float step_u = min(step, sampleCnt_u - 1);
|
|
float step_v = min(step, sampleCnt_v - 1);
|
|
|
|
int baseIdx = getStartIdxOfLayerN(level); // 当前层的第一个节点的坐标
|
|
int idx = baseIdx + bias;
|
|
|
|
int tmpIdx = (ix * sampleCnt_v + iy) * 3;
|
|
|
|
// if(idx == 75) printf("75: %g, %g, %g\n", evaluatedPoints[tmpIdx], evaluatedPoints[tmpIdx + 1], evaluatedPoints[tmpIdx + 2]);
|
|
if (step == 1) {
|
|
AABB bound(glm::vec3(evaluatedPoints[tmpIdx], evaluatedPoints[tmpIdx + 1],
|
|
evaluatedPoints[tmpIdx + 2])); // 最初只包含u,v点
|
|
// 叶子节点
|
|
BVH[idx].u0 = u;
|
|
BVH[idx].u1 = u + step_u * singleStepVal_u;
|
|
BVH[idx].v0 = v;
|
|
BVH[idx].v1 = v + step_v * singleStepVal_v;
|
|
BVH[idx].idx_u = ix;
|
|
BVH[idx].idx_v = iy;
|
|
BVH[idx].level = level;
|
|
int tmpIdx1 = ((ix + 1) * sampleCnt_v + iy) * 3;
|
|
int tmpIdx2 = (ix * sampleCnt_v + iy + 1) * 3;
|
|
int tmpIdx3 = ((ix + 1) * sampleCnt_v + iy + 1) * 3;
|
|
bound = bound.Union(glm::vec3(evaluatedPoints[tmpIdx1], evaluatedPoints[tmpIdx1 + 1],
|
|
evaluatedPoints[tmpIdx1 + 2]));
|
|
bound = bound.Union(glm::vec3(evaluatedPoints[tmpIdx2], evaluatedPoints[tmpIdx2 + 1],
|
|
evaluatedPoints[tmpIdx2 + 2]));
|
|
bound = bound.Union(glm::vec3(evaluatedPoints[tmpIdx3], evaluatedPoints[tmpIdx3 + 1],
|
|
evaluatedPoints[tmpIdx3 + 2]));
|
|
if(k != nullptr) bound.expand(*k);
|
|
BVH[idx].bounds = bound;
|
|
BVH[idx].firstChild = -1;
|
|
} else {
|
|
if (ix % step == 0 || iy % step == 0) {
|
|
|
|
// 非叶子节点
|
|
BVH[idx].u0 = u;
|
|
BVH[idx].u1 = u + step_u * singleStepVal_u;
|
|
BVH[idx].v0 = v;
|
|
BVH[idx].v1 = v + step_v * singleStepVal_v;
|
|
BVH[idx].level = level;
|
|
|
|
int firstChild = 4 * idx + 1;
|
|
AABB bound(BVH[firstChild].bounds);
|
|
bound = bound.Union(BVH[firstChild + 1].bounds);
|
|
bound = bound.Union(BVH[firstChild + 2].bounds);
|
|
bound = bound.Union(BVH[firstChild + 3].bounds);
|
|
BVH[idx].firstChild = firstChild;
|
|
BVH[idx].bounds = bound;
|
|
}
|
|
}
|
|
|
|
bias /= 4;
|
|
|
|
__syncthreads();
|
|
}
|
|
}
|
|
|
|
__global__ void getOverlapLeafNodes(const float *k, int level, const float *evaluatedPoints, float lastKnot_u, float lastKnot_v,
|
|
int sampleCnt_u, int sampleCnt_v, BVHNode *BVH){
|
|
// 假设还是二维grid和二维的block
|
|
// int ix = blockIdx.x * blockDim.x + threadIdx.x;
|
|
// int iy = blockIdx.y * blockDim.y + threadIdx.y;
|
|
// if (ix >= sampleCnt_u - 1 || iy >= sampleCnt_v - 1) {
|
|
// return;
|
|
// }
|
|
}
|
|
|
|
__host__ void BVH::printQuadTree() {
|
|
|
|
for (int l = 1, levelNodesCnt = 1, baseIdx = 0; l <= maxLevel; l++, levelNodesCnt *= 4, baseIdx = baseIdx * 4 + 1) {
|
|
for (int biasIdx = 0; biasIdx < levelNodesCnt; biasIdx++) {
|
|
int idx = baseIdx + biasIdx;
|
|
auto pMax = nodes[idx].bounds.pMax;
|
|
auto pMin = nodes[idx].bounds.pMin;
|
|
printf("<<%g, %g, %g>,<%g, %g, %g>> ", pMin.x, pMin.y, pMin.z, pMax.x, pMax.y, pMax.z);
|
|
}
|
|
printf("\n =============$$$$$$$============= \n");
|
|
}
|
|
}
|
|
|