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.
138 lines
5.5 KiB
138 lines
5.5 KiB
3 years ago
|
//
|
||
|
// Created by 14727 on 2022/12/11.
|
||
|
//
|
||
|
|
||
|
#include "../../../include/device/Nurbs/bvh.cuh"
|
||
|
/**
|
||
|
* 当前层的第一个节点的坐标
|
||
|
* @param layer 层号。根节点为第一层
|
||
|
*/
|
||
|
__device__ 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;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 根据u、v参数域中的小矩形的位置,判断它在BVH叶节点层(也就是最后一层)中的位置
|
||
|
* @param ix
|
||
|
* @param iy
|
||
|
* @return
|
||
|
*/
|
||
|
__device__ int 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
|
||
|
buildSurfaceBvh(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 = 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;
|
||
|
// AABB bound(FVec3(evaluatedPoints[tmpIdx] + *k, evaluatedPoints[tmpIdx + 1] + *k,
|
||
|
// evaluatedPoints[tmpIdx + 2] + *k)); // 最初只包含u,v点
|
||
|
AABB bound(FVec3(evaluatedPoints[tmpIdx], evaluatedPoints[tmpIdx + 1],
|
||
|
evaluatedPoints[tmpIdx + 2])); // 最初只包含u,v点
|
||
|
if(idx == 75) printf("75: %g, %g, %g\n", evaluatedPoints[tmpIdx], evaluatedPoints[tmpIdx + 1], evaluatedPoints[tmpIdx + 2]);
|
||
|
if (step == 1) {
|
||
|
// 叶子节点
|
||
|
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 tmpIdx1 = ((ix + 1) * sampleCnt_v + iy) * 3;
|
||
|
// bound = bound.Union(FVec3(evaluatedPoints[tmpIdx1] + *k, evaluatedPoints[tmpIdx1 + 1] + *k,
|
||
|
// evaluatedPoints[tmpIdx1 + 2] + *k));
|
||
|
// int tmpIdx2 = (ix * sampleCnt_v + iy + 1) * 3;
|
||
|
// bound = bound.Union(FVec3(evaluatedPoints[tmpIdx2] + *k, evaluatedPoints[tmpIdx2 + 1] + *k,
|
||
|
// evaluatedPoints[tmpIdx2 + 2] + *k));
|
||
|
// int tmpIdx3 = ((ix + 1) * sampleCnt_v + iy + 1) * 3;
|
||
|
// bound = bound.Union(FVec3(evaluatedPoints[tmpIdx3] + *k, evaluatedPoints[tmpIdx3 + 1] + *k,
|
||
|
// evaluatedPoints[tmpIdx3 + 2] + *k));
|
||
|
int tmpIdx1 = ((ix + 1) * sampleCnt_v + iy) * 3;
|
||
|
bound = bound.Union(FVec3(evaluatedPoints[tmpIdx1], evaluatedPoints[tmpIdx1 + 1],
|
||
|
evaluatedPoints[tmpIdx1 + 2]));
|
||
|
int tmpIdx2 = (ix * sampleCnt_v + iy + 1) * 3;
|
||
|
bound = bound.Union(FVec3(evaluatedPoints[tmpIdx2], evaluatedPoints[tmpIdx2 + 1],
|
||
|
evaluatedPoints[tmpIdx2 + 2]));
|
||
|
int tmpIdx3 = ((ix + 1) * sampleCnt_v + iy + 1) * 3;
|
||
|
bound = bound.Union(FVec3(evaluatedPoints[tmpIdx3], evaluatedPoints[tmpIdx3 + 1],
|
||
|
evaluatedPoints[tmpIdx3 + 2]));
|
||
|
|
||
|
BVH[idx].bounds = bound;
|
||
|
BVH[idx].childNum = -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;
|
||
|
bound = bound.Union(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();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
__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");
|
||
|
}
|
||
|
}
|