Exemplo n.º 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());
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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]));
}
Exemplo n.º 4
0
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));
}
Exemplo n.º 6
0
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);
        }
    }
}