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()); }
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()); } }
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; }
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); }
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; }
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())); } }
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)); }
// 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; }