Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fdc8867102 |
+5
-5
@@ -362,9 +362,9 @@ namespace embree
|
||||
__forceinline const QuantizedNode* quantizedNode() const { assert(isQuantizedNode()); return (const QuantizedNode*)(ptr & ~(size_t)align_mask ); }
|
||||
|
||||
/*! returns leaf pointer */
|
||||
__forceinline char* leaf(size_t& num) const {
|
||||
__forceinline char* leaf(size_t& ty) const {
|
||||
assert(isLeaf());
|
||||
num = (ptr & (size_t)items_mask)-tyLeaf;
|
||||
ty = (ptr & (size_t)items_mask)-tyLeaf;
|
||||
return (char*)(ptr & ~(size_t)align_mask);
|
||||
}
|
||||
|
||||
@@ -1454,10 +1454,10 @@ namespace embree
|
||||
}
|
||||
|
||||
/*! Encodes a leaf */
|
||||
static __forceinline NodeRef encodeLeaf(void* tri, size_t num) {
|
||||
static __forceinline NodeRef encodeLeaf(void* tri, size_t ty) {
|
||||
assert(!((size_t)tri & align_mask));
|
||||
assert(num <= maxLeafBlocks);
|
||||
return NodeRef((size_t)tri | (tyLeaf+min(num,(size_t)maxLeafBlocks)));
|
||||
assert(ty <= maxLeafBlocks);
|
||||
return NodeRef((size_t)tri | (tyLeaf+min(ty,(size_t)maxLeafBlocks)));
|
||||
}
|
||||
|
||||
/*! Encodes a leaf */
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace embree
|
||||
size_t items = set.size();
|
||||
Primitive* accel = (Primitive*) alloc.malloc1(items*sizeof(Primitive),BVH::byteAlignment);
|
||||
for (size_t i=0; i<items; i++) {
|
||||
accel[i].fill(prims,start,set.end(),bvh->scene);
|
||||
accel[i].fill(prims,start,set.end(),bvh->scene,i==(items-1));
|
||||
}
|
||||
return bvh->encodeLeaf((char*)accel,items);
|
||||
};
|
||||
@@ -165,7 +165,7 @@ namespace embree
|
||||
|
||||
LBBox3fa bounds = empty;
|
||||
for (size_t i=0; i<items; i++)
|
||||
bounds.extend(accel[i].fillMB(prims.prims->data(),start,end,bvh->scene,prims.time_range));
|
||||
bounds.extend(accel[i].fillMB(prims.prims->data(),start,end,bvh->scene,prims.time_range,i==(items-1)));
|
||||
|
||||
return NodeRecordMB4D(node,bounds,prims.time_range);
|
||||
};
|
||||
|
||||
@@ -128,7 +128,7 @@ namespace embree
|
||||
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
|
||||
}
|
||||
|
||||
Triangle4::store_nt(accel,Triangle4(v0,v1,v2,vgeomID,vprimID));
|
||||
Triangle4::store_nt(accel,Triangle4(v0,v1,v2,vgeomID,vprimID,true));
|
||||
BBox3fa box_o = BBox3fa((Vec3fa)lower,(Vec3fa)upper);
|
||||
#if ROTATE_TREE
|
||||
if (N == 4)
|
||||
@@ -183,7 +183,7 @@ namespace embree
|
||||
v1.x[i] = p1.x; v1.y[i] = p1.y; v1.z[i] = p1.z;
|
||||
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
|
||||
}
|
||||
Triangle4v::store_nt(accel,Triangle4v(v0,v1,v2,vgeomID,vprimID));
|
||||
Triangle4v::store_nt(accel,Triangle4v(v0,v1,v2,vgeomID,vprimID,true));
|
||||
BBox3fa box_o = BBox3fa((Vec3fa)lower,(Vec3fa)upper);
|
||||
#if ROTATE_TREE
|
||||
if (N == 4)
|
||||
@@ -249,7 +249,7 @@ namespace embree
|
||||
v2[i] = 0;
|
||||
}
|
||||
|
||||
Triangle4i::store_nt(accel,Triangle4i(v0,v1,v2,vgeomID,vprimID));
|
||||
Triangle4i::store_nt(accel,Triangle4i(v0,v1,v2,vgeomID,vprimID,true));
|
||||
BBox3fa box_o = BBox3fa((Vec3fa)lower,(Vec3fa)upper);
|
||||
#if ROTATE_TREE
|
||||
if (N == 4)
|
||||
@@ -306,7 +306,7 @@ namespace embree
|
||||
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
|
||||
v3.x[i] = p3.x; v3.y[i] = p3.y; v3.z[i] = p3.z;
|
||||
}
|
||||
Quad4v::store_nt(accel,Quad4v(v0,v1,v2,v3,vgeomID,vprimID));
|
||||
Quad4v::store_nt(accel,Quad4v(v0,v1,v2,v3,vgeomID,vprimID,true));
|
||||
BBox3fa box_o = BBox3fa((Vec3fa)lower,(Vec3fa)upper);
|
||||
#if ROTATE_TREE
|
||||
if (N == 4)
|
||||
@@ -349,7 +349,7 @@ namespace embree
|
||||
const unsigned index = morton[start+i].index;
|
||||
const unsigned primID = index;
|
||||
bounds.extend(mesh->bounds(primID));
|
||||
new (&accel[i]) Object(geomID,primID);
|
||||
new (&accel[i]) Object(geomID,primID,true);
|
||||
}
|
||||
BBox3fa box_o = bounds;
|
||||
#if ROTATE_TREE
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace embree
|
||||
Primitive* accel = (Primitive*) alloc.malloc1(items*sizeof(Primitive),BVH::byteAlignment);
|
||||
typename BVH::NodeRef node = BVH::encodeLeaf((char*)accel,items);
|
||||
for (size_t i=0; i<items; i++) {
|
||||
accel[i].fill(prims,start,set.end(),bvh->scene);
|
||||
accel[i].fill(prims,start,set.end(),bvh->scene,i==(items-1));
|
||||
}
|
||||
return node;
|
||||
}
|
||||
@@ -89,7 +89,7 @@ namespace embree
|
||||
Primitive* accel = (Primitive*) alloc.malloc1(items*sizeof(Primitive),BVH::byteAlignment);
|
||||
typename BVH::NodeRef node = BVH::encodeLeaf((char*)accel,items);
|
||||
for (size_t i=0; i<items; i++) {
|
||||
accel[i].fill(prims,start,set.end(),bvh->scene);
|
||||
accel[i].fill(prims,start,set.end(),bvh->scene,i==(items-1));
|
||||
}
|
||||
return node;
|
||||
}
|
||||
@@ -364,7 +364,7 @@ namespace embree
|
||||
|
||||
LBBox3fa allBounds = empty;
|
||||
for (size_t i=0; i<items; i++)
|
||||
allBounds.extend(accel[i].fillMB(prims, start, set.end(), bvh->scene, time));
|
||||
allBounds.extend(accel[i].fillMB(prims, start, set.end(), bvh->scene, time, i==(items-1)));
|
||||
|
||||
return NodeRecordMB(node,allBounds);
|
||||
}
|
||||
@@ -392,7 +392,7 @@ namespace embree
|
||||
NodeRef node = bvh->encodeLeaf((char*)accel,items);
|
||||
LBBox3fa allBounds = empty;
|
||||
for (size_t i=0; i<items; i++)
|
||||
allBounds.extend(accel[i].fillMB(current.prims.prims->data(), start, current.prims.object_range.end(), bvh->scene, current.prims.time_range));
|
||||
allBounds.extend(accel[i].fillMB(current.prims.prims->data(), start, current.prims.object_range.end(), bvh->scene, current.prims.time_range, i==(items-1)));
|
||||
return NodeRecordMB4D(node,allBounds,current.prims.time_range);
|
||||
}
|
||||
|
||||
|
||||
@@ -105,8 +105,12 @@ namespace embree
|
||||
if (unlikely(nodeTraverser.traverseTransform(cur,ray,vray,context,stackPtr,stackEnd)))
|
||||
goto pop;
|
||||
|
||||
/*! this is a leaf node */
|
||||
/*! check for empty leaf in case we accidentally hit one */
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (cur == BVH::emptyNode)
|
||||
goto pop;
|
||||
|
||||
/*! this is a leaf node */
|
||||
STAT3(normal.trav_leaves,1,1,1);
|
||||
size_t num; Primitive* prim = (Primitive*) cur.leaf(num);
|
||||
size_t lazy_node = 0;
|
||||
@@ -187,8 +191,12 @@ namespace embree
|
||||
if (unlikely(nodeTraverser.traverseTransform(cur,ray,vray,context,stackPtr,stackEnd)))
|
||||
goto pop;
|
||||
|
||||
/*! this is a leaf node */
|
||||
/*! check for empty leaf in case we accidentally hit one */
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (cur == BVH::emptyNode)
|
||||
goto pop;
|
||||
|
||||
/*! this is a leaf node */
|
||||
STAT3(shadow.trav_leaves,1,1,1);
|
||||
size_t num; Primitive* prim = (Primitive*) cur.leaf(num);
|
||||
size_t lazy_node = 0;
|
||||
|
||||
@@ -105,8 +105,12 @@ namespace embree
|
||||
BVHNNodeTraverser1<N,Nx,types>::traverseClosestHit(cur,mask,tNear,stackPtr,stackEnd);
|
||||
}
|
||||
|
||||
/*! this is a leaf node */
|
||||
/*! check for empty leaf in case we accidentally hit one */
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (cur == BVH::emptyNode)
|
||||
goto pop;
|
||||
|
||||
/*! this is a leaf node */
|
||||
STAT3(normal.trav_leaves, 1, 1, 1);
|
||||
size_t num; Primitive* prim = (Primitive*)cur.leaf(num);
|
||||
|
||||
@@ -345,8 +349,12 @@ namespace embree
|
||||
break;
|
||||
}
|
||||
|
||||
/* intersect leaf */
|
||||
/*! check for empty leaf in case we accidentally hit one */
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (cur == BVH::emptyNode)
|
||||
goto pop;
|
||||
|
||||
/* intersect leaf */
|
||||
const vbool<K> valid_leaf = ray_tfar > curDist;
|
||||
STAT3(normal.trav_leaves,1,popcnt(valid_leaf),K);
|
||||
if (unlikely(none(valid_leaf))) continue;
|
||||
@@ -493,12 +501,15 @@ namespace embree
|
||||
std::swap(stackPtr[-3],stackPtr[-2]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*! check for empty leaf in case we accidentally hit one */
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (cur == BVH::emptyNode)
|
||||
goto pop;
|
||||
|
||||
/* intersect leaf */
|
||||
assert(cur != BVH::invalidNode);
|
||||
assert(cur != BVH::emptyNode);
|
||||
const vbool<K> valid_leaf = ray_tfar > curDist;
|
||||
STAT3(normal.trav_leaves,1,popcnt(valid_leaf),K);
|
||||
if (unlikely(none(valid_leaf))) continue;
|
||||
@@ -577,8 +588,12 @@ namespace embree
|
||||
BVHNNodeTraverser1<N,Nx,types>::traverseAnyHit(cur,mask,tNear,stackPtr,stackEnd);
|
||||
}
|
||||
|
||||
/*! this is a leaf node */
|
||||
/*! check for empty leaf in case we accidentally hit one */
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (cur == BVH::emptyNode)
|
||||
goto pop;
|
||||
|
||||
/*! this is a leaf node */
|
||||
STAT3(shadow.trav_leaves,1,1,1);
|
||||
size_t num; Primitive* prim = (Primitive*) cur.leaf(num);
|
||||
|
||||
@@ -763,9 +778,12 @@ namespace embree
|
||||
break;
|
||||
}
|
||||
|
||||
/*! check for empty leaf in case we accidentally hit one */
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (cur == BVH::emptyNode)
|
||||
goto pop;
|
||||
|
||||
/* intersect leaf */
|
||||
assert(cur != BVH::emptyNode);
|
||||
const vbool<K> valid_leaf = ray_tfar > curDist;
|
||||
STAT3(shadow.trav_leaves,1,popcnt(valid_leaf),K);
|
||||
if (unlikely(none(valid_leaf))) continue;
|
||||
@@ -894,9 +912,13 @@ namespace embree
|
||||
if (unlikely(cur == BVH::emptyNode)) goto pop;
|
||||
}
|
||||
|
||||
/*! check for empty leaf in case we accidentally hit one */
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (cur == BVH::emptyNode)
|
||||
goto pop;
|
||||
|
||||
/* intersect leaf */
|
||||
assert(cur != BVH::invalidNode);
|
||||
assert(cur != BVH::emptyNode);
|
||||
#if defined(__AVX__)
|
||||
STAT3(normal.trav_leaves,1,__popcnt(m_active),K);
|
||||
#endif
|
||||
@@ -920,7 +942,5 @@ namespace embree
|
||||
|
||||
AVX_ZERO_UPPER();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,391 +0,0 @@
|
||||
// ======================================================================== //
|
||||
// Copyright 2009-2017 Intel Corporation //
|
||||
// //
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); //
|
||||
// you may not use this file except in compliance with the License. //
|
||||
// You may obtain a copy of the License at //
|
||||
// //
|
||||
// http://www.apache.org/licenses/LICENSE-2.0 //
|
||||
// //
|
||||
// Unless required by applicable law or agreed to in writing, software //
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, //
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
|
||||
// See the License for the specific language governing permissions and //
|
||||
// limitations under the License. //
|
||||
// ======================================================================== //
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "bvh.h"
|
||||
#include "bvh_intersector_node.h"
|
||||
#include "bvh_traverser1.h"
|
||||
#include "../common/ray.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace isa
|
||||
{
|
||||
/*! BVH single ray intersector for packets. */
|
||||
template<int N, int K, int types, bool robust, typename PrimitiveIntersectorK>
|
||||
class BVHNIntersectorKSingle
|
||||
{
|
||||
/* shortcuts for frequently used types */
|
||||
typedef typename PrimitiveIntersectorK::Precalculations Precalculations;
|
||||
typedef typename PrimitiveIntersectorK::Primitive Primitive;
|
||||
typedef BVHN<N> BVH;
|
||||
typedef typename BVH::NodeRef NodeRef;
|
||||
typedef typename BVH::BaseNode BaseNode;
|
||||
typedef typename BVH::AlignedNode AlignedNode;
|
||||
typedef Vec3<vfloat<N>> Vec3vfN;
|
||||
typedef Vec3<vfloat<K>> Vec3vfK;
|
||||
typedef Vec3<vint<K>> Vec3viK;
|
||||
|
||||
static const size_t stackSizeSingle = 1+(N-1)*BVH::maxDepth;
|
||||
|
||||
/* right now AVX512KNL SIMD extension only for standard node types */
|
||||
static const size_t Nx = types == BVH_AN1 ? vextend<N>::size : N;
|
||||
|
||||
public:
|
||||
|
||||
#if defined(__AVX512F__)
|
||||
__forceinline static void isort_update(vfloat16 &dist, vllong8 &ptr, const vfloat16 &d, const vllong8 &p)
|
||||
{
|
||||
const vfloat16 dist_shift = align_shift_right<15>(dist,dist);
|
||||
const vllong8 ptr_shift = align_shift_right<7>(ptr,ptr);
|
||||
const vbool16 m_leq = d <= dist;
|
||||
const vbool16 m_leq_shift = m_leq << 1;
|
||||
dist = select(m_leq,d,dist);
|
||||
ptr = select(vboold8(m_leq),p,ptr);
|
||||
dist = select(m_leq_shift,dist_shift,dist);
|
||||
ptr = select(vboold8(m_leq_shift),ptr_shift,ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
static __forceinline void traverseClosestHitNew(const BaseNode* node,
|
||||
NodeRef& cur,
|
||||
size_t mask,
|
||||
const vfloat<Nx>& tNear,
|
||||
StackItemT<NodeRef>*& stackPtr,
|
||||
StackItemT<NodeRef>* stackEnd)
|
||||
{
|
||||
assert(mask != 0);
|
||||
//const BaseNode* node = cur.baseNode(types);
|
||||
#if defined(__AVX512F__)
|
||||
/*! one child is hit, continue with that child */
|
||||
const size_t hits = __popcnt(mask);
|
||||
|
||||
size_t r = __bscf(mask);
|
||||
cur = node->child(r);
|
||||
cur.prefetch(types);
|
||||
if (likely(mask == 0)) {
|
||||
assert(cur != BVH::emptyNode);
|
||||
return;
|
||||
}
|
||||
|
||||
const vllong8 c0(cur);
|
||||
const vfloat16 d0(tNear[r]);
|
||||
r = __bscf(mask);
|
||||
cur = node->child(r);
|
||||
cur.prefetch(types);
|
||||
const vllong8 c1(cur);
|
||||
const vfloat16 d1(tNear[r]);
|
||||
|
||||
const vboolf16 m_dist = d0 <= d1;
|
||||
const vfloat16 d_near = select(m_dist, d0, d1);
|
||||
const vfloat16 d_far = select(m_dist, d1, d0);
|
||||
const vllong8 c_near = select(vboold8(m_dist), c0, c1);
|
||||
const vllong8 c_far = select(vboold8(m_dist), c1, c0);
|
||||
|
||||
if (likely(mask == 0)) {
|
||||
cur = toScalar(c_near);
|
||||
*(float*)&stackPtr[0].dist = toScalar(d_far);
|
||||
stackPtr[0].ptr = toScalar(c_far);
|
||||
stackPtr++;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
r = __bscf(mask);
|
||||
cur = node->child(r);
|
||||
cur.prefetch(types);
|
||||
const vllong8 c2(cur);
|
||||
const vfloat16 d2(tNear[r]);
|
||||
|
||||
const vboolf16 m_dist1 = d_near <= d2;
|
||||
const vfloat16 d_near1 = select(m_dist1, d_near, d2);
|
||||
const vfloat16 d_far1 = select(m_dist1, d2, d_near);
|
||||
const vllong8 c_near1 = select(vboold8(m_dist1), c_near, c2);
|
||||
const vllong8 c_far1 = select(vboold8(m_dist1), c2, c_near);
|
||||
|
||||
const vboolf16 m_dist2 = d_far <= d_far1;
|
||||
const vfloat16 d_near2 = select(m_dist2, d_far , d_far1);
|
||||
const vfloat16 d_far2 = select(m_dist2, d_far1, d_far);
|
||||
const vllong8 c_near2 = select(vboold8(m_dist2), c_far, c_far1);
|
||||
const vllong8 c_far2 = select(vboold8(m_dist2), c_far1, c_far);
|
||||
|
||||
if (likely(mask == 0)) {
|
||||
|
||||
cur = toScalar(c_near1);
|
||||
*(float*)&stackPtr[0].dist = toScalar(d_far2);
|
||||
stackPtr[0].ptr = toScalar(c_far2);
|
||||
*(float*)&stackPtr[1].dist = toScalar(d_near2);
|
||||
stackPtr[1].ptr = toScalar(c_near2);
|
||||
stackPtr+=2;
|
||||
return;
|
||||
}
|
||||
|
||||
vfloat16 dist(pos_inf);
|
||||
vllong8 ptr(zero);
|
||||
|
||||
isort_update(dist,ptr,d0,c0);
|
||||
isort_update(dist,ptr,d1,c1);
|
||||
isort_update(dist,ptr,d2,c2);
|
||||
|
||||
do {
|
||||
const size_t r = __bscf(mask);
|
||||
cur = node->child(r);
|
||||
const vfloat16 new_dist(tNear[r]);
|
||||
const vllong8 new_ptr(cur);
|
||||
cur.prefetch(types);
|
||||
isort_update(dist,ptr,new_dist,new_ptr);
|
||||
} while(mask);
|
||||
|
||||
cur = toScalar(ptr);
|
||||
stackPtr += hits - 1;
|
||||
for (size_t i=0;i<hits-1;i++)
|
||||
{
|
||||
dist = align_shift_right<1>(dist,dist);
|
||||
ptr = align_shift_right<1>(ptr,ptr);
|
||||
stackPtr[-1-i].ptr = toScalar(ptr);
|
||||
*(float*)&stackPtr[-1-i].dist = toScalar(dist);
|
||||
}
|
||||
#else
|
||||
/*! one child is hit, continue with that child */
|
||||
size_t r = __bscf(mask);
|
||||
cur = node->child(r);
|
||||
cur.prefetch(types);
|
||||
if (likely(mask == 0)) {
|
||||
assert(cur != BVH::emptyNode);
|
||||
return;
|
||||
}
|
||||
|
||||
/*! two children are hit, push far child, and continue with closer child */
|
||||
NodeRef c0 = cur;
|
||||
const unsigned int d0 = ((unsigned int*)&tNear)[r];
|
||||
r = __bscf(mask);
|
||||
NodeRef c1 = node->child(r);
|
||||
c1.prefetch(types);
|
||||
const unsigned int d1 = ((unsigned int*)&tNear)[r];
|
||||
|
||||
assert(c0 != BVH::emptyNode);
|
||||
assert(c1 != BVH::emptyNode);
|
||||
if (likely(mask == 0)) {
|
||||
assert(stackPtr < stackEnd);
|
||||
if (d0 < d1) { stackPtr->ptr = c1; stackPtr->dist = d1; stackPtr++; cur = c0; return; }
|
||||
else { stackPtr->ptr = c0; stackPtr->dist = d0; stackPtr++; cur = c1; return; }
|
||||
}
|
||||
|
||||
/*! 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);
|
||||
stackPtr->ptr = c0; stackPtr->dist = d0; stackPtr++;
|
||||
assert(stackPtr < stackEnd);
|
||||
stackPtr->ptr = c1; stackPtr->dist = d1; stackPtr++;
|
||||
|
||||
/*! three children are hit, push all onto stack and sort 3 stack items, continue with closest child */
|
||||
assert(stackPtr < stackEnd);
|
||||
r = __bscf(mask);
|
||||
NodeRef c = node->child(r);
|
||||
c.prefetch(types);
|
||||
unsigned int d = ((unsigned int*)&tNear)[r];
|
||||
stackPtr->ptr = c;
|
||||
stackPtr->dist = d;
|
||||
stackPtr++;
|
||||
assert(c != BVH::emptyNode);
|
||||
if (likely(mask == 0)) {
|
||||
sort(stackPtr[-1],stackPtr[-2],stackPtr[-3]);
|
||||
cur = (NodeRef) stackPtr[-1].ptr; stackPtr--;
|
||||
return;
|
||||
}
|
||||
|
||||
/*! four children are hit, push all onto stack and sort 4 stack items, continue with closest child */
|
||||
assert(stackPtr < stackEnd);
|
||||
r = __bscf(mask);
|
||||
c = node->child(r);
|
||||
c.prefetch(types);
|
||||
d = *(unsigned int*)&tNear[r];
|
||||
stackPtr->ptr = c;
|
||||
stackPtr->dist = d;
|
||||
stackPtr++;
|
||||
assert(c != BVH::emptyNode);
|
||||
if (likely(mask == 0)) {
|
||||
sort(stackPtr[-1],stackPtr[-2],stackPtr[-3],stackPtr[-4]);
|
||||
cur = (NodeRef) stackPtr[-1].ptr; stackPtr--;
|
||||
return;
|
||||
}
|
||||
|
||||
/*! fallback case if more than 4 children are hit */
|
||||
StackItemT<NodeRef>* stackFirst = stackPtr-4;
|
||||
while (1)
|
||||
{
|
||||
assert(stackPtr < stackEnd);
|
||||
r = __bscf(mask);
|
||||
c = node->child(r);
|
||||
c.prefetch(types);
|
||||
d = *(unsigned int*)&tNear[r];
|
||||
stackPtr->ptr = c; stackPtr->dist = d; stackPtr++;
|
||||
assert(c != BVH::emptyNode);
|
||||
if (unlikely(mask == 0)) break;
|
||||
}
|
||||
sort(stackFirst,stackPtr);
|
||||
cur = (NodeRef) stackPtr[-1].ptr; stackPtr--;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void intersect1(const BVH* bvh,
|
||||
NodeRef root,
|
||||
const size_t k,
|
||||
Precalculations& pre,
|
||||
RayK<K>& ray,
|
||||
const Vec3vfK &ray_org,
|
||||
const Vec3vfK &ray_dir,
|
||||
const Vec3vfK &ray_rdir,
|
||||
const vfloat<K> &ray_tnear,
|
||||
const vfloat<K> &ray_tfar,
|
||||
const Vec3viK& nearXYZ,
|
||||
IntersectContext* context)
|
||||
{
|
||||
/*! stack state */
|
||||
StackItemT<NodeRef> stack[stackSizeSingle]; //!< stack of nodes
|
||||
StackItemT<NodeRef>* stackPtr = stack + 1; //!< current stack pointer
|
||||
StackItemT<NodeRef>* stackEnd = stack + stackSizeSingle;
|
||||
stack[0].ptr = root;
|
||||
stack[0].dist = neg_inf;
|
||||
|
||||
/*! load the ray into SIMD registers */
|
||||
TravRay<N,Nx> vray(k,ray_org,ray_dir,ray_rdir,nearXYZ);
|
||||
vfloat<Nx> ray_near(ray_tnear[k]), ray_far(ray_tfar[k]);
|
||||
|
||||
/* 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;
|
||||
if (unlikely((int)stackPtr->dist >= *(const int*)&ray.tfar[k])) continue;
|
||||
|
||||
/* downtraversal loop */
|
||||
while (true)
|
||||
{
|
||||
//cur.prefetch(types);
|
||||
/*! stop if we found a leaf node */
|
||||
if (unlikely(cur.isLeaf())) break;
|
||||
STAT3(normal.trav_nodes,1,1,1);
|
||||
|
||||
/* intersect node */
|
||||
size_t mask = 0;
|
||||
vfloat<Nx> tNear;
|
||||
BVHNNodeIntersector1<N,Nx,types,robust>::intersect(cur,vray,ray_near,ray_far,pre.ftime(k),tNear,mask);
|
||||
AlignedNode *node = cur.alignedNode();
|
||||
|
||||
/*! if no child is hit, pop next node */
|
||||
if (unlikely(mask == 0))
|
||||
goto pop;
|
||||
|
||||
/* select next child and push other children */
|
||||
#if defined(__AVX512F__)
|
||||
traverseClosestHitNew(node,cur,mask,tNear,stackPtr,stackEnd);
|
||||
#else
|
||||
BVHNNodeTraverser1<N,Nx,types>::traverseClosestHit(cur,mask,tNear,stackPtr,stackEnd);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*! this is a leaf node */
|
||||
assert(cur != BVH::emptyNode);
|
||||
STAT3(normal.trav_leaves, 1, 1, 1);
|
||||
size_t num; Primitive* prim = (Primitive*)cur.leaf(num);
|
||||
|
||||
size_t lazy_node = 0;
|
||||
//const unsigned int old_primID = ray.primID[k];
|
||||
PrimitiveIntersectorK::intersect(pre, ray, k, context, prim, num, lazy_node);
|
||||
|
||||
ray_far = ray.tfar[k];
|
||||
|
||||
/* if (unlikely(lazy_node)) { */
|
||||
/* stackPtr->ptr = lazy_node; */
|
||||
/* stackPtr->dist = neg_inf; */
|
||||
/* stackPtr++; */
|
||||
/* } */
|
||||
}
|
||||
}
|
||||
|
||||
static bool occluded1(const BVH* bvh, NodeRef root, const size_t k, Precalculations& pre,
|
||||
RayK<K>& ray, const Vec3vfK &ray_org, const Vec3vfK &ray_dir, const Vec3vfK &ray_rdir, const vfloat<K> &ray_tnear, const vfloat<K> &ray_tfar,
|
||||
const Vec3viK& nearXYZ, IntersectContext* context)
|
||||
{
|
||||
/*! stack state */
|
||||
NodeRef stack[stackSizeSingle]; //!< stack of nodes that still need to get traversed
|
||||
NodeRef* stackPtr = stack+1; //!< current stack pointer
|
||||
NodeRef* stackEnd = stack+stackSizeSingle;
|
||||
stack[0] = root;
|
||||
|
||||
/*! load the ray into SIMD registers */
|
||||
TravRay<N,Nx> vray(k,ray_org,ray_dir,ray_rdir,nearXYZ);
|
||||
const vfloat<Nx> ray_near(ray_tnear[k]), ray_far(ray_tfar[k]);
|
||||
|
||||
/* 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 node */
|
||||
if (unlikely(cur.isLeaf())) break;
|
||||
STAT3(shadow.trav_nodes,1,1,1);
|
||||
|
||||
/* intersect node */
|
||||
size_t mask = 0;
|
||||
vfloat<Nx> tNear;
|
||||
BVHNNodeIntersector1<N,Nx,types,robust>::intersect(cur,vray,ray_near,ray_far,pre.ftime(k),tNear,mask);
|
||||
|
||||
/*! if no child is hit, pop next node */
|
||||
if (unlikely(mask == 0))
|
||||
goto pop;
|
||||
|
||||
/* select next child and push other children */
|
||||
BVHNNodeTraverser1<N,Nx,types>::traverseAnyHit(cur,mask,tNear,stackPtr,stackEnd);
|
||||
}
|
||||
|
||||
/*! this is a leaf node */
|
||||
assert(cur != BVH::emptyNode);
|
||||
STAT3(shadow.trav_leaves,1,1,1);
|
||||
size_t num; Primitive* prim = (Primitive*) cur.leaf(num);
|
||||
|
||||
size_t lazy_node = 0;
|
||||
if (PrimitiveIntersectorK::occluded(pre,ray,k,context,prim,num,lazy_node)) {
|
||||
ray.geomID[k] = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (unlikely(lazy_node)) {
|
||||
*stackPtr = lazy_node;
|
||||
stackPtr++;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void intersect(vint<K>* valid, BVH* bvh, RayK<K>& ray, IntersectContext* context);
|
||||
static void occluded (vint<K>* valid, BVH* bvh, RayK<K>& ray, IntersectContext* context);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -143,8 +143,12 @@ namespace embree
|
||||
m_trav_active = intersectAlignedNodePacket(packet, minX, minY, minZ, maxX, maxY, maxZ, m_trav_active);
|
||||
}
|
||||
|
||||
/*! this is a leaf node */
|
||||
/*! check for empty leaf in case we accidentally hit one */
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (cur == BVH::emptyNode)
|
||||
goto pop;
|
||||
|
||||
/*! this is a leaf node */
|
||||
STAT3(normal.trav_leaves, 1, 1, 1);
|
||||
size_t num; Primitive* prim = (Primitive*)cur.leaf(num);
|
||||
|
||||
@@ -261,8 +265,12 @@ namespace embree
|
||||
m_trav_active = intersectAlignedNodePacket(packet, minX, minY, minZ, maxX, maxY, maxZ, m_trav_active);
|
||||
}
|
||||
|
||||
/*! this is a leaf node */
|
||||
/*! check for empty leaf in case we accidentally hit one */
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (cur == BVH::emptyNode)
|
||||
goto pop;
|
||||
|
||||
/*! this is a leaf node */
|
||||
STAT3(normal.trav_leaves, 1, 1, 1);
|
||||
size_t num; Primitive* prim = (Primitive*)cur.leaf(num);
|
||||
|
||||
|
||||
@@ -89,12 +89,14 @@ namespace embree
|
||||
|
||||
virtual const BBox3fa leafBounds (NodeRef& ref) const
|
||||
{
|
||||
size_t num; char* prim = ref.leaf(num);
|
||||
size_t ty; Primitive* prim = (Primitive*) ref.leaf(ty);
|
||||
if (unlikely(ref == BVH::emptyNode)) return empty;
|
||||
|
||||
BBox3fa bounds = empty;
|
||||
for (size_t i=0; i<num; i++)
|
||||
bounds.extend(((Primitive*)prim)[i].update(mesh));
|
||||
for (size_t i=0;; i++) {
|
||||
bounds.extend(prim[i].update(mesh));
|
||||
if (prim[i].last()) break;
|
||||
}
|
||||
return bounds;
|
||||
}
|
||||
|
||||
|
||||
@@ -154,11 +154,15 @@ namespace embree
|
||||
}
|
||||
else if (node.isLeaf())
|
||||
{
|
||||
size_t num; const char* tri = node.leaf(num);
|
||||
if (num)
|
||||
size_t ty; const char* tri = node.leaf(ty);
|
||||
if (node != BVH::emptyNode)
|
||||
{
|
||||
for (size_t i=0; i<num; i++) {
|
||||
s.statLeaf.numPrims += bvh->primTy->size(tri+i*bvh->primTy->bytes);
|
||||
size_t num = 0;
|
||||
while (true) {
|
||||
const char* cur = tri+num*bvh->primTy->bytes;
|
||||
s.statLeaf.numPrims += bvh->primTy->size(cur);
|
||||
num++;
|
||||
if (bvh->primTy->last(cur)) break;
|
||||
}
|
||||
s.statLeaf.numLeaves++;
|
||||
s.statLeaf.numPrimBlocks += num;
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace embree
|
||||
struct Type : public PrimitiveType {
|
||||
Type ();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -43,17 +44,20 @@ namespace embree
|
||||
__forceinline Bezier1i () {}
|
||||
|
||||
/*! Construction from vertices and IDs. */
|
||||
__forceinline Bezier1i (const unsigned vertexID, const unsigned geomID, const unsigned primID)
|
||||
: vertexID(vertexID), geom(geomID), prim(primID) {}
|
||||
__forceinline Bezier1i (const unsigned vertexID, const unsigned geomID, const unsigned primID, const bool last)
|
||||
: vertexID(vertexID), geom(geomID | (unsigned(last) << 31)), prim(primID) {}
|
||||
|
||||
/*! checks if this is the last primitive */
|
||||
__forceinline unsigned last() const { return geom & 0x80000000; }
|
||||
|
||||
/*! returns geometry ID */
|
||||
__forceinline unsigned geomID() const { return geom; }
|
||||
__forceinline unsigned geomID() const { return geom & 0x7FFFFFFF; }
|
||||
|
||||
/*! returns primitive ID */
|
||||
__forceinline unsigned primID() const { return prim; }
|
||||
|
||||
/*! fill curve from curve list */
|
||||
__forceinline void fill(const PrimRef* prims, size_t& i, size_t end, Scene* scene)
|
||||
__forceinline void fill(const PrimRef* prims, size_t& i, size_t end, Scene* scene, bool last)
|
||||
{
|
||||
const PrimRef& prim = prims[i];
|
||||
i++;
|
||||
@@ -61,11 +65,11 @@ namespace embree
|
||||
const unsigned primID = prim.primID();
|
||||
const NativeCurves* curves = scene->get<NativeCurves>(geomID);
|
||||
const unsigned vertexID = curves->curve(primID);
|
||||
new (this) Bezier1i(vertexID,geomID,primID);
|
||||
new (this) Bezier1i(vertexID,geomID,primID,last);
|
||||
}
|
||||
|
||||
/*! fill curve from curve list */
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& i, size_t end, Scene* scene, const BBox1f time_range)
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& i, size_t end, Scene* scene, const BBox1f time_range, bool last)
|
||||
{
|
||||
const PrimRefMB& prim = prims[i];
|
||||
i++;
|
||||
@@ -73,7 +77,7 @@ namespace embree
|
||||
const unsigned primID = prim.primID();
|
||||
const NativeCurves* curves = scene->get<NativeCurves>(geomID);
|
||||
const unsigned vertexID = curves->curve(primID);
|
||||
new (this) Bezier1i(vertexID,geomID,primID);
|
||||
new (this) Bezier1i(vertexID,geomID,primID,last);
|
||||
return curves->linearBounds(primID,time_range);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace embree
|
||||
{
|
||||
Type ();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -45,8 +46,13 @@ namespace embree
|
||||
__forceinline Bezier1v () {}
|
||||
|
||||
/*! Construction from vertices and IDs. */
|
||||
__forceinline Bezier1v (const Vec3fa& p0, const Vec3fa& p1, const Vec3fa& p2, const Vec3fa& p3, const unsigned int geomID, const unsigned int primID)
|
||||
: p0(p0), p1(p1), p2(p2), p3(p3), geom(geomID), prim(primID) {}
|
||||
__forceinline Bezier1v (const Vec3fa& p0, const Vec3fa& p1, const Vec3fa& p2, const Vec3fa& p3, const unsigned int geomID, const unsigned int primID, const bool last)
|
||||
: p0(p0), p1(p1), p2(p2), p3(p3), geom(geomID | (unsigned(last) << 31)), prim(primID) {}
|
||||
|
||||
/*! checks if this is the last primitive */
|
||||
__forceinline unsigned last() const {
|
||||
return geom & 0x80000000;
|
||||
}
|
||||
|
||||
/*! return primitive ID */
|
||||
__forceinline unsigned int primID() const {
|
||||
@@ -55,11 +61,11 @@ namespace embree
|
||||
|
||||
/*! return geometry ID */
|
||||
__forceinline unsigned int geomID() const {
|
||||
return geom;
|
||||
return geom & 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
/*! fill triangle from triangle list */
|
||||
__forceinline void fill(const PrimRef* prims, size_t& i, size_t end, Scene* scene)
|
||||
__forceinline void fill(const PrimRef* prims, size_t& i, size_t end, Scene* scene, bool last)
|
||||
{
|
||||
const PrimRef& prim = prims[i];
|
||||
i++;
|
||||
@@ -71,7 +77,7 @@ namespace embree
|
||||
const Vec3fa& p1 = curves->vertex(id+1);
|
||||
const Vec3fa& p2 = curves->vertex(id+2);
|
||||
const Vec3fa& p3 = curves->vertex(id+3);
|
||||
new (this) Bezier1v(p0,p1,p2,p3,geomID,primID);
|
||||
new (this) Bezier1v(p0,p1,p2,p3,geomID,primID,last);
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& cout, const Bezier1v& b)
|
||||
|
||||
@@ -212,7 +212,7 @@ namespace embree
|
||||
if (Mx > M) valid &= (1<<M)-1;
|
||||
hit.finalize();
|
||||
size_t i = select_min(valid,hit.vt);
|
||||
int geomID = geomIDs[i];
|
||||
int geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
int instID = context->geomID_to_instID ? context->geomID_to_instID[0] : geomID;
|
||||
/* intersection filter test */
|
||||
#if defined(EMBREE_INTERSECTION_FILTER) || defined(EMBREE_RAY_MASK)
|
||||
@@ -223,7 +223,7 @@ namespace embree
|
||||
if (unlikely(none(valid))) return foundhit;
|
||||
i = select_min(valid,hit.vt);
|
||||
|
||||
geomID = geomIDs[i];
|
||||
geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
instID = context->geomID_to_instID ? context->geomID_to_instID[0] : geomID;
|
||||
entry:
|
||||
Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
|
||||
@@ -291,7 +291,7 @@ namespace embree
|
||||
if (Mx > M) valid &= (1<<M)-1;
|
||||
hit.finalize();
|
||||
size_t i = select_min(valid,hit.vt);
|
||||
int geomID = geomIDs[i];
|
||||
int geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
int instID = context->geomID_to_instID ? context->geomID_to_instID[0] : geomID;
|
||||
|
||||
/* intersection filter test */
|
||||
@@ -303,7 +303,7 @@ namespace embree
|
||||
if (unlikely(none(valid))) return foundhit;
|
||||
i = select_min(valid,hit.vt);
|
||||
|
||||
geomID = geomIDs[i];
|
||||
geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
instID = context->geomID_to_instID ? context->geomID_to_instID[0] : geomID;
|
||||
entry:
|
||||
Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
|
||||
@@ -374,7 +374,7 @@ namespace embree
|
||||
entry:
|
||||
size_t i=__bsf(m);
|
||||
|
||||
const int geomID = geomIDs[i];
|
||||
const int geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
const int instID = context->geomID_to_instID ? context->geomID_to_instID[0] : geomID;
|
||||
Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
|
||||
|
||||
@@ -539,7 +539,7 @@ namespace embree
|
||||
|
||||
std::tie(u,v,t,Ng) = hit();
|
||||
|
||||
const int geomID = geomIDs[i];
|
||||
const int geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
const int primID = primIDs[i];
|
||||
Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
|
||||
|
||||
@@ -596,7 +596,7 @@ namespace embree
|
||||
|
||||
/* ray masking test */
|
||||
Scene* scene = context->scene;
|
||||
const int geomID = geomIDs[i];
|
||||
const int geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
const int primID = primIDs[i];
|
||||
Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
|
||||
#if defined(EMBREE_RAY_MASK)
|
||||
@@ -749,7 +749,7 @@ namespace embree
|
||||
if (Mx > M) valid &= (1<<M)-1;
|
||||
size_t i = select_min(valid,hit.vt);
|
||||
assert(i<M);
|
||||
int geomID = geomIDs[i];
|
||||
int geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
|
||||
/* intersection filter test */
|
||||
#if defined(EMBREE_INTERSECTION_FILTER) || defined(EMBREE_RAY_MASK)
|
||||
@@ -760,7 +760,7 @@ namespace embree
|
||||
if (unlikely(none(valid))) return foundhit;
|
||||
i = select_min(valid,hit.vt);
|
||||
assert(i<M);
|
||||
geomID = geomIDs[i];
|
||||
geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
entry:
|
||||
Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
|
||||
|
||||
@@ -842,7 +842,7 @@ namespace embree
|
||||
entry:
|
||||
size_t i=__bsf(m);
|
||||
|
||||
const int geomID = geomIDs[i];
|
||||
const int geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
|
||||
|
||||
#if defined(EMBREE_RAY_MASK)
|
||||
|
||||
@@ -31,28 +31,31 @@ namespace embree
|
||||
|
||||
static const bool validIntersectorK = false; // FIXME: why do we need this
|
||||
|
||||
static __forceinline void intersect(Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
|
||||
static __forceinline void intersect(Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
|
||||
{
|
||||
for (size_t i=0; i<num; i++)
|
||||
for (size_t i=0;; i++) {
|
||||
Intersector::intersect(pre,ray,context,prim[i]);
|
||||
if (prim[i].last()) break;
|
||||
}
|
||||
}
|
||||
|
||||
static __forceinline bool occluded(Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
|
||||
static __forceinline bool occluded(Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
|
||||
{
|
||||
for (size_t i=0; i<num; i++) {
|
||||
for (size_t i=0;; i++) {
|
||||
if (Intersector::occluded(pre,ray,context,prim[i]))
|
||||
return true;
|
||||
if (prim[i].last()) break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<int K>
|
||||
static __forceinline void intersectK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
|
||||
static __forceinline void intersectK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
|
||||
{
|
||||
}
|
||||
|
||||
template<int K>
|
||||
static __forceinline vbool<K> occludedK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
|
||||
static __forceinline vbool<K> occludedK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
|
||||
{
|
||||
return valid;
|
||||
}
|
||||
@@ -64,35 +67,39 @@ namespace embree
|
||||
typedef typename Intersector::Primitive Primitive;
|
||||
typedef typename Intersector::Precalculations Precalculations;
|
||||
|
||||
static __forceinline void intersect(const vbool<K>& valid, Precalculations& pre, RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
|
||||
static __forceinline void intersect(const vbool<K>& valid, Precalculations& pre, RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
|
||||
{
|
||||
for (size_t i=0; i<num; i++) {
|
||||
for (size_t i=0;; i++) {
|
||||
Intersector::intersect(valid,pre,ray,context,prim[i]);
|
||||
if (prim[i].last()) break;
|
||||
}
|
||||
}
|
||||
|
||||
static __forceinline vbool<K> occluded(const vbool<K>& valid, Precalculations& pre, RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
|
||||
static __forceinline vbool<K> occluded(const vbool<K>& valid, Precalculations& pre, RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
|
||||
{
|
||||
vbool<K> valid0 = valid;
|
||||
for (size_t i=0; i<num; i++) {
|
||||
for (size_t i=0;; i++) {
|
||||
valid0 &= !Intersector::occluded(valid0,pre,ray,context,prim[i]);
|
||||
if (none(valid0)) break;
|
||||
if (prim[i].last()) break;
|
||||
}
|
||||
return !valid0;
|
||||
}
|
||||
|
||||
static __forceinline void intersect(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
|
||||
static __forceinline void intersect(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
|
||||
{
|
||||
for (size_t i=0; i<num; i++) {
|
||||
for (size_t i=0;; i++) {
|
||||
Intersector::intersect(pre,ray,k,context,prim[i]);
|
||||
if (prim[i].last()) break;
|
||||
}
|
||||
}
|
||||
|
||||
static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
|
||||
static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
|
||||
{
|
||||
for (size_t i=0; i<num; i++) {
|
||||
for (size_t i=0;; i++) {
|
||||
if (Intersector::occluded(pre,ray,k,context,prim[i]))
|
||||
return true;
|
||||
if (prim[i].last()) break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -108,26 +115,27 @@ namespace embree
|
||||
|
||||
static const bool validIntersectorK = true;
|
||||
|
||||
static __forceinline void intersectK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const PrimitiveK* prim, size_t num, size_t& lazy_node)
|
||||
static __forceinline void intersectK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const PrimitiveK* prim, size_t ty, size_t& lazy_node)
|
||||
{
|
||||
PrecalculationsK pre(valid,ray); // FIXME: might cause trouble
|
||||
|
||||
for (size_t i=0; i<num; i++) {
|
||||
for (size_t i=0; ; i++) {
|
||||
IntersectorK::intersect(valid,pre,ray,context,prim[i]);
|
||||
if (prim[i].last()) break;
|
||||
}
|
||||
}
|
||||
|
||||
static __forceinline vbool<K> occludedK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const PrimitiveK* prim, size_t num, size_t& lazy_node)
|
||||
static __forceinline vbool<K> occludedK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const PrimitiveK* prim, size_t ty, size_t& lazy_node)
|
||||
{
|
||||
PrecalculationsK pre(valid,ray); // FIXME: might cause trouble
|
||||
vbool<K> valid0 = valid;
|
||||
for (size_t i=0; i<num; i++) {
|
||||
for (size_t i=0; ; i++) {
|
||||
valid0 &= !IntersectorK::occluded(valid0,pre,ray,context,prim[i]);
|
||||
if (none(valid0)) break;
|
||||
if (prim[i].last()) break;
|
||||
}
|
||||
return !valid0;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+28
-18
@@ -28,6 +28,7 @@ namespace embree
|
||||
{
|
||||
Type();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -48,8 +49,11 @@ namespace embree
|
||||
__forceinline LineMi() { }
|
||||
|
||||
/* Construction from vertices and IDs */
|
||||
__forceinline LineMi(const vint<M>& v0, const vint<M>& geomIDs, const vint<M>& primIDs)
|
||||
: v0(v0), geomIDs(geomIDs), primIDs(primIDs) {}
|
||||
__forceinline LineMi(const vint<M>& v0, const vint<M>& geomIDs, const vint<M>& primIDs, const bool last)
|
||||
: v0(v0), geomIDs(geomIDs), primIDs(primIDs)
|
||||
{
|
||||
this->geomIDs[0] |= unsigned(last) << 31;
|
||||
}
|
||||
|
||||
/* Returns a mask that tells which line segments are valid */
|
||||
__forceinline vbool<M> valid() const { return primIDs != vint<M>(-1); }
|
||||
@@ -64,10 +68,16 @@ namespace embree
|
||||
/* Returns the number of stored line segments */
|
||||
__forceinline size_t size() const { return __bsf(~movemask(valid())); }
|
||||
|
||||
/*! checks if this is the last primitive */
|
||||
__forceinline unsigned last() const { return geomIDs[0] & 0x80000000; }
|
||||
|
||||
/* Returns the geometry IDs */
|
||||
__forceinline vint<M>& geomID() { return geomIDs; }
|
||||
__forceinline const vint<M>& geomID() const { return geomIDs; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i]; }
|
||||
__forceinline int geomID(const size_t i) const {
|
||||
assert(i<M);
|
||||
return geomIDs[i] & 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
/* Returns the primitive IDs */
|
||||
__forceinline vint<M>& primID() { return primIDs; }
|
||||
@@ -136,7 +146,7 @@ namespace embree
|
||||
|
||||
/* Fill line segment from line segment list */
|
||||
template<typename PrimRefT>
|
||||
__forceinline void fill(const PrimRefT* prims, size_t& begin, size_t end, Scene* scene)
|
||||
__forceinline void fill(const PrimRefT* prims, size_t& begin, size_t end, Scene* scene, bool last)
|
||||
{
|
||||
vint<M> geomID, primID;
|
||||
vint<M> v0;
|
||||
@@ -161,18 +171,18 @@ namespace embree
|
||||
if (begin<end) prim = &prims[begin];
|
||||
}
|
||||
|
||||
new (this) LineMi(v0,geomID,primID); // FIXME: use non temporal store
|
||||
new (this) LineMi(v0,geomID,primID,last); // FIXME: use non temporal store
|
||||
}
|
||||
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime)
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime, bool last)
|
||||
{
|
||||
fill(prims,begin,end,scene);
|
||||
fill(prims,begin,end,scene,last);
|
||||
return linearBounds(scene,itime);
|
||||
}
|
||||
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range)
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range, bool last)
|
||||
{
|
||||
fill(prims,begin,end,scene);
|
||||
fill(prims,begin,end,scene,last);
|
||||
return linearBounds(scene,time_range);
|
||||
}
|
||||
|
||||
@@ -193,7 +203,7 @@ namespace embree
|
||||
|
||||
/*! output operator */
|
||||
friend __forceinline std::ostream& operator<<(std::ostream& cout, const LineMi& line) {
|
||||
return cout << "Line" << M << "i {" << line.v0 << ", " << line.geomIDs << ", " << line.primIDs << "}";
|
||||
return cout << "Line" << M << "i {" << line.v0 << ", " << (line.geomIDs & 0x7FFFFFFF) << ", " << line.primIDs << "}";
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -208,10 +218,10 @@ namespace embree
|
||||
Vec4vf4& p1,
|
||||
const Scene* scene) const
|
||||
{
|
||||
const LineSegments* geom0 = scene->get<LineSegments>(geomID(0));
|
||||
const LineSegments* geom1 = scene->get<LineSegments>(geomID(1));
|
||||
const LineSegments* geom2 = scene->get<LineSegments>(geomID(2));
|
||||
const LineSegments* geom3 = scene->get<LineSegments>(geomID(3));
|
||||
const LineSegments* geom0 = scene->get<LineSegments>(geomIDs[0] & 0x7FFFFFFF);
|
||||
const LineSegments* geom1 = scene->get<LineSegments>(geomIDs[1]);
|
||||
const LineSegments* geom2 = scene->get<LineSegments>(geomIDs[2]);
|
||||
const LineSegments* geom3 = scene->get<LineSegments>(geomIDs[3]);
|
||||
|
||||
const vfloat4 a0 = vfloat4::loadu(geom0->vertexPtr(v0[0]));
|
||||
const vfloat4 a1 = vfloat4::loadu(geom1->vertexPtr(v0[1]));
|
||||
@@ -258,10 +268,10 @@ namespace embree
|
||||
const Scene* scene,
|
||||
float time) const
|
||||
{
|
||||
const LineSegments* geom0 = scene->get<LineSegments>(geomID(0));
|
||||
const LineSegments* geom1 = scene->get<LineSegments>(geomID(1));
|
||||
const LineSegments* geom2 = scene->get<LineSegments>(geomID(2));
|
||||
const LineSegments* geom3 = scene->get<LineSegments>(geomID(3));
|
||||
const LineSegments* geom0 = scene->get<LineSegments>(geomIDs[0] & 0x7FFFFFFF);
|
||||
const LineSegments* geom1 = scene->get<LineSegments>(geomIDs[1]);
|
||||
const LineSegments* geom2 = scene->get<LineSegments>(geomIDs[2]);
|
||||
const LineSegments* geom3 = scene->get<LineSegments>(geomIDs[3]);
|
||||
|
||||
const vfloat4 numTimeSegments(geom0->fnumTimeSegments, geom1->fnumTimeSegments, geom2->fnumTimeSegments, geom3->fnumTimeSegments);
|
||||
vfloat4 ftime;
|
||||
|
||||
+18
-10
@@ -26,6 +26,7 @@ namespace embree
|
||||
{
|
||||
Type ();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -43,42 +44,49 @@ namespace embree
|
||||
public:
|
||||
|
||||
/*! constructs a virtual object */
|
||||
Object (unsigned geomID, unsigned primID)
|
||||
: _geomID(geomID), _primID(primID) {}
|
||||
Object (unsigned geomID, unsigned primID, bool last)
|
||||
: _geomID(geomID | (unsigned(last) << 31)), _primID(primID) {}
|
||||
|
||||
__forceinline unsigned geomID() const {
|
||||
return _geomID;
|
||||
/*! checks if this is the last primitive */
|
||||
__forceinline unsigned last() const {
|
||||
return _geomID & 0x80000000;
|
||||
}
|
||||
|
||||
/*! returns geometry ID */
|
||||
__forceinline unsigned geomID() const {
|
||||
return _geomID & 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
/*! returns primitive ID */
|
||||
__forceinline unsigned primID() const {
|
||||
return _primID;
|
||||
}
|
||||
|
||||
/*! fill triangle from triangle list */
|
||||
__forceinline void fill(const PrimRef* prims, size_t& i, size_t end, Scene* scene)
|
||||
__forceinline void fill(const PrimRef* prims, size_t& i, size_t end, Scene* scene, bool last)
|
||||
{
|
||||
const PrimRef& prim = prims[i]; i++;
|
||||
new (this) Object(prim.geomID(), prim.primID());
|
||||
new (this) Object(prim.geomID(), prim.primID(),last);
|
||||
}
|
||||
|
||||
/*! fill triangle from triangle list */
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& i, size_t end, Scene* scene, size_t itime)
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& i, size_t end, Scene* scene, size_t itime, bool last)
|
||||
{
|
||||
const PrimRef& prim = prims[i]; i++;
|
||||
const unsigned geomID = prim.geomID();
|
||||
const unsigned primID = prim.primID();
|
||||
new (this) Object(geomID, primID);
|
||||
new (this) Object(geomID, primID,last);
|
||||
AccelSet* accel = (AccelSet*) scene->get(geomID);
|
||||
return accel->linearBounds(primID,itime);
|
||||
}
|
||||
|
||||
/*! fill triangle from triangle list */
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& i, size_t end, Scene* scene, const BBox1f time_range)
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& i, size_t end, Scene* scene, const BBox1f time_range, bool last)
|
||||
{
|
||||
const PrimRefMB& prim = prims[i]; i++;
|
||||
const unsigned geomID = prim.geomID();
|
||||
const unsigned primID = prim.primID();
|
||||
new (this) Object(geomID, primID);
|
||||
new (this) Object(geomID, primID,last);
|
||||
AccelSet* accel = (AccelSet*) scene->get(geomID);
|
||||
return accel->linearBounds(primID,time_range);
|
||||
}
|
||||
|
||||
@@ -38,6 +38,10 @@ namespace embree
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool Bezier1v::Type::last(const char* This) const {
|
||||
return ((Bezier1v*)This)->last();
|
||||
}
|
||||
|
||||
Bezier1v::Type Bezier1v::type;
|
||||
|
||||
/********************** Bezier1i **************************/
|
||||
@@ -49,6 +53,10 @@ namespace embree
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool Bezier1i::Type::last(const char* This) const {
|
||||
return ((Bezier1i*)This)->last();
|
||||
}
|
||||
|
||||
Bezier1i::Type Bezier1i::type;
|
||||
|
||||
/********************** Line4i **************************/
|
||||
@@ -62,6 +70,11 @@ namespace embree
|
||||
return ((Line4i*)This)->size();
|
||||
}
|
||||
|
||||
template<>
|
||||
bool Line4i::Type::last(const char* This) const {
|
||||
return ((Line4i*)This)->last();
|
||||
}
|
||||
|
||||
/********************** Triangle4 **************************/
|
||||
|
||||
template<>
|
||||
@@ -73,6 +86,11 @@ namespace embree
|
||||
return ((Triangle4*)This)->size();
|
||||
}
|
||||
|
||||
template<>
|
||||
bool Triangle4::Type::last(const char* This) const {
|
||||
return ((Triangle4*)This)->last();
|
||||
}
|
||||
|
||||
/********************** Triangle4v **************************/
|
||||
|
||||
template<>
|
||||
@@ -84,6 +102,11 @@ namespace embree
|
||||
return ((Triangle4v*)This)->size();
|
||||
}
|
||||
|
||||
template<>
|
||||
bool Triangle4v::Type::last(const char* This) const {
|
||||
return ((Triangle4v*)This)->last();
|
||||
}
|
||||
|
||||
/********************** Triangle4i **************************/
|
||||
|
||||
template<>
|
||||
@@ -95,6 +118,11 @@ namespace embree
|
||||
return ((Triangle4i*)This)->size();
|
||||
}
|
||||
|
||||
template<>
|
||||
bool Triangle4i::Type::last(const char* This) const {
|
||||
return ((Triangle4i*)This)->last();
|
||||
}
|
||||
|
||||
/********************** Triangle4vMB **************************/
|
||||
|
||||
template<>
|
||||
@@ -106,6 +134,11 @@ namespace embree
|
||||
return ((Triangle4vMB*)This)->size();
|
||||
}
|
||||
|
||||
template<>
|
||||
bool Triangle4vMB::Type::last(const char* This) const {
|
||||
return ((Triangle4vMB*)This)->last();
|
||||
}
|
||||
|
||||
/********************** Quad4v **************************/
|
||||
|
||||
template<>
|
||||
@@ -117,6 +150,11 @@ namespace embree
|
||||
return ((Quad4v*)This)->size();
|
||||
}
|
||||
|
||||
template<>
|
||||
bool Quad4v::Type::last(const char* This) const {
|
||||
return ((Quad4v*)This)->last();
|
||||
}
|
||||
|
||||
/********************** Quad4i **************************/
|
||||
|
||||
template<>
|
||||
@@ -128,6 +166,11 @@ namespace embree
|
||||
return ((Quad4i*)This)->size();
|
||||
}
|
||||
|
||||
template<>
|
||||
bool Quad4i::Type::last(const char* This) const {
|
||||
return ((Quad4i*)This)->last();
|
||||
}
|
||||
|
||||
/********************** SubdivPatch1 **************************/
|
||||
|
||||
SubdivPatch1Cached::Type::Type ()
|
||||
@@ -137,6 +180,10 @@ namespace embree
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool SubdivPatch1Cached::Type::last(const char* This) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
SubdivPatch1Cached::Type SubdivPatch1Cached::type;
|
||||
|
||||
/********************** SubdivPatch1Cached **************************/
|
||||
@@ -148,6 +195,10 @@ namespace embree
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool SubdivPatch1Cached::TypeCached::last(const char* This) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
SubdivPatch1Cached::TypeCached SubdivPatch1Cached::type_cached;
|
||||
|
||||
/********************** Virtual Object **************************/
|
||||
@@ -159,5 +210,9 @@ namespace embree
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool Object::Type::last(const char* This) const {
|
||||
return ((Object*)This)->last();
|
||||
}
|
||||
|
||||
Object::Type Object::type;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,9 @@ namespace embree
|
||||
/*! Returns the number of stored primitives in a block. */
|
||||
virtual size_t size(const char* This) const = 0;
|
||||
|
||||
/*! Returns if this is the last block in the leaf list. */
|
||||
virtual bool last(const char* This) const = 0;
|
||||
|
||||
public:
|
||||
std::string name; //!< name of this primitive type
|
||||
size_t bytes; //!< number of bytes of the triangle data
|
||||
|
||||
+33
-22
@@ -30,6 +30,7 @@ namespace embree
|
||||
{
|
||||
Type();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -55,8 +56,12 @@ namespace embree
|
||||
const vint<M>& v2,
|
||||
const vint<M>& v3,
|
||||
const vint<M>& geomIDs,
|
||||
const vint<M>& primIDs)
|
||||
: v0(v0),v1(v1), v2(v2), v3(v3), geomIDs(geomIDs), primIDs(primIDs) {}
|
||||
const vint<M>& primIDs,
|
||||
const bool last)
|
||||
: v0(v0),v1(v1), v2(v2), v3(v3), geomIDs(geomIDs), primIDs(primIDs)
|
||||
{
|
||||
this->geomIDs[0] |= unsigned(last) << 31;
|
||||
}
|
||||
|
||||
/* Returns a mask that tells which quads are valid */
|
||||
__forceinline vbool<M> valid() const { return primIDs != vint<M>(-1); }
|
||||
@@ -67,10 +72,16 @@ namespace embree
|
||||
/* Returns the number of stored quads */
|
||||
__forceinline size_t size() const { return __bsf(~movemask(valid())); }
|
||||
|
||||
/*! checks if this is the last primitive */
|
||||
__forceinline unsigned last() const { return geomIDs[0] & 0x80000000; }
|
||||
|
||||
/* Returns the geometry IDs */
|
||||
__forceinline vint<M>& geomID() { return geomIDs; }
|
||||
__forceinline const vint<M>& geomID() const { return geomIDs; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); assert(geomIDs[i] != -1); return geomIDs[i]; }
|
||||
__forceinline int geomID(const size_t i) const {
|
||||
assert(i<M);
|
||||
return geomIDs[i] & 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
/* Returns the primitive IDs */
|
||||
__forceinline vint<M>& primID() { return primIDs; }
|
||||
@@ -223,7 +234,7 @@ namespace embree
|
||||
|
||||
/* Fill quad from quad list */
|
||||
template<typename PrimRefT>
|
||||
__forceinline void fill(const PrimRefT* prims, size_t& begin, size_t end, Scene* scene)
|
||||
__forceinline void fill(const PrimRefT* prims, size_t& begin, size_t end, Scene* scene, bool last)
|
||||
{
|
||||
vint<M> geomID = -1, primID = -1;
|
||||
vint<M> v0 = zero, v1 = zero, v2 = zero, v3 = zero;
|
||||
@@ -256,23 +267,23 @@ namespace embree
|
||||
if (begin<end) prim = &prims[begin];
|
||||
}
|
||||
|
||||
new (this) QuadMi(v0,v1,v2,v3,geomID,primID); // FIXME: use non temporal store
|
||||
new (this) QuadMi(v0,v1,v2,v3,geomID,primID,last); // FIXME: use non temporal store
|
||||
}
|
||||
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime)
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime, bool last)
|
||||
{
|
||||
fill(prims, begin, end, scene);
|
||||
fill(prims, begin, end, scene, last);
|
||||
return linearBounds(scene, itime);
|
||||
}
|
||||
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range)
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range, bool last)
|
||||
{
|
||||
fill(prims, begin, end, scene);
|
||||
fill(prims, begin, end, scene, last);
|
||||
return linearBounds(scene, time_range);
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& cout, const QuadMi& quad) {
|
||||
return cout << "QuadMi<" << M << ">( v0 = " << quad.v0 << ", v1 = " << quad.v1 << ", v2 = " << quad.v2 << ", v3 = " << quad.v3 << ", geomID = " << quad.geomIDs << ", primID = " << quad.primIDs << " )";
|
||||
return cout << "QuadMi<" << M << ">( v0 = " << quad.v0 << ", v1 = " << quad.v1 << ", v2 = " << quad.v2 << ", v3 = " << quad.v3 << ", geomID = " << (quad.geomIDs & 0x7FFFFFFF) << ", primID = " << quad.primIDs << " )";
|
||||
}
|
||||
|
||||
/* Updates the primitive */
|
||||
@@ -313,10 +324,10 @@ namespace embree
|
||||
{
|
||||
prefetchL1(((char*)this)+0*64);
|
||||
prefetchL1(((char*)this)+1*64);
|
||||
const int* vertices0 = scene->vertices[geomID(0)];
|
||||
const int* vertices1 = scene->vertices[geomID(1)];
|
||||
const int* vertices2 = scene->vertices[geomID(2)];
|
||||
const int* vertices3 = scene->vertices[geomID(3)];
|
||||
const int* vertices0 = scene->vertices[geomIDs[0] & 0x7FFFFFFF];
|
||||
const int* vertices1 = scene->vertices[geomIDs[1]];
|
||||
const int* vertices2 = scene->vertices[geomIDs[2]];
|
||||
const int* vertices3 = scene->vertices[geomIDs[3]];
|
||||
const vfloat4 a0 = vfloat4::loadu(vertices0 + v0[0]);
|
||||
const vfloat4 a1 = vfloat4::loadu(vertices1 + v0[1]);
|
||||
const vfloat4 a2 = vfloat4::loadu(vertices2 + v0[2]);
|
||||
@@ -348,10 +359,10 @@ namespace embree
|
||||
const Scene *const scene) const // FIXME: why do we have this special path here and not for triangles?
|
||||
{
|
||||
const vint16 perm(0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15);
|
||||
const int* vertices0 = scene->vertices[geomID(0)];
|
||||
const int* vertices1 = scene->vertices[geomID(1)];
|
||||
const int* vertices2 = scene->vertices[geomID(2)];
|
||||
const int* vertices3 = scene->vertices[geomID(3)];
|
||||
const int* vertices0 = scene->vertices[geomIDs[0] & 0x7FFFFFFF];
|
||||
const int* vertices1 = scene->vertices[geomIDs[1]];
|
||||
const int* vertices2 = scene->vertices[geomIDs[2]];
|
||||
const int* vertices3 = scene->vertices[geomIDs[3]];
|
||||
|
||||
const vfloat4 a0 = vfloat4::loadu(vertices0 + v0[0]);
|
||||
const vfloat4 a1 = vfloat4::loadu(vertices1 + v0[1]);
|
||||
@@ -440,10 +451,10 @@ namespace embree
|
||||
const Scene *const scene,
|
||||
const float time) const
|
||||
{
|
||||
const QuadMesh* mesh0 = scene->get<QuadMesh>(geomID(0));
|
||||
const QuadMesh* mesh1 = scene->get<QuadMesh>(geomID(1));
|
||||
const QuadMesh* mesh2 = scene->get<QuadMesh>(geomID(2));
|
||||
const QuadMesh* mesh3 = scene->get<QuadMesh>(geomID(3));
|
||||
const QuadMesh* mesh0 = scene->get<QuadMesh>(geomIDs[0] & 0x7FFFFFFF);
|
||||
const QuadMesh* mesh1 = scene->get<QuadMesh>(geomIDs[1]);
|
||||
const QuadMesh* mesh2 = scene->get<QuadMesh>(geomIDs[2]);
|
||||
const QuadMesh* mesh3 = scene->get<QuadMesh>(geomIDs[3]);
|
||||
|
||||
const vfloat4 numTimeSegments(mesh0->fnumTimeSegments, mesh1->fnumTimeSegments, mesh2->fnumTimeSegments, mesh3->fnumTimeSegments);
|
||||
vfloat4 ftime;
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace embree
|
||||
{
|
||||
Type();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -46,8 +47,11 @@ namespace embree
|
||||
__forceinline QuadMv() {}
|
||||
|
||||
/* Construction from vertices and IDs */
|
||||
__forceinline QuadMv(const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, const vint<M>& geomIDs, const vint<M>& primIDs)
|
||||
: v0(v0), v1(v1), v2(v2), v3(v3), geomIDs(geomIDs), primIDs(primIDs) {}
|
||||
__forceinline QuadMv(const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, const vint<M>& geomIDs, const vint<M>& primIDs, const bool last)
|
||||
: v0(v0), v1(v1), v2(v2), v3(v3), geomIDs(geomIDs), primIDs(primIDs)
|
||||
{
|
||||
this->geomIDs[0] |= unsigned(last) << 31;
|
||||
}
|
||||
|
||||
/* Returns a mask that tells which quads are valid */
|
||||
__forceinline vbool<M> valid() const { return geomIDs != vint<M>(-1); }
|
||||
@@ -58,10 +62,13 @@ namespace embree
|
||||
/* Returns the number of stored quads */
|
||||
__forceinline size_t size() const { return __bsf(~movemask(valid())); }
|
||||
|
||||
/*! checks if this is the last primitive */
|
||||
__forceinline unsigned last() const { return geomIDs[0] & 0x80000000; }
|
||||
|
||||
/* Returns the geometry IDs */
|
||||
__forceinline vint<M>& geomID() { return geomIDs; }
|
||||
__forceinline const vint<M>& geomID() const { return geomIDs; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i]; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i] & 0x7FFFFFFF; }
|
||||
|
||||
/* Returns the primitive IDs */
|
||||
__forceinline vint<M> primID() { return primIDs; }
|
||||
@@ -104,7 +111,7 @@ namespace embree
|
||||
}
|
||||
|
||||
/* Fill quad from quad list */
|
||||
__forceinline void fill(const PrimRef* prims, size_t& begin, size_t end, Scene* scene)
|
||||
__forceinline void fill(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, bool last)
|
||||
{
|
||||
vint<M> vgeomID = -1, vprimID = -1;
|
||||
Vec3vf<M> v0 = zero, v1 = zero, v2 = zero, v3 = zero;
|
||||
@@ -127,7 +134,7 @@ namespace embree
|
||||
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
|
||||
v3.x[i] = p3.x; v3.y[i] = p3.y; v3.z[i] = p3.z;
|
||||
}
|
||||
QuadMv::store_nt(this,QuadMv(v0,v1,v2,v3,vgeomID,vprimID));
|
||||
QuadMv::store_nt(this,QuadMv(v0,v1,v2,v3,vgeomID,vprimID,last));
|
||||
}
|
||||
|
||||
/* Updates the primitive */
|
||||
@@ -140,7 +147,7 @@ namespace embree
|
||||
for (size_t i=0; i<M; i++)
|
||||
{
|
||||
if (primID(i) == -1) break;
|
||||
const unsigned geomId = geomID(i);
|
||||
const unsigned geomId = geomIDs[i]; // copies last bit
|
||||
const unsigned primId = primID(i);
|
||||
const QuadMesh::Quad& quad = mesh->quad(primId);
|
||||
const Vec3fa p0 = mesh->vertex(quad.v[0]);
|
||||
@@ -155,7 +162,7 @@ namespace embree
|
||||
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
|
||||
v3.x[i] = p3.x; v3.y[i] = p3.y; v3.z[i] = p3.z;
|
||||
}
|
||||
new (this) QuadMv(v0,v1,v2,v3,vgeomID,vprimID);
|
||||
QuadMv::store_nt(this,QuadMv(v0,v1,v2,v3,vgeomID,vprimID,false));
|
||||
return bounds;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace embree
|
||||
{
|
||||
Type ();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
|
||||
static Type type;
|
||||
@@ -36,6 +37,7 @@ namespace embree
|
||||
{
|
||||
TypeCached ();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
|
||||
static TypeCached type_cached;
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace embree
|
||||
{
|
||||
Type();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -48,8 +49,11 @@ namespace embree
|
||||
__forceinline TriangleM() {}
|
||||
|
||||
/* Construction from vertices and IDs */
|
||||
__forceinline TriangleM(const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const vint<M>& geomIDs, const vint<M>& primIDs)
|
||||
: v0(v0), e1(v0-v1), e2(v2-v0), geomIDs(geomIDs), primIDs(primIDs) {}
|
||||
__forceinline TriangleM(const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const vint<M>& geomIDs, const vint<M>& primIDs, const bool last)
|
||||
: v0(v0), e1(v0-v1), e2(v2-v0), geomIDs(geomIDs), primIDs(primIDs)
|
||||
{
|
||||
this->geomIDs[0] |= unsigned(last) << 31;
|
||||
}
|
||||
|
||||
/* Returns a mask that tells which triangles are valid */
|
||||
__forceinline vbool<M> valid() const { return geomIDs != vint<M>(-1); }
|
||||
@@ -60,10 +64,13 @@ namespace embree
|
||||
/* Returns the number of stored triangles */
|
||||
__forceinline size_t size() const { return __bsf(~movemask(valid())); }
|
||||
|
||||
/*! checks if this is the last primitive */
|
||||
__forceinline unsigned last() const { return geomIDs[0] & 0x80000000; }
|
||||
|
||||
/* Returns the geometry IDs */
|
||||
__forceinline vint<M>& geomID() { return geomIDs; }
|
||||
__forceinline const vint<M>& geomID() const { return geomIDs; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i]; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i] & 0x7FFFFFFF; }
|
||||
|
||||
/* Returns the primitive IDs */
|
||||
__forceinline vint<M>& primID() { return primIDs; }
|
||||
@@ -106,7 +113,7 @@ namespace embree
|
||||
}
|
||||
|
||||
/* Fill triangle from triangle list */
|
||||
__forceinline void fill(const PrimRef* prims, size_t& begin, size_t end, Scene* scene)
|
||||
__forceinline void fill(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, bool last)
|
||||
{
|
||||
vint<M> vgeomID = -1, vprimID = -1;
|
||||
Vec3vf<M> v0 = zero, v1 = zero, v2 = zero;
|
||||
@@ -127,7 +134,7 @@ namespace embree
|
||||
v1.x[i] = p1.x; v1.y[i] = p1.y; v1.z[i] = p1.z;
|
||||
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
|
||||
}
|
||||
TriangleM::store_nt(this,TriangleM(v0,v1,v2,vgeomID,vprimID));
|
||||
TriangleM::store_nt(this,TriangleM(v0,v1,v2,vgeomID,vprimID,last));
|
||||
}
|
||||
|
||||
/* Updates the primitive */
|
||||
@@ -137,10 +144,10 @@ namespace embree
|
||||
vint<M> vgeomID = -1, vprimID = -1;
|
||||
Vec3vf<M> v0 = zero, v1 = zero, v2 = zero;
|
||||
|
||||
for (size_t i=0; i<M; i++)
|
||||
for (size_t i=0; i<M; i++)
|
||||
{
|
||||
if (unlikely(geomID(i) == -1)) break;
|
||||
const unsigned geomId = geomID(i);
|
||||
if (unlikely(!valid(i))) break;
|
||||
const unsigned geomId = geomIDs[i]; // copies last bit
|
||||
const unsigned primId = primID(i);
|
||||
const TriangleMesh::Triangle& tri = mesh->triangle(primId);
|
||||
const Vec3fa p0 = mesh->vertex(tri.v[0]);
|
||||
@@ -153,7 +160,7 @@ namespace embree
|
||||
v1.x[i] = p1.x; v1.y[i] = p1.y; v1.z[i] = p1.z;
|
||||
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
|
||||
}
|
||||
TriangleM::store_nt(this,TriangleM(v0,v1,v2,vgeomID,vprimID));
|
||||
TriangleM::store_nt(this,TriangleM(v0,v1,v2,vgeomID,vprimID,false));
|
||||
return bounds;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ namespace embree
|
||||
{
|
||||
Type();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -54,8 +55,12 @@ namespace embree
|
||||
const vint<M>& v1,
|
||||
const vint<M>& v2,
|
||||
const vint<M>& geomIDs,
|
||||
const vint<M>& primIDs)
|
||||
: v0(v0), v1(v1), v2(v2), geomIDs(geomIDs), primIDs(primIDs) {}
|
||||
const vint<M>& primIDs,
|
||||
const bool last)
|
||||
: v0(v0), v1(v1), v2(v2), geomIDs(geomIDs), primIDs(primIDs)
|
||||
{
|
||||
this->geomIDs[0] |= unsigned(last) << 31;
|
||||
}
|
||||
|
||||
/* Returns a mask that tells which triangles are valid */
|
||||
__forceinline vbool<M> valid() const { return primIDs != vint<M>(-1); }
|
||||
@@ -66,9 +71,12 @@ namespace embree
|
||||
/* Returns the number of stored triangles */
|
||||
__forceinline size_t size() const { return __bsf(~movemask(valid())); }
|
||||
|
||||
/*! checks if this is the last primitive */
|
||||
__forceinline unsigned last() const { return geomIDs[0] & 0x80000000; }
|
||||
|
||||
/* Returns the geometry IDs */
|
||||
__forceinline vint<M> geomID() const { return geomIDs; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i]; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i] & 0x7FFFFFFF; }
|
||||
|
||||
/* Returns the primitive IDs */
|
||||
__forceinline vint<M> primID() const { return primIDs; }
|
||||
@@ -210,7 +218,7 @@ namespace embree
|
||||
|
||||
/* Fill triangle from triangle list */
|
||||
template<typename PrimRefT>
|
||||
__forceinline void fill(const PrimRefT* prims, size_t& begin, size_t end, Scene* scene)
|
||||
__forceinline void fill(const PrimRefT* prims, size_t& begin, size_t end, Scene* scene, bool last)
|
||||
{
|
||||
vint<M> geomID = -1, primID = -1;
|
||||
vint<M> v0 = zero, v1 = zero, v2 = zero;
|
||||
@@ -241,18 +249,18 @@ namespace embree
|
||||
if (begin<end) prim = &prims[begin];
|
||||
}
|
||||
|
||||
new (this) TriangleMi(v0,v1,v2,geomID,primID); // FIXME: use non temporal store
|
||||
new (this) TriangleMi(v0,v1,v2,geomID,primID,last); // FIXME: use non temporal store
|
||||
}
|
||||
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime)
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime, bool last)
|
||||
{
|
||||
fill(prims, begin, end, scene);
|
||||
fill(prims, begin, end, scene, last);
|
||||
return linearBounds(scene, itime);
|
||||
}
|
||||
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range)
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range, bool last)
|
||||
{
|
||||
fill(prims, begin, end, scene);
|
||||
fill(prims, begin, end, scene, last);
|
||||
return linearBounds(scene, time_range);
|
||||
}
|
||||
|
||||
@@ -288,10 +296,10 @@ namespace embree
|
||||
Vec3vf4& p2,
|
||||
const Scene* const scene) const
|
||||
{
|
||||
const int* vertices0 = scene->vertices[geomID(0)];
|
||||
const int* vertices1 = scene->vertices[geomID(1)];
|
||||
const int* vertices2 = scene->vertices[geomID(2)];
|
||||
const int* vertices3 = scene->vertices[geomID(3)];
|
||||
const int* vertices0 = scene->vertices[geomIDs[0] & 0x7FFFFFFF];
|
||||
const int* vertices1 = scene->vertices[geomIDs[1]];
|
||||
const int* vertices2 = scene->vertices[geomIDs[2]];
|
||||
const int* vertices3 = scene->vertices[geomIDs[3]];
|
||||
const vfloat4 a0 = vfloat4::loadu(vertices0 + v0[0]);
|
||||
const vfloat4 a1 = vfloat4::loadu(vertices1 + v0[1]);
|
||||
const vfloat4 a2 = vfloat4::loadu(vertices2 + v0[2]);
|
||||
@@ -347,10 +355,10 @@ namespace embree
|
||||
const Scene *const scene,
|
||||
const float time) const
|
||||
{
|
||||
const TriangleMesh* mesh0 = scene->get<TriangleMesh>(geomID(0));
|
||||
const TriangleMesh* mesh1 = scene->get<TriangleMesh>(geomID(1));
|
||||
const TriangleMesh* mesh2 = scene->get<TriangleMesh>(geomID(2));
|
||||
const TriangleMesh* mesh3 = scene->get<TriangleMesh>(geomID(3));
|
||||
const TriangleMesh* mesh0 = scene->get<TriangleMesh>(geomIDs[0] & 0x7FFFFFFF);
|
||||
const TriangleMesh* mesh1 = scene->get<TriangleMesh>(geomIDs[1]);
|
||||
const TriangleMesh* mesh2 = scene->get<TriangleMesh>(geomIDs[2]);
|
||||
const TriangleMesh* mesh3 = scene->get<TriangleMesh>(geomIDs[3]);
|
||||
|
||||
const vfloat4 numTimeSegments(mesh0->fnumTimeSegments, mesh1->fnumTimeSegments, mesh2->fnumTimeSegments, mesh3->fnumTimeSegments);
|
||||
vfloat4 ftime;
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace embree
|
||||
{
|
||||
Type();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -46,8 +47,11 @@ namespace embree
|
||||
__forceinline TriangleMv() {}
|
||||
|
||||
/* Construction from vertices and IDs */
|
||||
__forceinline TriangleMv(const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const vint<M>& geomIDs, const vint<M>& primIDs)
|
||||
: v0(v0), v1(v1), v2(v2), geomIDs(geomIDs), primIDs(primIDs) {}
|
||||
__forceinline TriangleMv(const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const vint<M>& geomIDs, const vint<M>& primIDs, const bool last)
|
||||
: v0(v0), v1(v1), v2(v2), geomIDs(geomIDs), primIDs(primIDs)
|
||||
{
|
||||
this->geomIDs[0] |= unsigned(last) << 31;
|
||||
}
|
||||
|
||||
/* Returns a mask that tells which triangles are valid */
|
||||
__forceinline vbool<M> valid() const { return geomIDs != vint<M>(-1); }
|
||||
@@ -58,10 +62,13 @@ namespace embree
|
||||
/* Returns the number of stored triangles */
|
||||
__forceinline size_t size() const { return __bsf(~movemask(valid())); }
|
||||
|
||||
/*! checks if this is the last primitive */
|
||||
__forceinline unsigned last() const { return geomIDs[0] & 0x80000000; }
|
||||
|
||||
/* Returns the geometry IDs */
|
||||
__forceinline vint<M>& geomID() { return geomIDs; }
|
||||
__forceinline const vint<M>& geomID() const { return geomIDs; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i]; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i] & 0x7FFFFFFF; }
|
||||
|
||||
/* Returns the primitive IDs */
|
||||
__forceinline vint<M>& primID() { return primIDs; }
|
||||
@@ -101,7 +108,7 @@ namespace embree
|
||||
}
|
||||
|
||||
/* Fill triangle from triangle list */
|
||||
__forceinline void fill(const PrimRef* prims, size_t& begin, size_t end, Scene* scene)
|
||||
__forceinline void fill(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, bool last)
|
||||
{
|
||||
vint<M> vgeomID = -1, vprimID = -1;
|
||||
Vec3vf<M> v0 = zero, v1 = zero, v2 = zero;
|
||||
@@ -122,7 +129,7 @@ namespace embree
|
||||
v1.x[i] = p1.x; v1.y[i] = p1.y; v1.z[i] = p1.z;
|
||||
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
|
||||
}
|
||||
TriangleMv::store_nt(this,TriangleMv(v0,v1,v2,vgeomID,vprimID));
|
||||
TriangleMv::store_nt(this,TriangleMv(v0,v1,v2,vgeomID,vprimID,last));
|
||||
}
|
||||
|
||||
/* Updates the primitive */
|
||||
@@ -135,7 +142,7 @@ namespace embree
|
||||
for (size_t i=0; i<M; i++)
|
||||
{
|
||||
if (primID(i) == -1) break;
|
||||
const unsigned geomId = geomID(i);
|
||||
const unsigned geomId = geomIDs[i]; // copies last bit
|
||||
const unsigned primId = primID(i);
|
||||
const TriangleMesh::Triangle& tri = mesh->triangle(primId);
|
||||
const Vec3fa p0 = mesh->vertex(tri.v[0]);
|
||||
@@ -148,7 +155,7 @@ namespace embree
|
||||
v1.x[i] = p1.x; v1.y[i] = p1.y; v1.z[i] = p1.z;
|
||||
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
|
||||
}
|
||||
new (this) TriangleMv(v0,v1,v2,vgeomID,vprimID);
|
||||
new (this) TriangleMv(v0,v1,v2,vgeomID,vprimID,false);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace embree
|
||||
{
|
||||
Type();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
|
||||
static Type type;
|
||||
@@ -53,8 +54,12 @@ namespace embree
|
||||
__forceinline TriangleMvMB(const Vec3vf<M>& a0, const Vec3vf<M>& a1,
|
||||
const Vec3vf<M>& b0, const Vec3vf<M>& b1,
|
||||
const Vec3vf<M>& c0, const Vec3vf<M>& c1,
|
||||
const vint<M>& geomIDs, const vint<M>& primIDs)
|
||||
: v0(a0), v1(b0), v2(c0), dv0(a1-a0), dv1(b1-b0), dv2(c1-c0), geomIDs(geomIDs), primIDs(primIDs) {}
|
||||
const vint<M>& geomIDs, const vint<M>& primIDs,
|
||||
const bool last)
|
||||
: v0(a0), v1(b0), v2(c0), dv0(a1-a0), dv1(b1-b0), dv2(c1-c0), geomIDs(geomIDs), primIDs(primIDs)
|
||||
{
|
||||
this->geomIDs[0] |= unsigned(last) << 31;
|
||||
}
|
||||
|
||||
/* Returns a mask that tells which triangles are valid */
|
||||
__forceinline vbool<M> valid() const { return geomIDs != vint<M>(-1); }
|
||||
@@ -65,10 +70,13 @@ namespace embree
|
||||
/* Returns the number of stored triangles */
|
||||
__forceinline size_t size() const { return __bsf(~movemask(valid())); }
|
||||
|
||||
/*! checks if this is the last primitive */
|
||||
__forceinline unsigned last() const { return geomIDs[0] & 0x80000000; }
|
||||
|
||||
/* Returns the geometry IDs */
|
||||
__forceinline vint<M>& geomID() { return geomIDs; }
|
||||
__forceinline const vint<M>& geomID() const { return geomIDs; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i]; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i] & 0x7FFFFFFF; }
|
||||
|
||||
/* Returns the primitive IDs */
|
||||
__forceinline vint<M>& primID() { return primIDs; }
|
||||
@@ -116,7 +124,7 @@ namespace embree
|
||||
}
|
||||
|
||||
/* Fill triangle from triangle list */
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime)
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime, bool last)
|
||||
{
|
||||
vint<M> vgeomID = -1, vprimID = -1;
|
||||
Vec3vf<M> va0 = zero, vb0 = zero, vc0 = zero;
|
||||
@@ -147,12 +155,12 @@ namespace embree
|
||||
vc0.x[i] = c0.x; vc0.y[i] = c0.y; vc0.z[i] = c0.z;
|
||||
vc1.x[i] = c1.x; vc1.y[i] = c1.y; vc1.z[i] = c1.z;
|
||||
}
|
||||
new (this) TriangleMvMB(va0,va1,vb0,vb1,vc0,vc1,vgeomID,vprimID);
|
||||
new (this) TriangleMvMB(va0,va1,vb0,vb1,vc0,vc1,vgeomID,vprimID,last);
|
||||
return LBBox3fa(bounds0,bounds1);
|
||||
}
|
||||
|
||||
/* Fill triangle from triangle list */
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range)
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range, bool last)
|
||||
{
|
||||
vint<M> vgeomID = -1, vprimID = -1;
|
||||
Vec3vf<M> va0 = zero, vb0 = zero, vc0 = zero;
|
||||
@@ -190,7 +198,7 @@ namespace embree
|
||||
vc0.x[i] = c01.first .x; vc0.y[i] = c01.first .y; vc0.z[i] = c01.first .z;
|
||||
vc1.x[i] = c01.second.x; vc1.y[i] = c01.second.y; vc1.z[i] = c01.second.z;
|
||||
}
|
||||
new (this) TriangleMvMB(va0,va1,vb0,vb1,vc0,vc1,vgeomID,vprimID);
|
||||
new (this) TriangleMvMB(va0,va1,vb0,vb1,vc0,vc1,vgeomID,vprimID,last);
|
||||
return allBounds;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user