Function convertToMesh

Synopsis

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

static MeshResult convertToMesh(size_t strandCount, const int *vertexCountsPerStrand, const float3 *controlPoints, const float *widths, const float2 *UVs, uint32_t subdivPerSegment, uint32_t pointCountPerCrossSection)

Description

Tessellate cubic B-splines to a triangular mesh.

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 ] subdivPerSegment - Number of sub-segments within each cubic bspline segment (defined by 4 control points).

[ in ] pointCountPerCrossSection - Number of points sampled at each cross-section.

Returns
Tessellated mesh.

Source

Lines 137-246 in Source/Falcor/Scene/Curves/CurveTessellation.cpp. Line 84 in Source/Falcor/Scene/Curves/CurveTessellation.h.

CurveTessellation::MeshResult CurveTessellation::convertToMesh(size_t strandCount, const int* vertexCountsPerStrand, const float3* controlPoints, const float* widths, const float2* UVs, uint32_t subdivPerSegment, uint32_t pointCountPerCrossSection)
{
    MeshResult result;
    uint32_t vertexCounts = 0;
    uint32_t faceCounts = 0;
    for (uint32_t i = 0; i < strandCount; i++)
    {
        vertexCounts += pointCountPerCrossSection * subdivPerSegment * (vertexCountsPerStrand[i] - 1) + 1;
        faceCounts += 2 * pointCountPerCrossSection * subdivPerSegment * (vertexCountsPerStrand[i] - 1);
    }
    result.vertices.reserve(vertexCounts);
    result.normals.reserve(vertexCounts);
    result.tangents.reserve(vertexCounts);
    result.faceVertexCounts.reserve(faceCounts);
    result.faceVertexIndices.reserve(faceCounts * 3);
    result.texCrds.reserve(vertexCounts);
    uint32_t pointOffset = 0;
    uint32_t meshVertexOffset = 0;
    for (uint32_t i = 0; i < strandCount; i++)
    {
        CubicSpline strandPoints(controlPoints + pointOffset, vertexCountsPerStrand[i]);
        CubicSpline strandWidths(widths + pointOffset, vertexCountsPerStrand[i]);
        std::vector<float3> curvePoints;
        std::vector<float> curveRadius;
        std::vector<float2> curveUVs;
        curvePoints.push_back(strandPoints.interpolate(0, 0.f));
        curveRadius.push_back(strandWidths.interpolate(0, 0.f) * 0.5f);
        for (uint32_t j = 0; j < (uint32_t)vertexCountsPerStrand[i] - 1; j++)
        {
            for (uint32_t k = 1; k <= subdivPerSegment; k++)
            {
                float t = (float)k / (float)subdivPerSegment;
                curvePoints.push_back(strandPoints.interpolate(j, t));
                curveRadius.push_back(strandWidths.interpolate(j, t) * 0.5f);
            }
        }
        // Texture coordinates.
        if (UVs)
        {
            CubicSpline strandUVs(UVs + pointOffset, vertexCountsPerStrand[i]);
            curveUVs.push_back(strandUVs.interpolate(0, 0.f));
            for (uint32_t j = 0; j < (uint32_t)vertexCountsPerStrand[i] - 1; j++)
            {
                for (uint32_t k = 1; k <= subdivPerSegment; k++)
                {
                    float t = (float)k / (float)subdivPerSegment;
                    curveUVs.push_back(strandUVs.interpolate(j, t));
                }
            }
        }
        pointOffset += vertexCountsPerStrand[i];
        // Create mesh.
        for (uint32_t j = 0; j < curvePoints.size(); j++)
        {
            float3 fwd, s, t;
            if (j < curvePoints.size() - 1)
            {
                fwd = normalize(curvePoints[j + 1] - curvePoints[j]);
            }
            else
            {
                fwd = normalize(curvePoints[j] - curvePoints[j - 1]);
            }
            buildFrame(fwd, s, t);
            // Mesh vertices, normals, tangents, and texCrds (if any).
            for (uint32_t k = 0; k < pointCountPerCrossSection; k++)
            {
                float phi = (float)k / (float)pointCountPerCrossSection * (float)M_PI * 2.f;
                float3 vNormal = std::cos(phi) * s + std::sin(phi) * t;
                result.vertices.push_back(curvePoints[j] + curveRadius[j] * vNormal);
                result.normals.push_back(vNormal);
                result.tangents.push_back(float4(fwd.x, fwd.y, fwd.z, 1));
                if (UVs)
                {
                    result.texCrds.push_back(curveUVs[j]);
                }
            }
            // Mesh faces.
            if (j < curvePoints.size() - 1)
            {
                for (uint32_t k = 0; k < pointCountPerCrossSection; k++)
                {
                    result.faceVertexCounts.push_back(3);
                    result.faceVertexIndices.push_back(meshVertexOffset + j * pointCountPerCrossSection + k);
                    result.faceVertexIndices.push_back(meshVertexOffset + j * pointCountPerCrossSection + (k + 1) % pointCountPerCrossSection);
                    result.faceVertexIndices.push_back(meshVertexOffset + (j + 1) * pointCountPerCrossSection + (k + 1) % pointCountPerCrossSection);
                    result.faceVertexCounts.push_back(3);
                    result.faceVertexIndices.push_back(meshVertexOffset + j * pointCountPerCrossSection + k);
                    result.faceVertexIndices.push_back(meshVertexOffset + (j + 1) * pointCountPerCrossSection + (k + 1) % pointCountPerCrossSection);
                    result.faceVertexIndices.push_back(meshVertexOffset + (j + 1) * pointCountPerCrossSection + k);
                }
            }
        }
        meshVertexOffset += pointCountPerCrossSection * (uint32_t)curvePoints.size();
    }
    return result;
}





Add Discussion as Guest

Log in