Пример #1
0
Файл: bvh.cpp Проект: AI42/OM3D
bool BVHAccel::IntersectQ(const Ray &ray, Intersection *isect, float* barycentrics) const {
    if (!nodes) return false;
    PBRT_BVH_INTERSECTION_STARTED(const_cast<BVHAccel *>(this), const_cast<Ray *>(&ray));	
    bool hit = false;
    //PbrtPoint origin = ray(ray.mint);
    Vector invDir(1.f / ray.d.x, 1.f / ray.d.y, 1.f / ray.d.z);
    uint32_t dirIsNeg[3] = { invDir.x < 0, invDir.y < 0, invDir.z < 0 };
    // Follow ray through BVH nodes to find primitive intersections
    uint32_t todoOffset = 0, nodeNum = 0;
    uint32_t todo[64];
	while (true) {
        const LinearBVHNode *node = &nodes[nodeNum];
        // Check ray against BVH node
        if (::IntersectP(node->bounds, ray, invDir, dirIsNeg)) {
            if (node->nPrimitives > 0) {
                // Intersect ray with primitives in leaf BVH node
                PBRT_BVH_INTERSECTION_TRAVERSED_LEAF_NODE(const_cast<LinearBVHNode *>(node));
                for (uint32_t i = 0; i < node->nPrimitives; ++i)
                {
                    PBRT_BVH_INTERSECTION_PRIMITIVE_TEST(const_cast<Primitive *>(primitives[node->primitivesOffset+i].GetPtr()));
                    if (primitives[node->primitivesOffset+i]->IntersectQ(ray, isect, barycentrics))
                    {
                        PBRT_BVH_INTERSECTION_PRIMITIVE_HIT(const_cast<Primitive *>(primitives[node->primitivesOffset+i].GetPtr()));
                        hit = true;
                    }
                    else {
                        PBRT_BVH_INTERSECTION_PRIMITIVE_MISSED(const_cast<Primitive *>(primitives[node->primitivesOffset+i].GetPtr()));
					}
                }
                if (todoOffset == 0) break;
                nodeNum = todo[--todoOffset];
            }
            else {
                // Put far BVH node on _todo_ stack, advance to near node
                PBRT_BVH_INTERSECTION_TRAVERSED_INTERIOR_NODE(const_cast<LinearBVHNode *>(node));
                if (dirIsNeg[node->axis]) {
					todo[todoOffset++] = nodeNum + 1;
					nodeNum = node->secondChildOffset;
                }
                else {
					todo[todoOffset++] = node->secondChildOffset;
					nodeNum = nodeNum + 1;
                }
            }
        }
        else {
            if (todoOffset == 0) break;
            nodeNum = todo[--todoOffset];
        }
    }
    PBRT_BVH_INTERSECTION_FINISHED();
	if (hit) {
		//printf("\t BVH Intersect: thit=%f\n", ray.maxt);
	}
    return hit;
}
Пример #2
0
bool EBVHAccel::Intersect(const Ray &ray, Intersection *isect) const {
    if (!nodes) return false;
    PBRT_BVH_INTERSECTION_STARTED(const_cast<EBVHAccel *>(this), const_cast<Ray *>(&ray));
    bool hit = false;
    Vector invDir(1.f / ray.d.x, 1.f / ray.d.y, 1.f / ray.d.z);
    uint32_t dirIsNeg[3] = { invDir.x < 0, invDir.y < 0, invDir.z < 0 };
    // Follow ray through EBVH nodes to find primitive intersections
    uint32_t todoOffset = 0, nodeNum = 0;
    uint32_t todo[64];

    std::stack<BBox> stackOfBoxes;
    stackOfBoxes.push(this->sceneBoundingBox);

    while (true) {
        LinearEBVHNode *node = &nodes[nodeNum];

        BBox myBBox = uncompressBBox(BBox(Point(node->bounds_x0, node->bounds_y0, node->bounds_z0), Point(node->bounds_x1, node->bounds_y1, node->bounds_z1)), stackOfBoxes.top());

        // Check ray against EBVH node
        if (::IntersectP(myBBox, ray, invDir, dirIsNeg)) {
            if (node->nPrimitives > 0) {
                // Intersect ray with primitives in leaf EBVH node
                PBRT_BVH_INTERSECTION_TRAVERSED_LEAF_NODE(const_cast<LinearEBVHNode *>(node));
                for (uint32_t i = 0; i < node->nPrimitives; ++i)
                {
                    PBRT_BVH_INTERSECTION_PRIMITIVE_TEST(const_cast<Primitive *>(primitives[node->primitivesOffset+i].GetPtr()));
                    if (primitives[node->primitivesOffset+i]->Intersect(ray, isect))
                    {
                        PBRT_BVH_INTERSECTION_PRIMITIVE_HIT(const_cast<Primitive *>(primitives[node->primitivesOffset+i].GetPtr()));
                        hit = true;
                    }
                    else {
                        PBRT_BVH_INTERSECTION_PRIMITIVE_MISSED(const_cast<Primitive *>(primitives[node->primitivesOffset+i].GetPtr()));
                   }
                }
                if (todoOffset == 0) break;
                todoOffset--;
                nodeNum = todo[todoOffset];
                stackOfBoxes.pop();
            }
            else {
                // Put far EBVH node on _todo_ stack, advance to near node
                PBRT_BVH_INTERSECTION_TRAVERSED_INTERIOR_NODE(const_cast<LinearEBVHNode *>(node));
                if (dirIsNeg[node->axis]) {
                   todo[todoOffset] = nodeNum + 1;
                   nodeNum = node->secondChildOffset;
                   stackOfBoxes.pop();
                   stackOfBoxes.push(myBBox);
                   stackOfBoxes.push(myBBox);
                   todoOffset++;
                }
                else {
                   todo[todoOffset] = node->secondChildOffset;
                   nodeNum = nodeNum + 1;
                   stackOfBoxes.pop();
                   stackOfBoxes.push(myBBox);
                   stackOfBoxes.push(myBBox);
                   todoOffset++;
                }
            }
        }
        else {
            if (todoOffset == 0) break;
            todoOffset--;
            nodeNum = todo[todoOffset];
            stackOfBoxes.pop();
        }
    }
    PBRT_BVH_INTERSECTION_FINISHED();
    return hit;
}