Exemplo n.º 1
0
bool AssemblyLeafProbeVisitor::visit(
    const vector<UniqueID>&             items,
    const vector<GAABB3>&               bboxes,
    const size_t                        begin,
    const size_t                        end,
    const ShadingRay::RayType&          ray,
    const ShadingRay::RayInfoType&      /*ray_info*/,
    const double                        tmin,
    const double                        tmax,
    double&                             distance)
{
    assert(begin + 1 == end);

    // Retrieve the assembly instance.
    const AssemblyInstance* assembly_instance =
        m_tree.m_scene.assembly_instances().get_by_uid(items[begin]);
    assert(assembly_instance);

    ShadingRay::RayType local_ray;
    local_ray.m_tmin = tmin;
    local_ray.m_tmax = tmax;

    // Transform the ray to assembly instance space.
    transform_ray_to_assembly_instance_space(
        assembly_instance,
        m_parent_shading_point,
        ray,
        local_ray);

    const RayInfo3d local_ray_info(local_ray);

    if (assembly_instance->get_assembly().is_flushable())
    {
        // Retrieve the region tree of this assembly.
        const RegionTree& region_tree =
            *m_region_tree_cache.access(
                assembly_instance->get_assembly_uid(),
                m_tree.m_region_trees);

        // Check the intersection between the ray and the region tree.
        RegionLeafProbeVisitor visitor(
            m_triangle_tree_cache
#ifdef FOUNDATION_BSP_ENABLE_TRAVERSAL_STATS
            , m_triangle_bsp_stats
#endif
            );
        RegionLeafProbeIntersector intersector;
#ifdef FOUNDATION_BSP_ENABLE_TRAVERSAL_STATS
        bsp::TraversalStatistics stats;
        intersector.intersect(
            region_tree,
            local_ray,
            local_ray_info,
            visitor,
            stats);
#else
        intersector.intersect(
            region_tree,
            local_ray,
            local_ray_info,
            visitor);
#endif
        
        // Terminate traversal if there was a hit.
        if (visitor.hit())
        {
            m_hit = true;
            return false;
        }
    }
    else
    {
        // Retrieve the triangle tree of this leaf.
        const TriangleTree* triangle_tree =
            m_triangle_tree_cache.access(
                assembly_instance->get_assembly_uid(),
                m_tree.m_triangle_trees);

        if (triangle_tree)
        {
            // Check the intersection between the ray and the triangle tree.
            TriangleLeafProbeVisitor visitor;
            TriangleLeafProbeIntersector intersector;
            intersector.intersect(
                *triangle_tree,
                local_ray,
                local_ray_info,
                visitor
#ifdef FOUNDATION_BSP_ENABLE_TRAVERSAL_STATS
                , m_triangle_bsp_stats
#endif
                );

            // Terminate traversal if there was a hit.
            if (visitor.hit())
            {
                m_hit = true;
                return false;
            }
        }
    }

    // Continue traversal.
    distance = ray.m_tmax;
    return true;
}
Exemplo n.º 2
0
bool AssemblyLeafProbeVisitor::visit(
    const AssemblyTree::NodeType&       node,
    const ShadingRay&                   ray,
    const ShadingRay::RayInfoType&      ray_info,
    double&                             distance
#ifdef FOUNDATION_BVH_ENABLE_TRAVERSAL_STATS
    , bvh::TraversalStatistics&         stats
#endif
    )
{
    // Retrieve the assembly instances for this leaf.
    const size_t assembly_instance_count = node.get_item_count();
    const AssemblyInstance* const* assembly_instances =
        assembly_instance_count <= AssemblyTree::NodeType::MaxUserDataSize / sizeof(AssemblyInstance*)
            ? &node.get_user_data<const AssemblyInstance*>()            // items are stored in the leaf node
            : &m_tree.m_assembly_instances[node.get_item_index()];      // items are stored in the tree

    for (size_t i = 0; i < assembly_instance_count; ++i)
    {
        // Retrieve the assembly instance.
        const AssemblyInstance* assembly_instance = assembly_instances[i];

        // Evaluate the transformation of the assembly instance.
        const Transformd assembly_instance_transform =
            assembly_instance->transform_sequence().evaluate(ray.m_time);

        // Transform the ray to assembly instance space.
        ShadingRay local_ray;
        transform_ray_to_assembly_instance_space(
            assembly_instance,
            assembly_instance_transform,
            m_parent_shading_point,
            ray,
            local_ray);
        local_ray.m_tmin = ray.m_tmin;
        local_ray.m_tmax = ray.m_tmax;
        local_ray.m_time = ray.m_time;
        local_ray.m_flags = ray.m_flags;
        const RayInfo3d local_ray_info(local_ray);

        FOUNDATION_BVH_TRAVERSAL_STATS(stats.m_intersected_items.insert(1));

        if (assembly_instance->get_assembly().is_flushable())
        {
            // Retrieve the region tree of this assembly.
            const RegionTree& region_tree =
                *m_region_tree_cache.access(
                    assembly_instance->get_assembly().get_uid(),
                    m_tree.m_region_trees);

            // Check the intersection between the ray and the region tree.
            RegionLeafProbeVisitor visitor(
                m_triangle_tree_cache
#ifdef FOUNDATION_BVH_ENABLE_TRAVERSAL_STATS
                , m_triangle_tree_stats
#endif
                );
            RegionLeafProbeIntersector intersector;
            intersector.intersect(
                region_tree,
                local_ray,
                local_ray_info,
                visitor);
        
            // Terminate traversal if there was a hit.
            if (visitor.hit())
            {
                m_hit = true;
                return false;
            }
        }
        else
        {
            // Retrieve the triangle tree of this leaf.
            const TriangleTree* triangle_tree =
                m_triangle_tree_cache.access(
                    assembly_instance->get_assembly().get_uid(),
                    m_tree.m_triangle_trees);

            if (triangle_tree)
            {
                // Check the intersection between the ray and the triangle tree.
                TriangleTreeProbeIntersector intersector;
                TriangleLeafProbeVisitor visitor(*triangle_tree);
                intersector.intersect(
                    *triangle_tree,
                    local_ray,
                    local_ray_info,
                    local_ray.m_time,
                    visitor
#ifdef FOUNDATION_BVH_ENABLE_TRAVERSAL_STATS
                    , m_triangle_tree_stats
#endif
                    );

                // Terminate traversal if there was a hit.
                if (visitor.hit())
                {
                    m_hit = true;
                    return false;
                }
            }
        }
    }

    // Continue traversal.
    distance = ray.m_tmax;
    return true;
}
Exemplo n.º 3
0
bool AssemblyLeafVisitor::visit(
    const vector<UniqueID>&             items,
    const vector<GAABB3>&               bboxes,
    const size_t                        begin,
    const size_t                        end,
    const ShadingRay::RayType&          ray,
    const ShadingRay::RayInfoType&      /*ray_info*/,
    const double                        tmin,
    const double                        tmax,
    double&                             distance)
{
    assert(begin + 1 == end);

    // Retrieve the assembly instance.
    const AssemblyInstance* assembly_instance =
        m_tree.m_scene.assembly_instances().get_by_uid(items[begin]);
    assert(assembly_instance);

    ShadingPoint result;
    result.m_ray.m_tmin = tmin;
    result.m_ray.m_tmax = tmax;
    result.m_ray.m_time = m_shading_point.m_ray.m_time;
    result.m_ray.m_flags = m_shading_point.m_ray.m_flags;

    // Transform the ray to assembly instance space.
    transform_ray_to_assembly_instance_space(
        assembly_instance,
        m_parent_shading_point,
        ray,
        result.m_ray);

    const RayInfo3d ray_info(result.m_ray);

    if (assembly_instance->get_assembly().is_flushable())
    {
        // Retrieve the region tree of this assembly.
        const RegionTree& region_tree =
            *m_region_tree_cache.access(
                assembly_instance->get_assembly_uid(),
                m_tree.m_region_trees);

        // Check the intersection between the ray and the region tree.
        RegionLeafVisitor visitor(
            result,
            m_triangle_tree_cache
#ifdef FOUNDATION_BSP_ENABLE_TRAVERSAL_STATS
            , m_triangle_bsp_stats
#endif
            );
        RegionLeafIntersector intersector;
#ifdef FOUNDATION_BSP_ENABLE_TRAVERSAL_STATS
        bsp::TraversalStatistics stats;
        intersector.intersect(
            region_tree,
            result.m_ray,
            ray_info,
            visitor,
            stats);
#else
        intersector.intersect(
            region_tree,
            result.m_ray,
            ray_info,
            visitor);
#endif
    }
    else
    {
        // Retrieve the triangle tree of this assembly.
        const TriangleTree* triangle_tree =
            m_triangle_tree_cache.access(
                assembly_instance->get_assembly_uid(),
                m_tree.m_triangle_trees);

        if (triangle_tree)
        {
            // Check the intersection between the ray and the triangle tree.
            TriangleLeafVisitor visitor(result);
            TriangleLeafIntersector intersector;
            intersector.intersect(
                *triangle_tree,
                result.m_ray,
                ray_info,
                visitor
#ifdef FOUNDATION_BSP_ENABLE_TRAVERSAL_STATS
                , m_triangle_bsp_stats
#endif
                );
            visitor.read_hit_triangle_data();
        }
    }

    // Keep track of the closest hit.
    if (result.m_hit && result.m_ray.m_tmax < m_shading_point.m_ray.m_tmax)
    {
        m_shading_point.m_ray.m_tmax = result.m_ray.m_tmax;
        m_shading_point.m_hit = true;
        m_shading_point.m_bary = result.m_bary;
        m_shading_point.m_asm_instance_uid = assembly_instance->get_uid();
        m_shading_point.m_object_instance_index = result.m_object_instance_index;
        m_shading_point.m_region_index = result.m_region_index;
        m_shading_point.m_triangle_index = result.m_triangle_index;
        m_shading_point.m_triangle_support_plane = result.m_triangle_support_plane;
    }

    // Continue traversal.
    distance = m_shading_point.m_ray.m_tmax;
    return true;
}