HRESULT Mesh::Optimize()

in Meshconvert/Mesh.cpp [613:748]


HRESULT Mesh::Optimize(bool lru) noexcept
{
    if (!mnFaces || !mIndices || !mnVerts || !mPositions)
        return E_UNEXPECTED;

    if (!lru && !mAdjacency)
        return E_UNEXPECTED;

    HRESULT hr = S_OK;

    {
        std::unique_ptr<uint32_t[]> remap(new (std::nothrow) uint32_t[mnFaces]);
        if (!remap)
            return E_OUTOFMEMORY;

        if (mAttributes)
        {
            // Note that Clean handles vertex splits due to reuse between attributes

            hr = AttributeSort(mnFaces, mAttributes.get(), remap.get());
            if (FAILED(hr))
                return hr;

            if (mAdjacency)
            {
                hr = ReorderIBAndAdjacency(mIndices.get(), mnFaces, mAdjacency.get(), remap.get());
            }
            else
            {
                hr = ReorderIB(mIndices.get(), mnFaces, remap.get());
            }
            if (FAILED(hr))
                return hr;

            // Optimize faces for pre-transform vertex cache
            if (lru)
            {
                hr = OptimizeFacesLRUEx(mIndices.get(), mnFaces, mAttributes.get(), remap.get());
            }
            else
            {
                hr = OptimizeFacesEx(mIndices.get(), mnFaces, mAdjacency.get(), mAttributes.get(), remap.get());
            }
        }
        else if (lru)
        {
            hr = OptimizeFacesLRU(mIndices.get(), mnFaces, remap.get());
        }
        else
        {
            hr = OptimizeFaces(mIndices.get(), mnFaces, mAdjacency.get(), remap.get());
        }
        if (FAILED(hr))
            return hr;

        if (mAdjacency)
        {
            hr = ReorderIBAndAdjacency(mIndices.get(), mnFaces, mAdjacency.get(), remap.get());
        }
        else
        {
            hr = ReorderIB(mIndices.get(), mnFaces, remap.get());
        }
        if (FAILED(hr))
            return hr;
    }

    // Optimize vertices for post-transform vertex cache
    std::unique_ptr<uint32_t[]> remap(new (std::nothrow) uint32_t[mnVerts]);
    if (!remap)
        return E_OUTOFMEMORY;

    hr = OptimizeVertices(mIndices.get(), mnFaces, mnVerts, remap.get());
    if (FAILED(hr))
        return hr;

    hr = FinalizeIB(mIndices.get(), mnFaces, remap.get(), mnVerts);
    if (FAILED(hr))
        return hr;

    hr = FinalizeVB(mPositions.get(), sizeof(XMFLOAT3), mnVerts, remap.get());
    if (FAILED(hr))
        return hr;

    if (mNormals)
    {
        hr = FinalizeVB(mNormals.get(), sizeof(XMFLOAT3), mnVerts, remap.get());
        if (FAILED(hr))
            return hr;
    }

    if (mTangents)
    {
        hr = FinalizeVB(mTangents.get(), sizeof(XMFLOAT4), mnVerts, remap.get());
        if (FAILED(hr))
            return hr;
    }

    if (mBiTangents)
    {
        hr = FinalizeVB(mBiTangents.get(), sizeof(XMFLOAT3), mnVerts, remap.get());
        if (FAILED(hr))
            return hr;
    }

    if (mTexCoords)
    {
        hr = FinalizeVB(mTexCoords.get(), sizeof(XMFLOAT2), mnVerts, remap.get());
        if (FAILED(hr))
            return hr;
    }

    if (mColors)
    {
        hr = FinalizeVB(mColors.get(), sizeof(XMFLOAT4), mnVerts, remap.get());
        if (FAILED(hr))
            return hr;
    }

    if (mBlendIndices)
    {
        hr = FinalizeVB(mBlendIndices.get(), sizeof(XMFLOAT4), mnVerts, remap.get());
        if (FAILED(hr))
            return hr;

    }

    if (mBlendWeights)
    {
        hr = FinalizeVB(mBlendWeights.get(), sizeof(XMFLOAT4), mnVerts, remap.get());
        if (FAILED(hr))
            return hr;
    }

    return S_OK;
}