|
|
@ -2,17 +2,17 @@ |
|
|
|
// Created by 14727 on 2022/12/9. |
|
|
|
// |
|
|
|
|
|
|
|
#include "../../../include/device/Nurbs/nurbs_surface.cuh" |
|
|
|
#include "../../../include/device/Nurbs/nurbs_common.cuh" |
|
|
|
#include "../../../include/utils.h" |
|
|
|
#include "../../../include/device/Nurbs/bvh.cuh" |
|
|
|
#include "device/Nurbs/nurbs_surface.cuh" |
|
|
|
#include "device/Nurbs/nurbs_common.cuh" |
|
|
|
#include "utils.h" |
|
|
|
#include "device/Nurbs/bvh.cuh" |
|
|
|
#include "device/device_utils.cuh" |
|
|
|
|
|
|
|
__global__ void |
|
|
|
NurbsSurface::g_evaluate(float *res, const float *d_nTexture_u, const float *d_nTexture_v, const float *d_points, |
|
|
|
int d_pointsCnt_u, |
|
|
|
int d_pointsCnt_v, int d_POINT_SIZE, float d_lastKnot_u, float d_lastKnot_v, int d_sampleCnt_u, |
|
|
|
int d_sampleCnt_v) { |
|
|
|
|
|
|
|
// 二维grid和二维的block |
|
|
|
int ix = blockIdx.x * blockDim.x + threadIdx.x; |
|
|
|
int iy = blockIdx.y * blockDim.y + threadIdx.y; |
|
|
@ -51,7 +51,7 @@ NurbsSurface::g_evaluate(float *res, const float *d_nTexture_u, const float *d_n |
|
|
|
|
|
|
|
|
|
|
|
__global__ void |
|
|
|
NurbsSurface::g_derivative(float *derivatives, const float *derTexture_u, const float *derTexture_v, |
|
|
|
NurbsSurface::g_derivative(float *derivatives, float *normals, const float *derTexture_u, const float *derTexture_v, |
|
|
|
const float *nTexture_u, const float *nTexture_v, const float *d_points, int d_pointsCnt_u, |
|
|
|
int d_pointsCnt_v, int d_POINT_SIZE, float d_lastKnot_u, float d_lastKnot_v, |
|
|
|
int d_sampleCnt_u, int d_sampleCnt_v) { |
|
|
@ -118,12 +118,16 @@ NurbsSurface::g_derivative(float *derivatives, const float *derTexture_u, const |
|
|
|
derivatives[baseIdx + 4] = pdy_v; |
|
|
|
derivatives[baseIdx + 5] = pdz_v; |
|
|
|
|
|
|
|
float x_n = pdy_u * pdz_v - pdy_v * pdz_u, y_n = pdx_v * pdz_u - pdx_u * pdz_v, z_n = |
|
|
|
pdx_u * pdy_v - pdx_v * pdy_u; // 叉乘得到法向量 |
|
|
|
if ((ix == 8 && iy == 9) || (ix == 7 && iy == 9) || (ix == 9 && iy == 9) || (ix == 8 && iy == 8) || |
|
|
|
(ix == 8 && iy == 10)) |
|
|
|
printf("(%g,%g)-->u:(%g, %g, %g), v:(%g,%g,%g), normal:(%g,%g,%g)\n", u, v, pdx_u, pdy_u, pdz_u, pdx_v, pdy_v, |
|
|
|
pdz_v, x_n, y_n, z_n); |
|
|
|
// 叉乘得到法向量 |
|
|
|
baseIdx = (ix * d_sampleCnt_v + iy) * 3; |
|
|
|
normals[baseIdx] = pdy_u * pdz_v - pdy_v * pdz_u; |
|
|
|
normals[baseIdx + 1] = pdx_v * pdz_u - pdx_u * pdz_v; |
|
|
|
normals[baseIdx + 2] = pdx_u * pdy_v - pdx_v * pdy_u; |
|
|
|
normalization(normals[baseIdx], normals[baseIdx + 1], normals[baseIdx + 2]); |
|
|
|
// if ((ix == 8 && iy == 9) || (ix == 7 && iy == 9) || (ix == 9 && iy == 9) || (ix == 8 && iy == 8) || |
|
|
|
// (ix == 8 && iy == 10)) |
|
|
|
// printf("(%g,%g)-->u:(%g, %g, %g), v:(%g,%g,%g), normal:(%g,%g,%g)\n", u, v, pdx_u, pdy_u, pdz_u, pdx_v, pdy_v, |
|
|
|
// pdz_v, normals[baseIdx], normals[baseIdx + 1], normals[baseIdx + 2]); |
|
|
|
} |
|
|
|
|
|
|
|
__global__ void |
|
|
@ -210,20 +214,18 @@ NurbsSurface::g_curvature(const float *derivatives, const int sampleCnt_u, const |
|
|
|
// normalization(uvx, uvy, uvz); |
|
|
|
// normalization(sndPdx_vv, sndPdy_vv, sndPdz_vv); |
|
|
|
|
|
|
|
|
|
|
|
if (ix == 8 && iy == 9) { |
|
|
|
printf("(%g, %g) --> uu: (%g, %g, %g), uv: (%g, %g, %g), vv: (%g, %g, %g)\n", u, v, sndPdx_uu, sndPdy_uu, |
|
|
|
sndPdz_uu, |
|
|
|
uvx, uvy, uvz, sndPdx_vv, sndPdy_vv, sndPdz_vv); |
|
|
|
printf("uv: (%g, %g, %g), vu: (%g, %g, %g)\n", sndPdx_uv, sndPdy_uv, sndPdz_uv, sndPdx_vu, sndPdy_vu, |
|
|
|
sndPdz_vu); |
|
|
|
} |
|
|
|
// if (ix == 8 && iy == 9) { |
|
|
|
// printf("(%g, %g) --> uu: (%g, %g, %g), uv: (%g, %g, %g), vv: (%g, %g, %g)\n", u, v, sndPdx_uu, sndPdy_uu, |
|
|
|
// sndPdz_uu, |
|
|
|
// uvx, uvy, uvz, sndPdx_vv, sndPdy_vv, sndPdz_vv); |
|
|
|
// printf("uv: (%g, %g, %g), vu: (%g, %g, %g)\n", sndPdx_uv, sndPdy_uv, sndPdz_uv, sndPdx_vu, sndPdy_vu, |
|
|
|
// sndPdz_vu); |
|
|
|
// } |
|
|
|
|
|
|
|
float m1 = max(max(sndPdx_uu, sndPdy_uu), sndPdz_uu); |
|
|
|
float m2 = max(max(uvx, uvy), uvz); |
|
|
|
float m3 = max(max(sndPdx_vv, sndPdy_vv), sndPdz_vv); |
|
|
|
|
|
|
|
|
|
|
|
// __shared__ float ms[363]; |
|
|
|
ms[(ix * sampleCnt_v + iy) * 3] = m1; |
|
|
|
ms[(ix * sampleCnt_v + iy) * 3 + 1] = m2; |
|
|
@ -280,6 +282,7 @@ __host__ NurbsSurface::Surface::Surface(std::vector<std::vector<std::vector<floa |
|
|
|
d_evaluationRes = nullptr; |
|
|
|
d_derivatives = nullptr; |
|
|
|
d_k = nullptr; |
|
|
|
d_normals = nullptr; |
|
|
|
bvh.nodes = nullptr; |
|
|
|
} |
|
|
|
|
|
|
@ -342,6 +345,7 @@ NurbsSurface::Surface::evaluate(int sampleCnt_u, int sampleCnt_v) { |
|
|
|
dim3 grid((sampleCnt_u + block.x - 1) / block.x, (sampleCnt_v + block.y - 1) / block.y); |
|
|
|
// 记录用时 |
|
|
|
double time_cost_device; |
|
|
|
if (recordTime) time_cost_device = get_time(); |
|
|
|
g_basisTexture<<<gridBasis_u, blockBasis>>>(d_nTexture_u, d_nTexture1_u, d_knots_u, pointsCnt_u, knotsCnt_u, |
|
|
|
sampleCnt_u); |
|
|
|
cudaDeviceSynchronize(); |
|
|
@ -349,7 +353,6 @@ NurbsSurface::Surface::evaluate(int sampleCnt_u, int sampleCnt_v) { |
|
|
|
sampleCnt_v); |
|
|
|
cudaDeviceSynchronize(); |
|
|
|
|
|
|
|
if (recordTime) time_cost_device = get_time(); |
|
|
|
g_evaluate <<<grid, block>>>(d_evaluationRes, d_nTexture_u, d_nTexture_v, d_points, pointsCnt_u, pointsCnt_v, |
|
|
|
POINT_SIZE, |
|
|
|
knots_u[knotsCnt_u - 1], knots_v[knotsCnt_v - 1], sampleCnt_u, sampleCnt_v); |
|
|
@ -403,7 +406,12 @@ __host__ void NurbsSurface::Surface::derivative(int sampleCnt_u, int sampleCnt_v |
|
|
|
// 构造切向量计算结果 |
|
|
|
safeCudaFree(d_derivatives); |
|
|
|
cudaMalloc((void **) &d_derivatives, |
|
|
|
sampleCnt_v * sampleCnt_u * 6 * sizeof(float)); // 每个采用所求的切向量是一个六元向量,前三位是对u的偏导、后三位是对v的偏导 |
|
|
|
sampleCnt_v * sampleCnt_u * 6 * sizeof(float)); // 每个采样所求的切向量是一个六元向量,前三位是对u的偏导、后三位是对v的偏导 |
|
|
|
|
|
|
|
// 构造法向量计算结果 |
|
|
|
safeCudaFree(d_normals); |
|
|
|
cudaMalloc((void **) &d_normals, |
|
|
|
sampleCnt_v * sampleCnt_u * 3 * sizeof(float)); |
|
|
|
|
|
|
|
// 构造线程层级 |
|
|
|
dim3 block(32, 32); |
|
|
@ -420,11 +428,9 @@ __host__ void NurbsSurface::Surface::derivative(int sampleCnt_u, int sampleCnt_v |
|
|
|
g_derTexture<<<gridTex_v, blockTex>>>(d_derTexture_v, d_nTexture1_v, d_knots_v, pointsCnt_v, knotsCnt_v, |
|
|
|
sampleCnt_v); |
|
|
|
cudaDeviceSynchronize(); |
|
|
|
g_derivative<<<grid, block>>>(d_derivatives, d_derTexture_u, d_derTexture_v, d_nTexture_u, d_nTexture_v, d_points, |
|
|
|
pointsCnt_u, |
|
|
|
pointsCnt_v, POINT_SIZE, knots_u[knotsCnt_u - 1], knots_v[knotsCnt_v - 1], |
|
|
|
sampleCnt_u, |
|
|
|
sampleCnt_v); |
|
|
|
g_derivative<<<grid, block>>>(d_derivatives, d_normals, d_derTexture_u, d_derTexture_v, d_nTexture_u, d_nTexture_v, |
|
|
|
d_points, pointsCnt_u, pointsCnt_v, POINT_SIZE, knots_u[knotsCnt_u - 1], |
|
|
|
knots_v[knotsCnt_v - 1], sampleCnt_u, sampleCnt_v); |
|
|
|
cudaDeviceSynchronize(); // 所用线程结束后再获取结束时间。cudaThreadSynchronize()在CUDA1.0后被弃用 |
|
|
|
if (recordTime) { |
|
|
|
time_cost_device = get_time() - time_cost_device; |
|
|
@ -462,9 +468,8 @@ __host__ void NurbsSurface::Surface::curvature(int sampleCnt_u, int sampleCnt_v) |
|
|
|
cudaDeviceSynchronize(); // 所用线程结束后再获取结束时间。cudaThreadSynchronize()在CUDA1.0后被弃用 |
|
|
|
if (recordTime) { |
|
|
|
time_cost_device = get_time() - time_cost_device; |
|
|
|
printf("GPU time cost of surface second derivative calculating for %d samples: %lf\n", |
|
|
|
sampleCnt_u * sampleCnt_v, |
|
|
|
time_cost_device); |
|
|
|
printf("GPU time cost of surface curvature calculating for %d samples: %lf\n", |
|
|
|
sampleCnt_u * sampleCnt_v, time_cost_device); |
|
|
|
} |
|
|
|
safeCudaFree(ms); |
|
|
|
} |
|
|
@ -483,13 +488,22 @@ NurbsSurface::Surface::~Surface() { |
|
|
|
safeCudaFree(d_knots_v); |
|
|
|
safeCudaFree(d_k); |
|
|
|
safeCudaFree(d_evaluationRes); |
|
|
|
safeCudaFree(d_normals); |
|
|
|
safeCudaFree(d_derivatives); |
|
|
|
safeFree(bvh.nodes); |
|
|
|
cudaDeviceReset(); |
|
|
|
} |
|
|
|
|
|
|
|
__host__ void NurbsSurface::Surface::buildBHV(int sampleCnt_u, int sampleCnt_v) { |
|
|
|
// 先计算曲率 |
|
|
|
curvature(sampleCnt_u, sampleCnt_v); |
|
|
|
__host__ void NurbsSurface::Surface::buildBHV(int layerCnt, bool useK) { |
|
|
|
int sampleCnt_u = pow(2, layerCnt - 1) + 1, sampleCnt_v = sampleCnt_u; |
|
|
|
if (useK) { |
|
|
|
// 先计算曲率,过程中也会计算曲面值 |
|
|
|
curvature(sampleCnt_u, sampleCnt_v); |
|
|
|
} else { |
|
|
|
// 只做evaluation |
|
|
|
evaluate(sampleCnt_u, sampleCnt_v); |
|
|
|
safeCudaFree(d_k); |
|
|
|
} |
|
|
|
if (POINT_SIZE != controlPoints[0][0].size()) { |
|
|
|
printf("Error! Nurbs控制点应表示为长度为4的齐次坐标\n"); |
|
|
|
return; |
|
|
@ -498,25 +512,161 @@ __host__ void NurbsSurface::Surface::buildBHV(int sampleCnt_u, int sampleCnt_v) |
|
|
|
dim3 block(32, 32); |
|
|
|
dim3 grid((sampleCnt_u + block.x - 1) / block.x, (sampleCnt_v + block.y - 1) / block.y); |
|
|
|
|
|
|
|
bvh.maxLevel = max(int(ceil(log2f(sampleCnt_u - 1))) + 1, int(ceil(log2f(sampleCnt_v - 1))) + 1); |
|
|
|
// bvh.maxLevel = max(int(ceil(log2f(sampleCnt_u - 1))) + 1, int(ceil(log2f(sampleCnt_v - 1))) + 1); |
|
|
|
bvh.maxLevel = layerCnt; |
|
|
|
bvh.size = (pow(4, bvh.maxLevel) - 1) / 3; // 等比数列求和公示求出数总的节点数 |
|
|
|
size_t bvhBytes = sizeof(BVHNode) * bvh.size; |
|
|
|
BVHNode *d_bvh = nullptr; |
|
|
|
cudaMalloc((void **) &d_bvh, bvhBytes); |
|
|
|
// 记录用时 |
|
|
|
double time_cost_device = get_time(); |
|
|
|
buildSurfaceBvh<<<grid, block>>>(d_k, bvh.maxLevel, d_evaluationRes, knots_u[knots_u.size() - 1], |
|
|
|
knots_v[knots_v.size() - 1], sampleCnt_u, sampleCnt_v, d_bvh); |
|
|
|
double time_cost_device; |
|
|
|
if (recordTime) time_cost_device = get_time(); |
|
|
|
buildBvh<<<grid, block>>>(d_k, bvh.maxLevel, d_evaluationRes, knots_u[knots_u.size() - 1], |
|
|
|
knots_v[knots_v.size() - 1], sampleCnt_u, sampleCnt_v, d_bvh); |
|
|
|
cudaDeviceSynchronize(); |
|
|
|
if (recordTime) { |
|
|
|
time_cost_device = get_time() - time_cost_device; |
|
|
|
printf("GPU time cost of surface second derivative calculating for %d samples: %lf\n", |
|
|
|
sampleCnt_u * sampleCnt_v, |
|
|
|
time_cost_device); |
|
|
|
printf("GPU time cost of a %d-layer BVH building: %lf\n", |
|
|
|
bvh.maxLevel, time_cost_device); |
|
|
|
} |
|
|
|
if (bvh.nodes == nullptr) bvh.nodes = (BVHNode *) malloc(bvhBytes); |
|
|
|
safeFree(bvh.nodes); |
|
|
|
bvh.nodes = (BVHNode *) malloc(bvhBytes); |
|
|
|
cudaMemcpy(bvh.nodes, d_bvh, bvhBytes, cudaMemcpyDeviceToHost); |
|
|
|
safeCudaFree(d_bvh); |
|
|
|
|
|
|
|
// bvh.printQuadTree(); |
|
|
|
} |
|
|
|
|
|
|
|
__host__ void NurbsSurface::Surface::buildGaussMap(int layerCnt) { |
|
|
|
int sampleCnt_u = pow(2, layerCnt - 1) + 1, sampleCnt_v = sampleCnt_u; |
|
|
|
// 先计算法向量 |
|
|
|
derivative(sampleCnt_u, sampleCnt_v); |
|
|
|
if (POINT_SIZE != controlPoints[0][0].size()) { |
|
|
|
printf("Error! Nurbs控制点应表示为长度为4的齐次坐标\n"); |
|
|
|
return; |
|
|
|
} |
|
|
|
// 构造线程层级 |
|
|
|
dim3 block(32, 32); |
|
|
|
dim3 grid((sampleCnt_u + block.x - 1) / block.x, (sampleCnt_v + block.y - 1) / block.y); |
|
|
|
|
|
|
|
gauss_map.maxLevel = layerCnt; |
|
|
|
gauss_map.size = (pow(4, layerCnt) - 1) / 3; // 等比数列求和公示求出数总的节点数 |
|
|
|
size_t gaussMapBytes = sizeof(BVHNode) * gauss_map.size; |
|
|
|
BVHNode *d_gaussMapTree = nullptr; |
|
|
|
cudaMalloc((void **) &d_gaussMapTree, gaussMapBytes); |
|
|
|
// 记录用时 |
|
|
|
double time_cost_device; |
|
|
|
if (recordTime) time_cost_device = get_time(); |
|
|
|
buildBvh<<<grid, block>>>(nullptr, layerCnt, d_normals, knots_u[knots_u.size() - 1], |
|
|
|
knots_v[knots_v.size() - 1], sampleCnt_u, sampleCnt_v, d_gaussMapTree); |
|
|
|
cudaDeviceSynchronize(); |
|
|
|
if (recordTime) { |
|
|
|
time_cost_device = get_time() - time_cost_device; |
|
|
|
printf("GPU time cost of a %d-layer Gauss Map building: %lf\n", |
|
|
|
layerCnt, time_cost_device); |
|
|
|
} |
|
|
|
safeFree(gauss_map.nodes); |
|
|
|
gauss_map.nodes = (BVHNode *) malloc(gaussMapBytes); |
|
|
|
cudaMemcpy(gauss_map.nodes, d_gaussMapTree, gaussMapBytes, cudaMemcpyDeviceToHost); |
|
|
|
safeCudaFree(d_gaussMapTree); |
|
|
|
} |
|
|
|
|
|
|
|
__host__ void NurbsSurface::recursiveGetOverlapLeafNodes(const BVH &bvh1, const BVH &bvh2, int idx1, int idx2, |
|
|
|
std::vector<std::pair<int, int>> &pairs) { |
|
|
|
auto A = bvh1.nodes[idx1]; |
|
|
|
auto B = bvh2.nodes[idx2]; |
|
|
|
auto AABBSize = [](const AABB &aabb) { |
|
|
|
return (aabb.pMax.z - aabb.pMin.z) * |
|
|
|
(aabb.pMax.y - aabb.pMin.y) * |
|
|
|
(aabb.pMax.x - aabb.pMin.x); |
|
|
|
}; |
|
|
|
// 两个包围盒不相交,返回 |
|
|
|
if (!A.bounds.IsOverlap(B.bounds)) return; |
|
|
|
// 相交 |
|
|
|
if (A.firstChild == -1 && B.firstChild == -1) { |
|
|
|
// 两者都是叶子节点 |
|
|
|
pairs.emplace_back(idx1, idx2); |
|
|
|
} else if (A.firstChild != -1 && B.firstChild == -1) { |
|
|
|
// A是中间结点,B是叶子结点 |
|
|
|
for (int i = 0; i < 4; i++) recursiveGetOverlapLeafNodes(bvh1, bvh2, A.firstChild + i, idx2, pairs); |
|
|
|
} else if (A.firstChild == -1 && B.firstChild != -1) { |
|
|
|
// A是叶子结点,B是中间结点 |
|
|
|
for (int i = 0; i < 4; i++) recursiveGetOverlapLeafNodes(bvh1, bvh2, idx1, B.firstChild + i, pairs); |
|
|
|
} else { |
|
|
|
// 都是中间结点 |
|
|
|
if (AABBSize(A.bounds) > AABBSize(B.bounds)) { |
|
|
|
// A的包围盒更大 |
|
|
|
for (int i = 0; i < 4; i++) recursiveGetOverlapLeafNodes(bvh1, bvh2, A.firstChild + i, idx2, pairs); |
|
|
|
} else { |
|
|
|
// B的包围盒更大 |
|
|
|
for (int i = 0; i < 4; i++) recursiveGetOverlapLeafNodes(bvh1, bvh2, idx1, B.firstChild + i, pairs); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
__host__ std::vector<std::pair<int, int>> |
|
|
|
NurbsSurface::getOverlappedLeafNodes(const BVH &bvh1, const BVH &bvh2) { |
|
|
|
std::vector<std::pair<int, int>> resPairs; |
|
|
|
// 记录用时 |
|
|
|
double time_cost_device = get_time(); |
|
|
|
recursiveGetOverlapLeafNodes(bvh1, bvh2, 0, 0, resPairs); |
|
|
|
time_cost_device = get_time() - time_cost_device; |
|
|
|
printf("CPU time cost for recursively calculating the overlapped leaf nodes: %lf\n", time_cost_device); |
|
|
|
|
|
|
|
return resPairs; |
|
|
|
} |
|
|
|
|
|
|
|
__host__ bool |
|
|
|
NurbsSurface::isGaussMapsOverlapped(const BVH &gm1, const BVH &gm2, std::pair<int, int> idxRange_u1, |
|
|
|
std::pair<int, int> idxRange_v1, std::pair<int, int> idxRange_u2, |
|
|
|
std::pair<int, int> idxRange_v2) { |
|
|
|
if (gm1.maxLevel != gm2.maxLevel || gm1.maxLevel <= 0) { |
|
|
|
printf("BVH Layer error!\n"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
int commonMaxLayer = gm1.maxLevel; |
|
|
|
int edgeCellCnt = pow(2, commonMaxLayer - 1); |
|
|
|
if (idxRange_u1.first < 0 || idxRange_u2.first < 0 || idxRange_v1.first < 0 || idxRange_v2.first < 0 || |
|
|
|
idxRange_u1.second >= edgeCellCnt || idxRange_u2.second >= edgeCellCnt || |
|
|
|
idxRange_v1.second >= edgeCellCnt || idxRange_v2.second >= edgeCellCnt) { |
|
|
|
printf("Error when detecting overlapping: idx range invalid!\n"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
auto getRangedBox = [&commonMaxLayer](const BVH &bvh, const std::pair<int, int> &idxRange_u, |
|
|
|
const std::pair<int, int> idxRange_v) { |
|
|
|
AABB bounding; |
|
|
|
for (int i = idxRange_u.first; i <= idxRange_u.second; ++i) { |
|
|
|
for (int j = idxRange_v.first; j <= idxRange_v.second; ++j) { |
|
|
|
bounding = bounding.Union( |
|
|
|
bvh.nodes[getStartIdxOfLayerN(commonMaxLayer) + h_getChildNodeIdx(i, j)].bounds); |
|
|
|
} |
|
|
|
} |
|
|
|
return bounding; |
|
|
|
}; |
|
|
|
return getRangedBox(gm1, idxRange_u1, idxRange_v1) |
|
|
|
.IsOverlap(getRangedBox(gm2, idxRange_u2, idxRange_v2)); |
|
|
|
} |
|
|
|
|
|
|
|
__host__ bool NurbsSurface::isGaussMapsOverlapped(const BVH &gm1, const BVH &gm2, std::pair<float, float> range_u1, |
|
|
|
std::pair<float, float> range_v1, std::pair<float, float> range_u2, |
|
|
|
std::pair<float, float> range_v2, |
|
|
|
std::pair<float, float> paramRange_u1, |
|
|
|
std::pair<float, float> paramRange_v1, |
|
|
|
std::pair<float, float> paramRange_u2, |
|
|
|
std::pair<float, float> paramRange_v2) { |
|
|
|
if (gm1.maxLevel != gm2.maxLevel || gm1.maxLevel <= 0) { |
|
|
|
printf("BVH Layer error!\n"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
int edgeCellCnt = pow(2, gm1.maxLevel - 1); |
|
|
|
// 根据所给参数的范围和参数的定义域范围,获得对应的采样网格中的范围 |
|
|
|
auto getIdxRange = [](std::pair<float, float> range, std::pair<float, float> paramRange, int edgeCellCnt) { |
|
|
|
float paramStep = (paramRange.second - paramRange.first) / edgeCellCnt; |
|
|
|
return std::pair<int, int>({int((range.first - paramRange.first) / paramStep), |
|
|
|
int((range.second - paramRange.first) / paramStep)}); |
|
|
|
}; |
|
|
|
auto idxRange_u1 = getIdxRange(range_u1, paramRange_u1, edgeCellCnt); |
|
|
|
auto idxRange_v1 = getIdxRange(range_v1, paramRange_v1, edgeCellCnt); |
|
|
|
auto idxRange_u2 = getIdxRange(range_u2, paramRange_u2, edgeCellCnt); |
|
|
|
auto idxRange_v2 = getIdxRange(range_v2, paramRange_v2, edgeCellCnt); |
|
|
|
return isGaussMapsOverlapped(gm1, gm2, idxRange_u1, idxRange_v1, idxRange_u2, idxRange_v2); |
|
|
|
} |
|
|
|