Function convertToLinearSweptSphere

Synopsis

#include <Source/Falcor/Scene/Curves/CurveTessellation.h>

static SweptSphereResult convertToLinearSweptSphere(size_t strandCount, const int *vertexCountsPerStrand, const float3 *controlPoints, const float *widths, const float2 *UVs, uint32_t degree, uint32_t subdivPerSegment, const glm::mat4 &xform)

Description

Convert cubic B-splines to a couple of linear swept sphere segments.

Parameters

[ in ] strandCount - Number of curve strands.

[ in ] vertexCountsPerStrand - Number of control points per strand.

[ in ] controlPoints - Array of control points.

[ in ] widths - Array of curve widths, i.e., diameters of swept spheres.

[ in ] UVs - Array of texture coordinates.

[ in ] degree - Polynomial degree of strand (linear – cubic).

[ in ] subdivPerSegment - Number of sub-segments within each cubic bspline segment (defined by 4 control points).

[ in ] xform - Row-major 4x4 transformation matrix. We apply pre-transformation to curve geometry.

Returns
Linear swept sphere segments.

Source

Lines 50-135 in Source/Falcor/Scene/Curves/CurveTessellation.cpp. Line 60 in Source/Falcor/Scene/Curves/CurveTessellation.h.

CurveTessellation::SweptSphereResult CurveTessellation::convertToLinearSweptSphere(size_t strandCount, const int* vertexCountsPerStrand, const float3* controlPoints, const float* widths, const float2* UVs, uint32_t degree, uint32_t subdivPerSegment, const glm::mat4& xform)
{
    SweptSphereResult result;
    // Only support linear tube segments now.
    // TODO: Add quadratic or cubic tube segments if necessary.
    assert(degree == 1);
    result.degree = degree;
    uint32_t pointCounts = 0;
    uint32_t segCounts = 0;
    for (uint32_t i = 0; i < strandCount; i++)
    {
        pointCounts += subdivPerSegment * (vertexCountsPerStrand[i] - 1) + 1;
        segCounts += pointCounts - 1;
    }
    result.indices.reserve(segCounts);
    result.points.reserve(pointCounts);
    result.radius.reserve(pointCounts);
    result.tangents.reserve(pointCounts);
    result.normals.reserve(pointCounts);
    result.texCrds.reserve(pointCounts);
    uint32_t pointOffset = 0;
    for (uint32_t i = 0; i < strandCount; i++)
    {
        CubicSpline strandPoints(controlPoints + pointOffset, vertexCountsPerStrand[i]);
        CubicSpline strandWidths(widths + pointOffset, vertexCountsPerStrand[i]);
        uint32_t resOffset = (uint32_t)result.points.size();
        for (uint32_t j = 0; j < (uint32_t)vertexCountsPerStrand[i] - 1; j++)
        {
            for (uint32_t k = 0; k < subdivPerSegment; k++)
            {
                float t = (float)k / (float)subdivPerSegment;
                result.indices.push_back((uint32_t)result.points.size());
                // Pre-transform curve points.
                float4 sph = transformSphere(xform, float4(strandPoints.interpolate(j, t), strandWidths.interpolate(j, t) * 0.5f));
                result.points.push_back(sph.xyz);
                result.radius.push_back(sph.w);
            }
        }
        float4 sph = transformSphere(xform, float4(strandPoints.interpolate(vertexCountsPerStrand[i] - 2, 1.f), strandWidths.interpolate(vertexCountsPerStrand[i] - 2, 1.f) * 0.5f));
        result.points.push_back(sph.xyz);
        result.radius.push_back(sph.w);
        // Compute tangents and normals.
        for (uint32_t j = resOffset; j < result.points.size(); j++)
        {
            float3 fwd, s, t;
            if (j < result.points.size() - 1)
            {
                fwd = normalize(result.points[j + 1] - result.points[j]);
            }
            else
            {
                fwd = normalize(result.points[j] - result.points[j - 1]);
            }
            buildFrame(fwd, s, t);
            result.tangents.push_back(fwd);
            result.normals.push_back(s);
        }
        // Texture coordinates.
        if (UVs)
        {
            CubicSpline strandUVs(UVs + pointOffset, vertexCountsPerStrand[i]);
            for (uint32_t j = 0; j < (uint32_t)vertexCountsPerStrand[i] - 1; j++)
            {
                for (uint32_t k = 0; k < subdivPerSegment; k++)
                {
                    float t = (float)k / (float)subdivPerSegment;
                    result.texCrds.push_back(strandUVs.interpolate(j, t));
                }
            }
            result.texCrds.push_back(strandUVs.interpolate(vertexCountsPerStrand[i] - 2, 1.f));
        }
        pointOffset += vertexCountsPerStrand[i];
    }
    return result;
}





Add Discussion as Guest

Log in