Compare commits

...
1 Commits
Author SHA1 Message Date
Sven Woop fdc8867102 Using highest bit in geomID to tag the last primitive in a leaf.
This makes 3 NodeRef bits available for leaf type encoding.
2017-09-06 14:32:51 +02:00
25 changed files with 360 additions and 565 deletions
+5 -5
View File
@@ -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 */
+2 -2
View File
@@ -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);
};
+5 -5
View File
@@ -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
+4 -4
View File
@@ -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);
}
+10 -2
View File
@@ -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;
+29 -9
View File
@@ -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();
}
}
}
-391
View File
@@ -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);
};
}
}
+10 -2
View File
@@ -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);
+5 -3
View File
@@ -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;
}
+8 -4
View File
@@ -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;
+11 -7
View File
@@ -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);
}
+11 -5
View File
@@ -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)
+10 -10
View File
@@ -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)
+27 -19
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
+55
View File
@@ -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;
}
+3
View File
@@ -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
View File
@@ -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;
+14 -7
View File
@@ -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;
}
+2
View File
@@ -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;
+16 -9
View File
@@ -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;
}
+25 -17
View File
@@ -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;
+14 -7
View File
@@ -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;
}
+15 -7
View File
@@ -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;
}