예제 #1
0
intersection3f intersect(BVHAccelerator* bvh, int nodeid, const ray3f& ray,
                         const intersect_func& intersect_elem) {
    // grab node
    auto& node = bvh->nodes[nodeid];
    // intersect bbox
    if(not intersect_bbox(ray, node.bbox)) return intersection3f();
    // recursively intersect nodes
    intersection3f intersection;
    // copy the ray to allow for shortening it
    auto sray = ray;
    if(node.leaf) {
        for(int idx = node.start; idx < node.end; idx ++) {
            auto i = bvh->prims[idx];
            intersection3f sintersection = intersect_elem(i,sray);
            if(not sintersection.hit) continue;
            if(sintersection.ray_t > intersection.ray_t and intersection.hit) continue;
            intersection = sintersection;
            sray.tmax = intersection.ray_t;
        }
    } else {
        for(auto n : { node.n0, node.n1 }) {
            intersection3f sintersection = intersect(bvh,n,sray,intersect_elem);
            if(not sintersection.hit) continue;
            if(sintersection.ray_t > intersection.ray_t and intersection.hit) continue;
            intersection = sintersection;
            sray.tmax = intersection.ray_t;
        }
    }
    return intersection;
}
예제 #2
0
bool intersect_shadow(BVHAccelerator* bvh, int nodeid, const ray3f& ray,
                      const intersect_func& intersect_elem_shadow) {
    // grab node
    auto& node = bvh->nodes[nodeid];
    // intersect bbox
    if(not intersect_bbox(ray, node.bbox)) return false;
    // recursively intersect nodes
    if(node.leaf) {
        // for(auto idx : range(node.start,node.end)) {
        for(int idx = node.start; idx < node.end; idx++) {
            auto i = bvh->prims[idx];
            if(intersect_elem_shadow(i,ray)) return true;
        }
    } else {
        if(intersect_shadow(bvh,node.n0,ray,intersect_elem_shadow)) return true;
        if(intersect_shadow(bvh,node.n1,ray,intersect_elem_shadow)) return true;
    }
    return false;
}
bool RayTracer::rayIntersectNodeShadow(const Vec3f& orig, const Vec3f& dir, const float maxval, const Node* node) const
{
	// Test whether the ray intersects the node's bounding box at all
	if (!intersect_bbox(&orig.x, &dir.x, &(node->bbMin).x, &(node->bbMax).x, maxval)) {
		return false;
	}

	// If the node is a leaf node
	if (!node->leftChild && !node->rightChild) {
		return rayIntersectTriangles(orig, dir, node->startPrim, node->endPrim).triangle ? true : false;
	}

	if (rayIntersectNodeShadow(orig, dir, maxval, node->leftChild))
		return true;
	if (rayIntersectNodeShadow(orig, dir, maxval, node->rightChild))
		return true;

	return false;
}
Hit RayTracer::rayIntersectNode(const Vec3f& orig, const Vec3f& dir, const float maxval, const Node* node) const
{
	// Test whether the ray intersects the node's bounding box at all
	if (!intersect_bbox(&orig.x, &dir.x, &(node->bbMin).x, &(node->bbMax).x, maxval)) {
		return Hit(NULL);
	}

	// If the node is a leaf node
	if (!node->leftChild && !node->rightChild) {
		return rayIntersectTriangles(orig, dir, node->startPrim, node->endPrim);
	}

	Hit left = rayIntersectNode(orig, dir, maxval, node->leftChild);
	Hit right = rayIntersectNode(orig, dir, maxval, node->rightChild);

	if (!left.triangle && !right.triangle)
		return Hit(NULL);
	else if (left.tmin < right.tmin)
		return left;
	else
		return right;
}
예제 #5
0
// intersect bounding box without returning bounds
inline bool intersect_bbox(const ray3f& ray, const range3f& bbox) {
    float t0, t1; return intersect_bbox(ray,bbox,t0,t1);
}