예제 #1
0
AOVoxelTree::AOVoxelTree(
    const Scene&    scene,
    const GScalar   max_extent_fraction)
{
    assert(max_extent_fraction > GScalar(0.0));

    // Print a progress message.
    RENDERER_LOG_INFO("building ambient occlusion voxel tree...");

    // Compute the bounding box of the scene.
    const GAABB3 scene_bbox = scene.compute_bbox();

    // Compute the maximum extent of a leaf, in world space.
    const GScalar max_extent = max_extent_fraction * max_value(scene_bbox.extent());

    // Build the tree.
    BuilderType builder(m_tree, scene_bbox, max_extent);
    build(scene, builder);
    builder.complete();

    // Print statistics.
    TreeStatisticsType tree_stats(m_tree, builder);
    RENDERER_LOG_DEBUG("ambient occlusion voxel tree statistics:");
    tree_stats.print(global_logger());
}
예제 #2
0
GAABB3 Assembly::compute_local_bbox() const
{
    GAABB3 bbox = compute_non_hierarchical_local_bbox();

    bbox.insert(
        compute_parent_bbox<GAABB3>(
            assembly_instances().begin(),
            assembly_instances().end()));

    return bbox;
}
void CameraController::slot_entity_picked(ScenePicker::PickingResult result)
{
    if (result.m_object_instance)
    {
        const GAABB3 object_instance_world_bbox =
            result.m_assembly_instance_transform.to_parent(
                result.m_object_instance->compute_parent_bbox());

        m_pivot = Vector3d(object_instance_world_bbox.center());
    }
    else
    {
        m_pivot = Vector3d(m_project.get_scene()->compute_bbox().center());
    }
}
예제 #4
0
    GAABB3 compute_bounds() const
    {
        GAABB3 bbox;
        bbox.invalidate();

        const size_t curve1_count = m_curves1.size();
        const size_t curve3_count = m_curves3.size();

        for (size_t i = 0; i < curve1_count; ++i)
            bbox.insert(m_curves1[i].compute_bbox());

        for (size_t i = 0; i < curve3_count; ++i)
            bbox.insert(m_curves3[i].compute_bbox());

        return bbox;
    }
예제 #5
0
double Scene::compute_radius() const
{
    double square_radius = 0.0;
    const GAABB3 bbox = compute_bbox();

    if (bbox.is_valid())
    {
        for (size_t i = 0; i < 8; ++i)
        {
            const double square_distance =
                static_cast<double>(square_norm(bbox.compute_corner(i)));

            square_radius = max(square_radius, square_distance);
        }
    }

    return sqrt(square_radius);
}
예제 #6
0
SPPMPassCallback::SPPMPassCallback(
    const Scene&            scene,
    const LightSampler&     light_sampler,
    const TraceContext&     trace_context,
    TextureStore&           texture_store,
#ifdef APPLESEED_WITH_OIIO
    OIIO::TextureSystem&    oiio_texture_system,
#endif
#ifdef APPLESEED_WITH_OSL
    OSL::ShadingSystem&     shading_system,
#endif
    const SPPMParameters&   params)
  : m_params(params)
  , m_photon_tracer(
        scene,
        light_sampler,
        trace_context,
        texture_store,
#ifdef APPLESEED_WITH_OIIO
        oiio_texture_system,
#endif
#ifdef APPLESEED_WITH_OSL
        shading_system,
#endif
        params)
  , m_pass_number(0)
{
    // Compute the initial lookup radius.
    const GAABB3 scene_bbox = scene.compute_bbox();
    const float scene_diameter =
        scene_bbox.is_valid()
            ? static_cast<float>(scene_bbox.diameter())
            : 0.0f;
    const float diameter_factor = m_params.m_initial_radius_percents / 100.0f;
    m_initial_lookup_radius = scene_diameter * diameter_factor;

    // Start with the initial lookup radius.
    m_lookup_radius = m_initial_lookup_radius;
}
예제 #7
0
double Scene::compute_radius() const
{
    double square_radius = 0.0;

    for (const_each<AssemblyInstanceContainer> i = impl->m_assembly_instances; i; ++i)
    {
        const AssemblyInstance& inst = *i;
        const GAABB3 inst_bbox = inst.compute_parent_bbox();

        GVector3 corners[8];
        inst_bbox.compute_corners(corners);

        for (size_t j = 0; j < 8; ++j)
        {
            const double square_distance = square_norm(corners[j]);

            if (square_radius < square_distance)
                square_radius = square_distance;
        }
    }

    return sqrt(square_radius);
}
void CameraController::configure_controller(const Scene* scene)
{
    Camera* camera = m_scene->get_camera();

    // Set the controller orientation and position based on the scene camera.
    m_controller.set_transform(
        camera->transform_sequence().get_earliest_transform().get_local_to_parent());

    if (camera->get_parameters().strings().exist("controller_target"))
    {
        // The camera already has a target position, use it.
        m_controller.set_target(
            camera->get_parameters().get_optional<Vector3d>(
                "controller_target",
                Vector3d(0.0)));
    }
    else
    {
        // Otherwise, if the scene is not empty, use its center as the target position.
        const GAABB3 scene_bbox = scene->compute_bbox();
        if (scene_bbox.is_valid())
            m_controller.set_target(Vector3d(scene_bbox.center()));
    }
}
예제 #9
0
GAABB3 Scene::compute_bbox() const
{
    const AssemblyInstanceContainer& instances = assembly_instances();
    const GAABB3 bbox = compute_parent_bbox<GAABB3>(instances.begin(), instances.end());
    return bbox.is_valid() ? bbox : GAABB3(GVector3(0.0f), GVector3(0.0f));
}
예제 #10
0
    // Partition a set of items into two distinct sets.
    // Return end if the set is not to be partitioned.
    size_t partition(
        vector<UniqueID>&   items,
        vector<GAABB3>&     bboxes,
        const size_t        begin,
        const size_t        end,
        const GAABB3&       bbox)
    {
        const size_t count = end - begin;
        assert(count > 1);

        // Ensure that sufficient memory is allocated for the working arrays.
        ensure_size(m_indices, count);
        ensure_size(m_left_bboxes, count);
        ensure_size(m_temp_items, count);
        ensure_size(m_temp_bboxes, count);

        // Create the set of indices.
        for (size_t i = 0; i < count; ++i)
            m_indices[i] = i;

        GScalar best_split_cost = numeric_limits<GScalar>::max();
        size_t best_split_dim = 0;
        size_t best_split_pivot = 0;
        GAABB3 group_bbox;

        for (size_t dim = 0; dim < 3; ++dim)
        {
            // Sort the items according to their bounding boxes.
            BboxSortPredicate predicate(bboxes, begin, dim);
            sort(&m_indices[0], &m_indices[0] + count, predicate);

            // Left-to-right sweep to accumulate bounding boxes.
            group_bbox.invalidate();
            for (size_t i = 0; i < count; ++i)
            {
                group_bbox.insert(bboxes[begin + m_indices[i]]);
                m_left_bboxes[i] = group_bbox;
            }

            // Right-to-left sweep to accumulate bounding boxes and evaluate SAH.
            group_bbox.invalidate();
            for (size_t i = count - 1; i > 0; --i)
            {
                // Get left and right bounding boxes.
                const GAABB3& left_bbox = m_left_bboxes[i - 1];
                group_bbox.insert(bboxes[begin + m_indices[i]]);

                // Compute the cost of this partition.
                const GScalar left_cost = left_bbox.half_surface_area() * i;
                const GScalar right_cost = group_bbox.half_surface_area() * (count - i);
                const GScalar split_cost = left_cost + right_cost;

                // Keep track of the partition with the lowest cost.
                if (best_split_cost > split_cost)
                {
                    best_split_cost = split_cost;
                    best_split_dim = dim;
                    best_split_pivot = i;
                }
            }
        }

        // Just split in half if the cost of the best partition is too high.
        const GScalar leaf_cost = bbox.half_surface_area() * count;
        if (best_split_cost >= leaf_cost)
            return (begin + end) / 2;

        // Sort the indices according to the item bounding boxes.
        BboxSortPredicate predicate(bboxes, begin, best_split_dim);
        sort(&m_indices[0], &m_indices[0] + count, predicate);

        // Reorder the items.
        small_item_reorder(&items[begin], &m_temp_items[0], &m_indices[0], count);
        small_item_reorder(&bboxes[begin], &m_temp_bboxes[0], &m_indices[0], count);

        assert(begin + best_split_pivot < end);
        return begin + best_split_pivot;
    }