//------------------------------------------------------------------------------------- // DirectXMeshGSAdjacency.cpp // // DirectX Mesh Geometry Library - Geometry Shader adjacency computation // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkID=324981 //------------------------------------------------------------------------------------- #include "DirectXMeshP.h" // // Generates an IB triangle list with adjacency (D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ) // http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124.aspx // namespace DirectX { template HRESULT _GenerateGSAdjacency( _In_reads_(nFaces*3) const index_t* indices, _In_ size_t nFaces, _In_reads_(nVerts) const uint32_t* pointRep, _In_reads_(nFaces*3) const uint32_t* adjacency, _In_ size_t nVerts, _Out_writes_(nFaces*6) index_t* indicesAdj ) { if ( !indices || !nFaces || !pointRep || !adjacency || !nVerts || !indicesAdj ) return E_INVALIDARG; if ( nVerts >= index_t(-1) ) return E_INVALIDARG; if ( indices == indicesAdj ) { // Does not support in-place conversion of the index buffer return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED); } if ( ( uint64_t(nFaces) * 3 ) >= UINT32_MAX ) return HRESULT_FROM_WIN32( ERROR_ARITHMETIC_OVERFLOW ); size_t inputi = 0; size_t outputi = 0; for( size_t face = 0; face < nFaces; ++face ) { for( uint32_t point = 0; point < 3; ++point ) { assert( outputi < (nFaces*6) ); _Analysis_assume_( outputi < (nFaces*6) ); indicesAdj[ outputi ] = indices[ inputi ]; ++outputi; ++inputi; assert( outputi < (nFaces*6) ); _Analysis_assume_( outputi < (nFaces*6) ); uint32_t a = adjacency[ face * 3 + point ]; if ( a == UNUSED32 ) { indicesAdj[ outputi ] = indices[ face * 3 + ( ( point+2 ) % 3 ) ]; } else { uint32_t v1 = indices[ face * 3 + point ]; uint32_t v2 = indices[ face * 3 + ( ( point + 1 ) % 3 ) ]; if ( v1 == index_t(-1) || v2 == index_t(-1) ) { indicesAdj[ outputi ] = index_t(-1); } else { if ( v1 >= nVerts || v2 >= nVerts ) return E_UNEXPECTED; v1 = pointRep[ v1 ]; v2 = pointRep[ v2 ]; uint32_t vOther = UNUSED32; // find other vertex for( uint32_t k = 0; k < 3; ++k ) { assert( a < nFaces ); _Analysis_assume_( a < nFaces ); uint32_t ak = indices[ a * 3 + k ]; if ( ak == index_t(-1) ) break; if ( ak >= nVerts ) return E_UNEXPECTED; if ( pointRep[ ak ] == v1 ) continue; if ( pointRep[ ak ] == v2 ) continue; vOther = ak; } if ( vOther == UNUSED32 ) { indicesAdj[ outputi ] = indices[ face * 3 + ( ( point+2 ) % 3 ) ]; } else { indicesAdj[ outputi ] = index_t( vOther ); } } } ++outputi; } } assert( inputi == ( nFaces * 3 ) ); assert( outputi == ( nFaces * 6 ) ); return S_OK; } //===================================================================================== // Entry-points //===================================================================================== //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT GenerateGSAdjacency( const uint16_t* indices, size_t nFaces, const uint32_t* pointRep, const uint32_t* adjacency, size_t nVerts, uint16_t* indicesAdj ) { return _GenerateGSAdjacency( indices, nFaces, pointRep, adjacency, nVerts, indicesAdj ); } //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT GenerateGSAdjacency( const uint32_t* indices, size_t nFaces, const uint32_t* pointRep, const uint32_t* adjacency, size_t nVerts, uint32_t* indicesAdj ) { return _GenerateGSAdjacency( indices, nFaces, pointRep, adjacency, nVerts, indicesAdj ); } } // namespace