D3DXOptimize Faces/Vertices

Does anyone know how to use D3DXOptimizeFaces and D3DXOptimizeVertices

I'm just a little bit confused as to what the SDK documentation means, and how the functions actually work. Do the functions modify the index buffer for me or do they expect me to reorder it myself using the remapping What's the format of the remapping If someone's got a code sample of these functions being used properly that would be great.

Thanks,
Phill


Answer this question

D3DXOptimize Faces/Vertices

  • nfedin

    The two functions can be used separately. First you call D3DXOptimizeFaces, then you can follow that up with a D3DXOptimizeVertices. The latter will change your vertices' layout, so it might not be desirable for all users.
    Below is "semi pseudo-code" for doing the thing :)



    // Must be an indexed mesh
    DWORD dwFacesCount = m_base.aIndices.GetCount()/3; // Assume triangle list
    CArray<DWORD> aRemap(dwFacesCount);
    D3DXOptimizeFaces(m_base.aIndices,dwFacesCount,m_base.dwVertsCount,TRUE,aRemap.GetData());
    < xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

    // Apply remap
    CArray<DWORD> aNewIndices(m_base.aIndices.GetCount());
    DWORD *pNewFace = aNewIndices;
    for (DWORD i=0;i<dwFacesCount;i++)
    {
       DWORD *pOldFaceBase = m_base.aIndices + aRemapIdea * 3;
       *(pNewFace++) = *(pOldFaceBase++);
       *(pNewFace++) = *(pOldFaceBase++);
       *(pNewFace++) = *(pOldFaceBase++);
    }

    m_base.aIndices.CopyFrom(aNewIndices);
    aNewIndices.Clear();

    // If you need to preserve vertices order then just stop here
    aRemap.SetSize(m_base.dwVertsCount);
    D3DXOptimizeVertices(m_base.aIndices,dwFacesCount,m_base.dwVertsCount,TRUE,aRemap);
    // Find where vertices stop being referenced
    DWORD dwNewVertsCount = aRemap.Find(0xFFFFFFFF);

    if (dwNewVertsCount == CARRAY_ELEMNOTFOUND)
       dwNewVertsCount = m_base.dwVertsCount;

    // (m_base.dwVertsCount-dwNewVertsCount) vertices removed
    // Move vertices based on the remap array...

    Remap<D3DXVECTOR3>((D3DXVECTOR3*)m_base.aPosition.GetData(),aRemap,dwNewVertsCount);
    Remap<D3DXVECTOR3>((D3DXVECTOR3*)m_base.aNormal.GetData(),aRemap,dwNewVertsCount);

    for (DWORD i=0;i<m_base.aUVs.GetCount();i++)
       Remap<D3DXVECTOR2>((D3DXVECTOR2*)m_base.aUVsIdea.GetData(),aRemap,dwNewVertsCount);
    Remap<D3DXVECTOR3>((D3DXVECTOR3*)m_base.aTangent.GetData(),aRemap,dwNewVertsCount);
    Remap<D3DXVECTOR3>((D3DXVECTOR3*)m_base.aBinormal.GetData(),aRemap,dwNewVertsCount);
    Remap<DWORD>((DWORD*)m_base.aColor.GetData(),aRemap,dwNewVertsCount);

    DWORD dwIndicesCount = m_base.aIndices.GetCount();
    for (DWORD i=0;i<dwIndicesCount;i++)
       m_base.aIndicesIdea = aRemap[m_base.aIndicesIdea];

    // Shrink arrays if applicable
    m_base.dwVertsCount = dwNewVertsCount;

     




    Oh,and the template function Remap<> is:



    template <class DATATYPE>
    void Remap(DATATYPE *pSrc,const RArray<DWORD>& aRemap,const DWORD dwEntriesCount)
    {
       CArray<DATATYPE> aTemp(aRemap.GetCount());
       aTemp.MemCopy(pSrc);
       const DWORD *pRemap = aRemap;
       const DATATYPE *pTemp = aTemp;
       for (DWORD i=0;i<dwEntriesCount;i++)
          pSrc[*(pRemap++)] = *(pTemp++);
    }

     




    I hope this helps :)



  • mikeb_aaron

    That was exactly what I needed, thanks. Works great.

    Phill


  • D3DXOptimize Faces/Vertices