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()); }
void Scene::create_render_data() { assert(!m_has_render_data); m_render_data.m_bbox = compute_bbox(); m_render_data.m_center = m_render_data.m_bbox.center(); m_render_data.m_radius = m_render_data.m_bbox.radius(); m_render_data.m_diameter = m_render_data.m_bbox.diameter(); m_render_data.m_safe_diameter = m_render_data.m_diameter * GScalar(1.01); m_has_render_data = true; }
void compute_smooth_vertex_tangents_base_pose(MeshObject& object) { assert(object.get_vertex_tangent_count() == 0); assert(object.get_tex_coords_count() > 0); const size_t vertex_count = object.get_vertex_count(); const size_t triangle_count = object.get_triangle_count(); vector<GVector3> tangents(vertex_count, GVector3(0.0)); for (size_t i = 0; i < triangle_count; ++i) { const Triangle& triangle = object.get_triangle(i); if (!triangle.has_vertex_attributes()) continue; const GVector2 v0_uv = object.get_tex_coords(triangle.m_a0); const GVector2 v1_uv = object.get_tex_coords(triangle.m_a1); const GVector2 v2_uv = object.get_tex_coords(triangle.m_a2); // // Reference: // // Physically Based Rendering, first edition, pp. 128-129 // const GScalar du0 = v0_uv[0] - v2_uv[0]; const GScalar dv0 = v0_uv[1] - v2_uv[1]; const GScalar du1 = v1_uv[0] - v2_uv[0]; const GScalar dv1 = v1_uv[1] - v2_uv[1]; const GScalar det = du0 * dv1 - dv0 * du1; if (det == GScalar(0.0)) continue; const GVector3& v2 = object.get_vertex(triangle.m_v2); const GVector3 dp0 = object.get_vertex(triangle.m_v0) - v2; const GVector3 dp1 = object.get_vertex(triangle.m_v1) - v2; const GVector3 tangent = normalize(dv1 * dp0 - dv0 * dp1); tangents[triangle.m_v0] += tangent; tangents[triangle.m_v1] += tangent; tangents[triangle.m_v2] += tangent; } object.reserve_vertex_tangents(vertex_count); for (size_t i = 0; i < vertex_count; ++i) object.push_vertex_tangent(safe_normalize(tangents[i])); }
void Scene::create_render_data() { assert(!m_has_render_data); m_render_data.m_bbox = compute_bbox(); if (m_render_data.m_bbox.is_valid()) { m_render_data.m_center = m_render_data.m_bbox.center(); m_render_data.m_radius = m_render_data.m_bbox.radius(); m_render_data.m_diameter = m_render_data.m_bbox.diameter(); m_render_data.m_safe_diameter = m_render_data.m_diameter * GScalar(1.01); } else { m_render_data.m_center = GVector3(0.0); m_render_data.m_radius = GScalar(0.0); m_render_data.m_diameter = GScalar(0.0); m_render_data.m_safe_diameter = GScalar(0.0); } m_has_render_data = true; }
void ShadingPoint::fetch_source_geometry() const { assert(hit()); assert(!(m_members & HasSourceGeometry)); // Retrieve the assembly. m_assembly = &m_assembly_instance->get_assembly(); // Retrieve the object instance. m_object_instance = m_assembly->object_instances().get_by_index(m_object_instance_index); assert(m_object_instance); // Retrieve the object. m_object = &m_object_instance->get_object(); // Retrieve the region kit of the object. assert(m_region_kit_cache); const RegionKit& region_kit = *m_region_kit_cache->access( m_object->get_uid(), m_object->get_region_kit()); // Retrieve the region. const IRegion* region = region_kit[m_region_index]; // Retrieve the tessellation of the region. assert(m_tess_cache); const StaticTriangleTess& tess = *m_tess_cache->access( region->get_uid(), region->get_static_triangle_tess()); const size_t motion_segment_count = tess.get_motion_segment_count(); // Retrieve the triangle. const Triangle& triangle = tess.m_primitives[m_triangle_index]; // Copy the index of the triangle attribute. m_triangle_pa = triangle.m_pa; // Copy the texture coordinates from UV set #0. if (triangle.has_vertex_attributes() && tess.get_uv_vertex_count() > 0) { m_v0_uv = tess.get_uv_vertex(triangle.m_a0); m_v1_uv = tess.get_uv_vertex(triangle.m_a1); m_v2_uv = tess.get_uv_vertex(triangle.m_a2); } else { // UV set #0 doesn't exist, or this triangle doesn't have vertex attributes. m_v0_uv = m_v1_uv = m_v2_uv = GVector2(0.0); } // Copy the object instance space triangle vertices. assert(triangle.m_v0 != Triangle::None); assert(triangle.m_v1 != Triangle::None); assert(triangle.m_v2 != Triangle::None); if (motion_segment_count > 0) { // Fetch triangle vertices from the previous pose. const size_t prev_index = truncate<size_t>(m_ray.m_time * motion_segment_count); GVector3 prev_v0, prev_v1, prev_v2; if (prev_index == 0) { prev_v0 = tess.m_vertices[triangle.m_v0]; prev_v1 = tess.m_vertices[triangle.m_v1]; prev_v2 = tess.m_vertices[triangle.m_v2]; } else { prev_v0 = tess.get_vertex_pose(triangle.m_v0, prev_index - 1); prev_v1 = tess.get_vertex_pose(triangle.m_v1, prev_index - 1); prev_v2 = tess.get_vertex_pose(triangle.m_v2, prev_index - 1); } // Fetch triangle vertices from the next pose. const GVector3 next_v0 = tess.get_vertex_pose(triangle.m_v0, prev_index); const GVector3 next_v1 = tess.get_vertex_pose(triangle.m_v1, prev_index); const GVector3 next_v2 = tess.get_vertex_pose(triangle.m_v2, prev_index); // Interpolate triangle vertices. const GScalar k = static_cast<GScalar>(m_ray.m_time * motion_segment_count - prev_index); m_v0 = (GScalar(1.0) - k) * prev_v0 + k * next_v0; m_v1 = (GScalar(1.0) - k) * prev_v1 + k * next_v1; m_v2 = (GScalar(1.0) - k) * prev_v2 + k * next_v2; } else { m_v0 = tess.m_vertices[triangle.m_v0]; m_v1 = tess.m_vertices[triangle.m_v1]; m_v2 = tess.m_vertices[triangle.m_v2]; } // Copy the object instance space triangle vertex normals. assert(triangle.m_n0 != Triangle::None); assert(triangle.m_n1 != Triangle::None); assert(triangle.m_n2 != Triangle::None); m_n0 = tess.m_vertex_normals[triangle.m_n0]; m_n1 = tess.m_vertex_normals[triangle.m_n1]; m_n2 = tess.m_vertex_normals[triangle.m_n2]; assert(is_normalized(m_n0)); assert(is_normalized(m_n1)); assert(is_normalized(m_n2)); }
void CurveTree::collect_curves(vector<GAABB3>& curve_bboxes) { const ObjectInstanceContainer& object_instances = m_arguments.m_assembly.object_instances(); for (size_t i = 0; i < object_instances.size(); ++i) { // Retrieve the object instance. const ObjectInstance* object_instance = object_instances.get_by_index(i); assert(object_instance); // Retrieve the object. const Object& object = object_instance->get_object(); // Process only curve objects. if (strcmp(object.get_model(), CurveObjectFactory::get_model())) continue; const CurveObject& curve_object = static_cast<const CurveObject&>(object); // Retrieve the object instance transform. const Transformd::MatrixType& transform = object_instance->get_transform().get_local_to_parent(); // Store degree-1 curves, curve keys and curve bounding boxes. const size_t curve1_count = curve_object.get_curve1_count(); for (size_t j = 0; j < curve1_count; ++j) { const Curve1Type curve(curve_object.get_curve1(j), transform); const CurveKey curve_key( i, // object instance index j, // curve index in object m_curves1.size(), // curve index in tree 0, // for now we assume all the curves have the same material 1); // curve degree GAABB3 curve_bbox = curve.compute_bbox(); curve_bbox.grow(GVector3(GScalar(0.5) * curve.compute_max_width())); m_curves1.push_back(curve); m_curve_keys.push_back(curve_key); curve_bboxes.push_back(curve_bbox); } // Store degree-3 curves, curve keys and curve bounding boxes. const size_t curve3_count = curve_object.get_curve3_count(); for (size_t j = 0; j < curve3_count; ++j) { const Curve3Type curve(curve_object.get_curve3(j), transform); const CurveKey curve_key( i, // object instance index j, // curve index in object m_curves3.size(), // curve index in tree 0, // for now we assume all the curves have the same material 3); // curve degree GAABB3 curve_bbox = curve.compute_bbox(); curve_bbox.grow(GVector3(GScalar(0.5) * curve.compute_max_width())); m_curves3.push_back(curve); m_curve_keys.push_back(curve_key); curve_bboxes.push_back(curve_bbox); } } }