本文整理汇总了C++中NodeRef::node方法的典型用法代码示例。如果您正苦于以下问题:C++ NodeRef::node方法的具体用法?C++ NodeRef::node怎么用?C++ NodeRef::node使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类NodeRef
的用法示例。
在下文中一共展示了NodeRef::node方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: if
__m256 BVH2Intersector8Chunk<TriangleIntersector>::occluded(const BVH2Intersector8Chunk* This, Ray8& ray, const __m256 valid_i)
{
avxb valid = valid_i;
avxb terminated = !valid;
const BVH2* bvh = This->bvh;
STAT3(shadow.travs,1,popcnt(valid),8);
NodeRef stack[1+BVH2::maxDepth]; //!< stack of nodes that still need to get traversed
NodeRef* stackPtr = stack; //!< current stack pointer
NodeRef cur = bvh->root; //!< in cur we track the ID of the current node
/* let inactive rays miss all boxes */
const avx3f rdir = rcp_safe(ray.dir);
avxf rayFar = select(terminated,avxf(neg_inf),ray.tfar);
while (true)
{
/*! downtraversal loop */
while (likely(cur.isNode()))
{
STAT3(normal.trav_nodes,1,popcnt(valid),8);
/* intersect packet with box of both children */
const Node* node = cur.node();
const size_t hit0 = intersectBox(ray.org,rdir,ray.tnear,rayFar,node,0);
const size_t hit1 = intersectBox(ray.org,rdir,ray.tnear,rayFar,node,1);
/*! if two children are hit push both onto stack */
if (likely(hit0 != 0 && hit1 != 0)) {
*stackPtr = node->child(0); stackPtr++; cur = node->child(1);
}
/*! if one child hit, continue with that child */
else {
if (likely(hit0 != 0)) cur = node->child(0);
else if (likely(hit1 != 0)) cur = node->child(1);
else goto pop_node;
}
}
/*! leaf node, intersect all triangles */
{
STAT3(shadow.trav_leaves,1,popcnt(valid),8);
size_t num; Triangle* tri = (Triangle*) cur.leaf(NULL,num);
for (size_t i=0; i<num; i++) {
terminated |= TriangleIntersector::occluded(valid,ray,tri[i],bvh->vertices);
if (all(terminated)) return terminated;
}
/* let terminated rays miss all boxes */
rayFar = select(terminated,avxf(neg_inf),rayFar);
}
/*! pop next node from stack */
pop_node:
if (unlikely(stackPtr == stack)) break;
cur = *(--stackPtr);
}
return terminated;
}
示例2: if
void BVHN<N>::clearBarrier(NodeRef& node)
{
if (node.isBarrier())
node.clearBarrier();
else if (!node.isLeaf()) {
Node* n = node.node();
for (size_t c=0; c<N; c++)
clearBarrier(n->child(c));
}
}
示例3: if
BVH4::NodeRef BVH4::layoutLargeNodesRecursion(NodeRef& node)
{
if (node.isBarrier()) {
node.clearBarrier();
return node;
}
else if (node.isNode())
{
Node* oldnode = node.node();
Node* newnode = (BVH4::Node*) alloc.threadLocal2()->alloc0.malloc(sizeof(BVH4::Node)); // FIXME: optimize access to threadLocal2
*newnode = *oldnode;
for (size_t c=0; c<BVH4::N; c++)
newnode->child(c) = layoutLargeNodesRecursion(oldnode->child(c));
return encodeNode(newnode);
}
else return node;
}
示例4: area
float BVH4i::sah (NodeRef& node, const BBox3f& bounds)
{
float f = bounds.empty() ? 0.0f : area(bounds);
if (node.isNode())
{
Node* n = node.node(nodePtr());
for (size_t c=0; c<4; c++)
f += sah(n->child(c),n->bounds(c));
return f;
}
else
{
size_t num; node.leaf(triPtr(),num);
return f*num;
}
}
示例5: area
float BVH4i::sah (NodeRef& node, BBox3fa bounds)
{
float f = bounds.empty() ? 0.0f : area(bounds);
if (node.isNode())
{
Node* n = node.node(nodePtr());
for (size_t c=0; c<BVH4i::N; c++)
if (n->child(c) != BVH4i::invalidNode)
f += sah(n->child(c),n->bounds(c));
return f;
}
else
{
unsigned int num; node.leaf(triPtr(),num);
return f*num;
}
}
示例6: runtime_error
void BVH4Statistics::statistics(NodeRef node, const BBox3fa& bounds, size_t& depth)
{
float A = bounds.empty() ? 0.0f : area(bounds);
if (node.isNode())
{
numNodes++;
depth = 0;
size_t cdepth = 0;
Node* n = node.node();
bvhSAH += A*BVH4::travCost;
for (size_t i=0; i<BVH4::N; i++) {
statistics(n->child(i),n->bounds(i),cdepth);
depth=max(depth,cdepth);
}
for (size_t i=0; i<BVH4::N; i++) {
if (n->child(i) == BVH4::emptyNode) {
for (; i<BVH4::N; i++) {
if (n->child(i) != BVH4::emptyNode)
throw std::runtime_error("invalid node");
}
break;
}
}
depth++;
return;
}
else
{
depth = 0;
size_t num; const char* tri = node.leaf(num);
if (!num) return;
numLeaves++;
numPrimBlocks += num;
for (size_t i=0; i<num; i++) {
numPrims += bvh->primTy.size(tri+i*bvh->primTy.bytes);
}
float sah = A * bvh->primTy.intCost * num;
bvhSAH += sah;
leafSAH += sah;
}
}
示例7: rayNear
__forceinline void BVH8iIntersector8Hybrid<TriangleIntersector8>::intersect1(const BVH8i* bvh, NodeRef root, const size_t k, Ray8& ray,const avx3f &ray_org, const avx3f &ray_dir, const avx3f &ray_rdir, const avxf &ray_tnear, const avxf &ray_tfar, const avx3i& nearXYZ)
{
/*! stack state */
StackItemInt64 stack[stackSizeSingle]; //!< stack of nodes
StackItemInt64* stackPtr = stack+1; //!< current stack pointer
StackItemInt64* stackEnd = stack+stackSizeSingle;
stack[0].ptr = root;
stack[0].dist = neg_inf;
/*! offsets to select the side that becomes the lower or upper bound */
const size_t nearX = nearXYZ.x[k];
const size_t nearY = nearXYZ.y[k];
const size_t nearZ = nearXYZ.z[k];
/*! load the ray into SIMD registers */
const avx3f org (ray_org .x[k],ray_org .y[k],ray_org .z[k]);
const avx3f rdir(ray_rdir.x[k],ray_rdir.y[k],ray_rdir.z[k]);
const avx3f org_rdir(org*rdir);
avxf rayNear(ray_tnear[k]), rayFar(ray_tfar[k]);
const Node * __restrict__ nodes = (Node *)bvh->nodePtr();
const Triangle * __restrict__ accel = (Triangle*)bvh->triPtr();
/* pop loop */
while (true) pop:
{
/*! pop next node */
if (unlikely(stackPtr == stack)) break;
stackPtr--;
NodeRef cur = NodeRef(stackPtr->ptr);
/*! if popped node is too far, pop next one */
if (unlikely(*(float*)&stackPtr->dist > ray.tfar[k]))
continue;
/* downtraversal loop */
while (true)
{
/*! stop if we found a leaf */
if (unlikely(cur.isLeaf())) break;
STAT3(normal.trav_nodes,1,1,1);
/*! single ray intersection with 4 boxes */
const Node* node = (Node*)cur.node(nodes);
const size_t farX = nearX ^ sizeof(avxf), farY = nearY ^ sizeof(avxf), farZ = nearZ ^ sizeof(avxf);
#if defined (__AVX2__)
const avxf tNearX = msub(load8f((const char*)node+nearX), rdir.x, org_rdir.x);
const avxf tNearY = msub(load8f((const char*)node+nearY), rdir.y, org_rdir.y);
const avxf tNearZ = msub(load8f((const char*)node+nearZ), rdir.z, org_rdir.z);
const avxf tFarX = msub(load8f((const char*)node+farX ), rdir.x, org_rdir.x);
const avxf tFarY = msub(load8f((const char*)node+farY ), rdir.y, org_rdir.y);
const avxf tFarZ = msub(load8f((const char*)node+farZ ), rdir.z, org_rdir.z);
#else
const avxf tNearX = (load8f((const char*)node+nearX) - org.x) * rdir.x;
const avxf tNearY = (load8f((const char*)node+nearY) - org.y) * rdir.y;
const avxf tNearZ = (load8f((const char*)node+nearZ) - org.z) * rdir.z;
const avxf tFarX = (load8f((const char*)node+farX ) - org.x) * rdir.x;
const avxf tFarY = (load8f((const char*)node+farY ) - org.y) * rdir.y;
const avxf tFarZ = (load8f((const char*)node+farZ ) - org.z) * rdir.z;
#endif
#if defined(__AVX2__)
const avxf tNear = maxi(maxi(tNearX,tNearY),maxi(tNearZ,rayNear));
const avxf tFar = mini(mini(tFarX ,tFarY ),mini(tFarZ ,rayFar ));
const avxb vmask = cast(tNear) > cast(tFar);
unsigned int mask = movemask(vmask)^0xff;
#else
const avxf tNear = max(tNearX,tNearY,tNearZ,rayNear);
const avxf tFar = min(tFarX ,tFarY ,tFarZ ,rayFar);
const avxb vmask = tNear <= tFar;
unsigned int mask = movemask(vmask);
#endif
/*! if no child is hit, pop next node */
if (unlikely(mask == 0))
goto pop;
/*! one child is hit, continue with that child */
size_t r = __bscf(mask);
if (likely(mask == 0)) {
cur = node->child(r);
assert(cur != BVH4i::emptyNode);
continue;
}
/*! two children are hit, push far child, and continue with closer child */
NodeRef c0 = node->child(r); const unsigned int d0 = ((unsigned int*)&tNear)[r];
r = __bscf(mask);
NodeRef c1 = node->child(r); const unsigned int d1 = ((unsigned int*)&tNear)[r];
assert(c0 != BVH4i::emptyNode);
assert(c1 != BVH4i::emptyNode);
if (likely(mask == 0)) {
assert(stackPtr < stackEnd);
if (d0 < d1) { stackPtr->ptr = c1; stackPtr->dist = d1; stackPtr++; cur = c0; continue; }
else { stackPtr->ptr = c0; stackPtr->dist = d0; stackPtr++; cur = c1; continue; }
}
/*! Here starts the slow path for 3 or 4 hit children. We push
* all nodes onto the stack to sort them there. */
assert(stackPtr < stackEnd);
//.........这里部分代码省略.........
示例8: pre
void BVH4Intersector4Chunk<PrimitiveIntersector4>::intersect(sseb* valid_i, BVH4* bvh, Ray4& ray)
{
/* load ray */
const sseb valid0 = *valid_i;
const sse3f rdir = rcp_safe(ray.dir);
const sse3f org(ray.org), org_rdir = org * rdir;
ssef ray_tnear = select(valid0,ray.tnear,ssef(pos_inf));
ssef ray_tfar = select(valid0,ray.tfar ,ssef(neg_inf));
const ssef inf = ssef(pos_inf);
Precalculations pre(valid0,ray);
/* allocate stack and push root node */
ssef stack_near[stackSize];
NodeRef stack_node[stackSize];
stack_node[0] = BVH4::invalidNode;
stack_near[0] = inf;
stack_node[1] = bvh->root;
stack_near[1] = ray_tnear;
NodeRef* stackEnd = stack_node+stackSize;
NodeRef* __restrict__ sptr_node = stack_node + 2;
ssef* __restrict__ sptr_near = stack_near + 2;
while (1)
{
/* pop next node from stack */
assert(sptr_node > stack_node);
sptr_node--;
sptr_near--;
NodeRef curNode = *sptr_node;
if (unlikely(curNode == BVH4::invalidNode)) {
assert(sptr_node == stack_node);
break;
}
/* cull node if behind closest hit point */
ssef curDist = *sptr_near;
if (unlikely(none(ray_tfar > curDist)))
continue;
while (1)
{
/* test if this is a leaf node */
if (unlikely(curNode.isLeaf()))
break;
const sseb valid_node = ray_tfar > curDist;
STAT3(normal.trav_nodes,1,popcnt(valid_node),4);
const Node* __restrict__ const node = curNode.node();
/* pop of next node */
assert(sptr_node > stack_node);
sptr_node--;
sptr_near--;
curNode = *sptr_node;
curDist = *sptr_near;
#pragma unroll(4)
for (unsigned i=0; i<BVH4::N; i++)
{
const NodeRef child = node->children[i];
if (unlikely(child == BVH4::emptyNode)) break;
#if defined(__AVX2__)
const ssef lclipMinX = msub(node->lower_x[i],rdir.x,org_rdir.x);
const ssef lclipMinY = msub(node->lower_y[i],rdir.y,org_rdir.y);
const ssef lclipMinZ = msub(node->lower_z[i],rdir.z,org_rdir.z);
const ssef lclipMaxX = msub(node->upper_x[i],rdir.x,org_rdir.x);
const ssef lclipMaxY = msub(node->upper_y[i],rdir.y,org_rdir.y);
const ssef lclipMaxZ = msub(node->upper_z[i],rdir.z,org_rdir.z);
#else
const ssef lclipMinX = (node->lower_x[i] - org.x) * rdir.x;
const ssef lclipMinY = (node->lower_y[i] - org.y) * rdir.y;
const ssef lclipMinZ = (node->lower_z[i] - org.z) * rdir.z;
const ssef lclipMaxX = (node->upper_x[i] - org.x) * rdir.x;
const ssef lclipMaxY = (node->upper_y[i] - org.y) * rdir.y;
const ssef lclipMaxZ = (node->upper_z[i] - org.z) * rdir.z;
#endif
#if defined(__SSE4_1__)
const ssef lnearP = maxi(maxi(mini(lclipMinX, lclipMaxX), mini(lclipMinY, lclipMaxY)), mini(lclipMinZ, lclipMaxZ));
const ssef lfarP = mini(mini(maxi(lclipMinX, lclipMaxX), maxi(lclipMinY, lclipMaxY)), maxi(lclipMinZ, lclipMaxZ));
const sseb lhit = maxi(lnearP,ray_tnear) <= mini(lfarP,ray_tfar);
#else
const ssef lnearP = max(max(min(lclipMinX, lclipMaxX), min(lclipMinY, lclipMaxY)), min(lclipMinZ, lclipMaxZ));
const ssef lfarP = min(min(max(lclipMinX, lclipMaxX), max(lclipMinY, lclipMaxY)), max(lclipMinZ, lclipMaxZ));
const sseb lhit = max(lnearP,ray_tnear) <= min(lfarP,ray_tfar);
#endif
/* if we hit the child we choose to continue with that child if it
is closer than the current next child, or we push it onto the stack */
if (likely(any(lhit)))
{
assert(sptr_node < stackEnd);
const ssef childDist = select(lhit,lnearP,inf);
const NodeRef child = node->children[i];
assert(child != BVH4::emptyNode);
sptr_node++;
sptr_near++;
/* push cur node onto stack and continue with hit child */
//.........这里部分代码省略.........
示例9: pre
void BVH4Intersector4Hybrid<types,robust,PrimitiveIntersector4>::intersect(bool4* valid_i, BVH4* bvh, Ray4& ray)
{
/* verify correct input */
bool4 valid0 = *valid_i;
#if defined(RTCORE_IGNORE_INVALID_RAYS)
valid0 &= ray.valid();
#endif
assert(all(valid0,ray.tnear > -FLT_MIN));
assert(!(types & BVH4::FLAG_NODE_MB) || all(valid0,ray.time >= 0.0f & ray.time <= 1.0f));
/* load ray */
Vec3f4 ray_org = ray.org;
Vec3f4 ray_dir = ray.dir;
float4 ray_tnear = ray.tnear, ray_tfar = ray.tfar;
const Vec3f4 rdir = rcp_safe(ray_dir);
const Vec3f4 org(ray_org), org_rdir = org * rdir;
ray_tnear = select(valid0,ray_tnear,float4(pos_inf));
ray_tfar = select(valid0,ray_tfar ,float4(neg_inf));
const float4 inf = float4(pos_inf);
Precalculations pre(valid0,ray);
/* compute near/far per ray */
Vec3i4 nearXYZ;
nearXYZ.x = select(rdir.x >= 0.0f,int4(0*(int)sizeof(float4)),int4(1*(int)sizeof(float4)));
nearXYZ.y = select(rdir.y >= 0.0f,int4(2*(int)sizeof(float4)),int4(3*(int)sizeof(float4)));
nearXYZ.z = select(rdir.z >= 0.0f,int4(4*(int)sizeof(float4)),int4(5*(int)sizeof(float4)));
/* allocate stack and push root node */
float4 stack_near[stackSizeChunk];
NodeRef stack_node[stackSizeChunk];
stack_node[0] = BVH4::invalidNode;
stack_near[0] = inf;
stack_node[1] = bvh->root;
stack_near[1] = ray_tnear;
NodeRef* stackEnd = stack_node+stackSizeChunk;
NodeRef* __restrict__ sptr_node = stack_node + 2;
float4* __restrict__ sptr_near = stack_near + 2;
while (1) pop:
{
/* pop next node from stack */
assert(sptr_node > stack_node);
sptr_node--;
sptr_near--;
NodeRef cur = *sptr_node;
if (unlikely(cur == BVH4::invalidNode)) {
assert(sptr_node == stack_node);
break;
}
/* cull node if behind closest hit point */
float4 curDist = *sptr_near;
const bool4 active = curDist < ray_tfar;
if (unlikely(none(active)))
continue;
/* switch to single ray traversal */
#if !defined(__WIN32__) || defined(__X86_64__)
size_t bits = movemask(active);
if (unlikely(__popcnt(bits) <= SWITCH_THRESHOLD)) {
for (size_t i=__bsf(bits); bits!=0; bits=__btc(bits,i), i=__bsf(bits)) {
BVH4Intersector4Single<types,robust,PrimitiveIntersector4>::intersect1(bvh, cur, i, pre, ray, ray_org, ray_dir, rdir, ray_tnear, ray_tfar, nearXYZ);
}
ray_tfar = min(ray_tfar,ray.tfar);
continue;
}
#endif
while (1)
{
/* process normal nodes */
if (likely((types & 0x1) && cur.isNode()))
{
const bool4 valid_node = ray_tfar > curDist;
STAT3(normal.trav_nodes,1,popcnt(valid_node),4);
const Node* __restrict__ const node = cur.node();
/* pop of next node */
assert(sptr_node > stack_node);
sptr_node--;
sptr_near--;
cur = *sptr_node;
curDist = *sptr_near;
#pragma unroll(4)
for (unsigned i=0; i<BVH4::N; i++)
{
const NodeRef child = node->children[i];
if (unlikely(child == BVH4::emptyNode)) break;
float4 lnearP; const bool4 lhit = intersect_node<robust>(node,i,org,rdir,org_rdir,ray_tnear,ray_tfar,lnearP);
/* if we hit the child we choose to continue with that child if it
is closer than the current next child, or we push it onto the stack */
if (likely(any(lhit)))
{
assert(sptr_node < stackEnd);
assert(child != BVH4::emptyNode);
const float4 childDist = select(lhit,lnearP,inf);
sptr_node++;
sptr_near++;
//.........这里部分代码省略.........
示例10: pre
void BVH8Intersector8Chunk<PrimitiveIntersector8>::intersect(avxb* valid_i, BVH8* bvh, Ray8& ray)
{
#if defined(__AVX__)
/* load ray */
const avxb valid0 = *valid_i;
const avx3f rdir = rcp_safe(ray.dir);
const avx3f org_rdir = ray.org * rdir;
avxf ray_tnear = select(valid0,ray.tnear,pos_inf);
avxf ray_tfar = select(valid0,ray.tfar ,neg_inf);
const avxf inf = avxf(pos_inf);
Precalculations pre(valid0,ray);
/* allocate stack and push root node */
avxf stack_near[3*BVH8::maxDepth+1];
NodeRef stack_node[3*BVH8::maxDepth+1];
stack_node[0] = BVH8::invalidNode;
stack_near[0] = inf;
stack_node[1] = bvh->root;
stack_near[1] = ray_tnear;
NodeRef* __restrict__ sptr_node = stack_node + 2;
avxf* __restrict__ sptr_near = stack_near + 2;
while (1)
{
/* pop next node from stack */
sptr_node--;
sptr_near--;
NodeRef cur = *sptr_node;
if (unlikely(cur == BVH8::invalidNode))
break;
/* cull node if behind closest hit point */
avxf curDist = *sptr_near;
if (unlikely(none(ray_tfar > curDist)))
continue;
while (1)
{
/* test if this is a leaf node */
if (unlikely(cur.isLeaf()))
break;
const avxb valid_node = ray_tfar > curDist;
STAT3(normal.trav_nodes,1,popcnt(valid_node),8);
const Node* __restrict__ const node = (BVH8::Node*)cur.node();
/* pop of next node */
sptr_node--;
sptr_near--;
cur = *sptr_node; // FIXME: this trick creates issues with stack depth
curDist = *sptr_near;
for (unsigned i=0; i<BVH8::N; i++)
{
const NodeRef child = node->children[i];
if (unlikely(child == BVH8::emptyNode)) break;
#if defined(__AVX2__)
const avxf lclipMinX = msub(node->lower_x[i],rdir.x,org_rdir.x);
const avxf lclipMinY = msub(node->lower_y[i],rdir.y,org_rdir.y);
const avxf lclipMinZ = msub(node->lower_z[i],rdir.z,org_rdir.z);
const avxf lclipMaxX = msub(node->upper_x[i],rdir.x,org_rdir.x);
const avxf lclipMaxY = msub(node->upper_y[i],rdir.y,org_rdir.y);
const avxf lclipMaxZ = msub(node->upper_z[i],rdir.z,org_rdir.z);
const avxf lnearP = maxi(maxi(mini(lclipMinX, lclipMaxX), mini(lclipMinY, lclipMaxY)), mini(lclipMinZ, lclipMaxZ));
const avxf lfarP = mini(mini(maxi(lclipMinX, lclipMaxX), maxi(lclipMinY, lclipMaxY)), maxi(lclipMinZ, lclipMaxZ));
const avxb lhit = maxi(lnearP,ray_tnear) <= mini(lfarP,ray_tfar);
#else
const avxf lclipMinX = node->lower_x[i] * rdir.x - org_rdir.x;
const avxf lclipMinY = node->lower_y[i] * rdir.y - org_rdir.y;
const avxf lclipMinZ = node->lower_z[i] * rdir.z - org_rdir.z;
const avxf lclipMaxX = node->upper_x[i] * rdir.x - org_rdir.x;
const avxf lclipMaxY = node->upper_y[i] * rdir.y - org_rdir.y;
const avxf lclipMaxZ = node->upper_z[i] * rdir.z - org_rdir.z;
const avxf lnearP = max(max(min(lclipMinX, lclipMaxX), min(lclipMinY, lclipMaxY)), min(lclipMinZ, lclipMaxZ));
const avxf lfarP = min(min(max(lclipMinX, lclipMaxX), max(lclipMinY, lclipMaxY)), max(lclipMinZ, lclipMaxZ));
const avxb lhit = max(lnearP,ray_tnear) <= min(lfarP,ray_tfar);
#endif
/* if we hit the child we choose to continue with that child if it
is closer than the current next child, or we push it onto the stack */
if (likely(any(lhit)))
{
const avxf childDist = select(lhit,lnearP,inf);
const NodeRef child = node->children[i];
/* push cur node onto stack and continue with hit child */
if (any(childDist < curDist))
{
*sptr_node = cur;
*sptr_near = curDist;
sptr_node++;
sptr_near++;
curDist = childDist;
cur = child;
}
/* push hit child onto stack*/
//.........这里部分代码省略.........
示例11: defined
void BVH4Intersector4Hybrid<PrimitiveIntersector4>::intersect(sseb* valid_i, BVH4* bvh, Ray4& ray)
{
/* load ray */
const sseb valid0 = *valid_i;
sse3f ray_org = ray.org, ray_dir = ray.dir;
ssef ray_tnear = ray.tnear, ray_tfar = ray.tfar;
#if defined(__FIX_RAYS__)
const ssef float_range = 0.1f*FLT_MAX;
ray_org = clamp(ray_org,sse3f(-float_range),sse3f(+float_range));
ray_dir = clamp(ray_dir,sse3f(-float_range),sse3f(+float_range));
ray_tnear = max(ray_tnear,FLT_MIN);
ray_tfar = min(ray_tfar,float(inf));
#endif
const sse3f rdir = rcp_safe(ray_dir);
const sse3f org(ray_org), org_rdir = org * rdir;
ray_tnear = select(valid0,ray_tnear,ssef(pos_inf));
ray_tfar = select(valid0,ray_tfar ,ssef(neg_inf));
const ssef inf = ssef(pos_inf);
/* allocate stack and push root node */
ssef stack_near[stackSizeChunk];
NodeRef stack_node[stackSizeChunk];
stack_node[0] = BVH4::invalidNode;
stack_near[0] = inf;
stack_node[1] = bvh->root;
stack_near[1] = ray_tnear;
NodeRef* stackEnd = stack_node+stackSizeChunk;
NodeRef* __restrict__ sptr_node = stack_node + 2;
ssef* __restrict__ sptr_near = stack_near + 2;
while (1)
{
/* pop next node from stack */
assert(sptr_node > stack_node);
sptr_node--;
sptr_near--;
NodeRef curNode = *sptr_node;
if (unlikely(curNode == BVH4::invalidNode)) {
assert(sptr_node == stack_node);
break;
}
/* cull node if behind closest hit point */
ssef curDist = *sptr_near;
const sseb active = curDist < ray_tfar;
if (unlikely(none(active)))
continue;
/* switch to single ray traversal */
#if !defined(__WIN32__) || defined(__X86_64__)
size_t bits = movemask(active);
if (unlikely(__popcnt(bits) <= SWITCH_THRESHOLD)) {
for (size_t i=__bsf(bits); bits!=0; bits=__btc(bits,i), i=__bsf(bits)) {
intersect1(bvh,curNode,i,ray,ray_org,ray_dir,rdir,ray_tnear,ray_tfar);
}
ray_tfar = ray.tfar;
continue;
}
#endif
while (1)
{
/* test if this is a leaf node */
if (unlikely(curNode.isLeaf()))
break;
const sseb valid_node = ray_tfar > curDist;
STAT3(normal.trav_nodes,1,popcnt(valid_node),4);
const Node* __restrict__ const node = curNode.node();
/* pop of next node */
assert(sptr_node > stack_node);
sptr_node--;
sptr_near--;
curNode = *sptr_node;
curDist = *sptr_near;
#pragma unroll(4)
for (unsigned i=0; i<4; i++)
{
const NodeRef child = node->children[i];
if (unlikely(child == BVH4::emptyNode)) break;
#if defined(__AVX2__)
const ssef lclipMinX = msub(node->lower_x[i],rdir.x,org_rdir.x);
const ssef lclipMinY = msub(node->lower_y[i],rdir.y,org_rdir.y);
const ssef lclipMinZ = msub(node->lower_z[i],rdir.z,org_rdir.z);
const ssef lclipMaxX = msub(node->upper_x[i],rdir.x,org_rdir.x);
const ssef lclipMaxY = msub(node->upper_y[i],rdir.y,org_rdir.y);
const ssef lclipMaxZ = msub(node->upper_z[i],rdir.z,org_rdir.z);
#else
const ssef lclipMinX = (node->lower_x[i] - org.x) * rdir.x;
const ssef lclipMinY = (node->lower_y[i] - org.y) * rdir.y;
const ssef lclipMinZ = (node->lower_z[i] - org.z) * rdir.z;
const ssef lclipMaxX = (node->upper_x[i] - org.x) * rdir.x;
const ssef lclipMaxY = (node->upper_y[i] - org.y) * rdir.y;
const ssef lclipMaxZ = (node->upper_z[i] - org.z) * rdir.z;
#endif
#if defined(__SSE4_1__)
//.........这里部分代码省略.........
示例12: pre
void BVH4Intersector8Chunk<types, robust, PrimitiveIntersector8>::intersect(bool8* valid_i, BVH4* bvh, Ray8& ray)
{
/* verify correct input */
bool8 valid0 = *valid_i;
#if defined(RTCORE_IGNORE_INVALID_RAYS)
valid0 &= ray.valid();
#endif
assert(all(valid0,ray.tnear > -FLT_MIN));
assert(!(types & BVH4::FLAG_NODE_MB) || all(valid0,ray.time >= 0.0f & ray.time <= 1.0f));
/* load ray */
const Vec3f8 rdir = rcp_safe(ray.dir);
const Vec3f8 org(ray.org), org_rdir = org * rdir;
float8 ray_tnear = select(valid0,ray.tnear,pos_inf);
float8 ray_tfar = select(valid0,ray.tfar ,neg_inf);
const float8 inf = float8(pos_inf);
Precalculations pre(valid0,ray);
/* allocate stack and push root node */
float8 stack_near[stackSize];
NodeRef stack_node[stackSize];
stack_node[0] = BVH4::invalidNode;
stack_near[0] = inf;
stack_node[1] = bvh->root;
stack_near[1] = ray_tnear;
NodeRef* stackEnd = stack_node+stackSize;
NodeRef* __restrict__ sptr_node = stack_node + 2;
float8* __restrict__ sptr_near = stack_near + 2;
while (1)
{
/* pop next node from stack */
assert(sptr_node > stack_node);
sptr_node--;
sptr_near--;
NodeRef cur = *sptr_node;
if (unlikely(cur == BVH4::invalidNode)) {
assert(sptr_node == stack_node);
break;
}
/* cull node if behind closest hit point */
float8 curDist = *sptr_near;
if (unlikely(none(ray_tfar > curDist)))
continue;
while (1)
{
/* process normal nodes */
if (likely((types & 0x1) && cur.isNode()))
{
const bool8 valid_node = ray_tfar > curDist;
STAT3(normal.trav_nodes,1,popcnt(valid_node),8);
const Node* __restrict__ const node = cur.node();
/* pop of next node */
assert(sptr_node > stack_node);
sptr_node--;
sptr_near--;
cur = *sptr_node;
curDist = *sptr_near;
#pragma unroll(4)
for (unsigned i=0; i<BVH4::N; i++)
{
const NodeRef child = node->children[i];
if (unlikely(child == BVH4::emptyNode)) break;
float8 lnearP; const bool8 lhit = intersect8_node<robust>(node,i,org,rdir,org_rdir,ray_tnear,ray_tfar,lnearP);
/* if we hit the child we choose to continue with that child if it
is closer than the current next child, or we push it onto the stack */
if (likely(any(lhit)))
{
assert(sptr_node < stackEnd);
assert(child != BVH4::emptyNode);
const float8 childDist = select(lhit,lnearP,inf);
sptr_node++;
sptr_near++;
/* push cur node onto stack and continue with hit child */
if (any(childDist < curDist))
{
*(sptr_node-1) = cur;
*(sptr_near-1) = curDist;
curDist = childDist;
cur = child;
}
/* push hit child onto stack */
else {
*(sptr_node-1) = child;
*(sptr_near-1) = childDist;
}
}
}
}
/* process motion blur nodes */
else if (likely((types & 0x10) && cur.isNodeMB()))
{
const bool8 valid_node = ray_tfar > curDist;
//.........这里部分代码省略.........
示例13: rayNearFar
__forceinline bool occludedT(const BVH4* bvh, Ray& ray)
{
typedef typename TriangleIntersector::Triangle Triangle;
typedef StackItemT<size_t> StackItem;
typedef typename BVH4::NodeRef NodeRef;
typedef typename BVH4::Node Node;
/*! stack state */
NodeRef stack[1+3*BVH4::maxDepth]; //!< stack of nodes that still need to get traversed
NodeRef* stackPtr = stack+1; //!< current stack pointer
stack[0] = bvh->root;
/*! load the ray into SIMD registers */
const avxf pos_neg = avxf(ssef(+0.0f),ssef(-0.0f));
const avxf neg_pos = avxf(ssef(-0.0f),ssef(+0.0f));
const avxf flipSignX = swapX ? neg_pos : pos_neg;
const avxf flipSignY = swapY ? neg_pos : pos_neg;
const avxf flipSignZ = swapZ ? neg_pos : pos_neg;
const avx3f norg(-ray.org.x,-ray.org.y,-ray.org.z);
const Vector3f ray_rdir = rcp_safe(ray.dir);
const avx3f rdir(ray_rdir.x^flipSignX,ray_rdir.y^flipSignY,ray_rdir.z^flipSignZ);
const avx3f org_rdir(avx3f(ray.org.x,ray.org.y,ray.org.z)*rdir);
const avxf rayNearFar(ssef(ray.tnear),-ssef(ray.tfar));
const void* nodePtr = bvh->nodePtr();
const void* triPtr = bvh->triPtr();
/* pop loop */
while (true) pop:
{
/*! pop next node */
if (unlikely(stackPtr == stack)) break;
stackPtr--;
NodeRef cur = (NodeRef) *stackPtr;
/* downtraversal loop */
while (true)
{
/*! stop if we found a leaf */
if (unlikely(cur.isLeaf())) break;
STAT3(shadow.trav_nodes,1,1,1);
/*! single ray intersection with 4 boxes */
const Node* node = cur.node(nodePtr);
#if defined (__AVX2__) || defined(__MIC__)
const avxf tLowerUpperX = msub(avxf::load(&node->lower_x), rdir.x, org_rdir.x);
const avxf tLowerUpperY = msub(avxf::load(&node->lower_y), rdir.y, org_rdir.y);
const avxf tLowerUpperZ = msub(avxf::load(&node->lower_z), rdir.z, org_rdir.z);
#else
const avxf tLowerUpperX = (norg.x + avxf::load(&node->lower_x)) * rdir.x;
const avxf tLowerUpperY = (norg.y + avxf::load(&node->lower_y)) * rdir.y;
const avxf tLowerUpperZ = (norg.z + avxf::load(&node->lower_z)) * rdir.z;
#endif
const avxf tNearFarX = swapX ? shuffle<1,0>(tLowerUpperX) : tLowerUpperX;
const avxf tNearFarY = swapY ? shuffle<1,0>(tLowerUpperY) : tLowerUpperY;
const avxf tNearFarZ = swapZ ? shuffle<1,0>(tLowerUpperZ) : tLowerUpperZ;
const avxf tNearFar = max(tNearFarX,tNearFarY,tNearFarZ,rayNearFar);
const ssef tNear = extract<0>(tNearFar);
const ssef tFar = extract<1>(tNearFar);
size_t mask = movemask(-tNear >= tFar);
/*! if no child is hit, pop next node */
if (unlikely(mask == 0))
goto pop;
/*! one child is hit, continue with that child */
size_t r = __bsf(mask); mask = __btc(mask,r);
if (likely(mask == 0)) {
cur = node->child(r);
continue;
}
/*! two children are hit, push far child, and continue with closer child */
NodeRef c0 = node->child(r); const float d0 = tNear[r];
r = __bsf(mask); mask = __btc(mask,r);
NodeRef c1 = node->child(r); const float d1 = tNear[r];
if (likely(mask == 0)) {
if (d0 < d1) { *stackPtr = c1; stackPtr++; cur = c0; continue; }
else { *stackPtr = c0; stackPtr++; cur = c1; continue; }
}
*stackPtr = c0; stackPtr++;
*stackPtr = c1; stackPtr++;
/*! three children are hit */
r = __bsf(mask); mask = __btc(mask,r);
cur = node->child(r); *stackPtr = cur; stackPtr++;
if (likely(mask == 0)) {
stackPtr--;
continue;
}
/*! four children are hit */
cur = node->child(3);
}
/*! this is a leaf node */
STAT3(shadow.trav_leaves,1,1,1);
size_t num; Triangle* tri = (Triangle*) cur.leaf(triPtr,num);
for (size_t i=0; i<num; i++) {
//.........这里部分代码省略.........
示例14: pre
void BVH4Intersector4Chunk<types,robust,PrimitiveIntersector4>::intersect(sseb* valid_i, BVH4* bvh, Ray4& ray)
{
/* load ray */
const sseb valid0 = *valid_i;
const sse3f rdir = rcp_safe(ray.dir);
const sse3f org(ray.org), org_rdir = org * rdir;
ssef ray_tnear = select(valid0,ray.tnear,ssef(pos_inf));
ssef ray_tfar = select(valid0,ray.tfar ,ssef(neg_inf));
const ssef inf = ssef(pos_inf);
Precalculations pre(valid0,ray);
/* allocate stack and push root node */
ssef stack_near[stackSize];
NodeRef stack_node[stackSize];
stack_node[0] = BVH4::invalidNode;
stack_near[0] = inf;
stack_node[1] = bvh->root;
stack_near[1] = ray_tnear;
NodeRef* stackEnd = stack_node+stackSize;
NodeRef* __restrict__ sptr_node = stack_node + 2;
ssef* __restrict__ sptr_near = stack_near + 2;
while (1)
{
/* pop next node from stack */
assert(sptr_node > stack_node);
sptr_node--;
sptr_near--;
NodeRef cur = *sptr_node;
if (unlikely(cur == BVH4::invalidNode)) {
assert(sptr_node == stack_node);
break;
}
/* cull node if behind closest hit point */
ssef curDist = *sptr_near;
if (unlikely(none(ray_tfar > curDist)))
continue;
while (1)
{
/* process normal nodes */
if (likely((types & 0x1) && cur.isNode()))
{
const sseb valid_node = ray_tfar > curDist;
STAT3(normal.trav_nodes,1,popcnt(valid_node),8);
const Node* __restrict__ const node = cur.node();
/* pop of next node */
assert(sptr_node > stack_node);
sptr_node--;
sptr_near--;
cur = *sptr_node;
curDist = *sptr_near;
#pragma unroll(4)
for (unsigned i=0; i<BVH4::N; i++)
{
const NodeRef child = node->children[i];
if (unlikely(child == BVH4::emptyNode)) break;
ssef lnearP; const sseb lhit = node->intersect<robust>(i,org,rdir,org_rdir,ray_tnear,ray_tfar,lnearP);
/* if we hit the child we choose to continue with that child if it
is closer than the current next child, or we push it onto the stack */
if (likely(any(lhit)))
{
assert(sptr_node < stackEnd);
const ssef childDist = select(lhit,lnearP,inf);
const NodeRef child = node->children[i];
assert(child != BVH4::emptyNode);
sptr_node++;
sptr_near++;
/* push cur node onto stack and continue with hit child */
if (any(childDist < curDist))
{
*(sptr_node-1) = cur;
*(sptr_near-1) = curDist;
curDist = childDist;
cur = child;
}
/* push hit child onto stack */
else {
*(sptr_node-1) = child;
*(sptr_near-1) = childDist;
}
}
}
}
/* process motion blur nodes */
else if (likely((types & 0x10) && cur.isNodeMB()))
{
const sseb valid_node = ray_tfar > curDist;
STAT3(normal.trav_nodes,1,popcnt(valid_node),8);
const BVH4::NodeMB* __restrict__ const node = cur.nodeMB();
/* pop of next node */
assert(sptr_node > stack_node);
sptr_node--;
//.........这里部分代码省略.........
示例15: select
void BVH4Intersector4Chunk<TriangleIntersector4>::intersect(const BVH4Intersector4Chunk* This, Ray4& ray, const __m128 valid_i)
{
sseb valid = valid_i;
NodeRef invalid = (NodeRef)1;
const BVH4* bvh = This->bvh;
STAT3(normal.travs,1,popcnt(valid),4);
/* load ray into registers */
ssef ray_near = select(valid,ray.tnear,pos_inf);
ssef ray_far = select(valid,ray.tfar ,neg_inf);
sse3f rdir = rcp_safe(ray.dir);
ray.tfar = ray_far;
/* allocate stack and push root node */
NodeRef stack_node[3*BVH4::maxDepth+1];
ssef stack_near[3*BVH4::maxDepth+1];
stack_node[0] = invalid;
stack_near[0] = ssef(inf);
stack_node[1] = bvh->root;
stack_near[1] = ray_near;
NodeRef* sptr_node = stack_node+2;
ssef * sptr_near = stack_near+2;
while (1)
{
/* pop next node from stack */
sptr_node--;
sptr_near--;
ssef curDist = *sptr_near;
NodeRef curNode = *sptr_node;
if (unlikely(curNode == invalid))
break;
/* cull node if behind closest hit point */
const sseb m_dist = curDist < ray_far;
if (unlikely(none(m_dist)))
continue;
while (1)
{
/* test if this is a leaf node */
if (unlikely(curNode.isLeaf()))
break;
STAT3(normal.trav_nodes,1,popcnt(valid),4);
const Node* const node = curNode.node(bvh->nodePtr()); //NodeRef(curNode).node(nodes);
//prefetch<PFHINT_L1>((ssef*)node + 1); // depth first order prefetch
/* pop of next node */
sptr_node--;
sptr_near--;
curNode = *sptr_node;
curDist = *sptr_near;
for (unsigned i=0;i<4;i++)
{
const ssef dminx = (ssef(node->lower_x[i]) - ray.org.x) * rdir.x;
const ssef dmaxx = (ssef(node->upper_x[i]) - ray.org.x) * rdir.x;
const ssef dminy = (ssef(node->lower_y[i]) - ray.org.y) * rdir.y;
const ssef dmaxy = (ssef(node->upper_y[i]) - ray.org.y) * rdir.y;
const ssef dminz = (ssef(node->lower_z[i]) - ray.org.z) * rdir.z;
const ssef dmaxz = (ssef(node->upper_z[i]) - ray.org.z) * rdir.z;
const ssef dlowerx = min(dminx,dmaxx);
const ssef dupperx = max(dminx,dmaxx);
const ssef dlowery = min(dminy,dmaxy);
const ssef duppery = max(dminy,dmaxy);
const ssef dlowerz = min(dminz,dmaxz);
const ssef dupperz = max(dminz,dmaxz);
const ssef near = max(dlowerx,dlowery,dlowerz,ray_near);
const ssef far = min(dupperx,duppery,dupperz,ray_far );
const sseb mhit = near <= far;
const ssef childDist = select(mhit,near,inf);
const sseb closer = childDist < curDist;
/* if we hit the child we choose to continue with that child if it
is closer than the current next child, or we push it onto the stack */
if (likely(any(mhit)))
{
const NodeRef child = node->child(i);
//if (child != invalid)
{
sptr_node++;
sptr_near++;
/* push cur node onto stack and continue with hit child */
if (any(closer)) {
*(sptr_node-1) = curNode;
*(sptr_near-1) = curDist;
curDist = childDist;
curNode = child;
}
/* push hit child onto stack*/
else {
*(sptr_node-1) = child;
*(sptr_near-1) = childDist;
//.........这里部分代码省略.........