import { assert } from "../platform/GfxPlatformUtil" ; export const enum GfxTopology { TRIANGLES , TRISTRIP , TRIFAN , QUADS , QUADSTRIP } ; export function convertToTriangles ( dstBuffer , dstOffs , topology , indexBuffer ) { assert ( dstOffs + getTriangleIndexCountForTopologyIndexCount ( topology , indexBuffer . length ) <= dstBuffer . length ) ; let dst = dstOffs ; if ( topology === GfxTopology . QUADS ) { for ( let i = 0 ; i < indexBuffer . length ; i += 4 ) { dstBuffer [ dst ++ ] = indexBuffer [ i + 0 ] ; dstBuffer [ dst ++ ] = indexBuffer [ i + 1 ] ; dstBuffer [ dst ++ ] = indexBuffer [ i + 2 ] ; dstBuffer [ dst ++ ] = indexBuffer [ i + 0 ] ; dstBuffer [ dst ++ ] = indexBuffer [ i + 2 ] ; dstBuffer [ dst ++ ] = indexBuffer [ i + 3 ] ; } } else if ( topology === GfxTopology . TRISTRIP ) { for ( let i = 0 ; i < indexBuffer . length - 2 ; i ++ ) { if ( i % 2 === 0 ) { dstBuffer [ dst ++ ] = indexBuffer [ i + 0 ] ; dstBuffer [ dst ++ ] = indexBuffer [ i + 1 ] ; dstBuffer [ dst ++ ] = indexBuffer [ i + 2 ] ; } else { dstBuffer [ dst ++ ] = indexBuffer [ i + 1 ] ; dstBuffer [ dst ++ ] = indexBuffer [ i + 0 ] ; dstBuffer [ dst ++ ] = indexBuffer [ i + 2 ] ; } } } else if ( topology === GfxTopology . TRIFAN ) { for ( let i = 0 ; i < indexBuffer . length - 2 ; i ++ ) { dstBuffer [ dst ++ ] = indexBuffer [ 0 ] ; dstBuffer [ dst ++ ] = indexBuffer [ i + 1 ] ; dstBuffer [ dst ++ ] = indexBuffer [ i + 2 ] ; } } else if ( topology === GfxTopology . QUADSTRIP ) { for ( let i = 0 ; i < indexBuffer . length - 2 ; i += 2 ) { dstBuffer [ dst ++ ] = indexBuffer [ i + 0 ] ; dstBuffer [ dst ++ ] = indexBuffer [ i + 1 ] ; dstBuffer [ dst ++ ] = indexBuffer [ i + 2 ] ; dstBuffer [ dst ++ ] = indexBuffer [ i + 2 ] ; dstBuffer [ dst ++ ] = indexBuffer [ i + 1 ] ; dstBuffer [ dst ++ ] = indexBuffer [ i + 3 ] ; } } else if ( topology === GfxTopology . TRIANGLES ) { dstBuffer . set ( indexBuffer , dstOffs ) ; } } export function convertToTrianglesRange ( dstBuffer , dstOffs , topology , baseVertex , numVertices ) { assert ( dstOffs + getTriangleIndexCountForTopologyIndexCount ( topology , numVertices ) <= dstBuffer . length ) ; let dst = dstOffs ; if ( topology === GfxTopology . QUADS ) { for ( let i = 0 ; i < numVertices ; i += 4 ) { dstBuffer [ dst ++ ] = baseVertex + i + 0 ; dstBuffer [ dst ++ ] = baseVertex + i + 1 ; dstBuffer [ dst ++ ] = baseVertex + i + 2 ; dstBuffer [ dst ++ ] = baseVertex + i + 2 ; dstBuffer [ dst ++ ] = baseVertex + i + 3 ; dstBuffer [ dst ++ ] = baseVertex + i + 0 ; } } else if ( topology === GfxTopology . TRISTRIP ) { for ( let i = 0 ; i < numVertices - 2 ; i ++ ) { if ( i % 2 === 0 ) { dstBuffer [ dst ++ ] = baseVertex + i + 0 ; dstBuffer [ dst ++ ] = baseVertex + i + 1 ; dstBuffer [ dst ++ ] = baseVertex + i + 2 ; } else { dstBuffer [ dst ++ ] = baseVertex + i + 1 ; dstBuffer [ dst ++ ] = baseVertex + i + 0 ; dstBuffer [ dst ++ ] = baseVertex + i + 2 ; } } } else if ( topology === GfxTopology . TRIFAN ) { for ( let i = 0 ; i < numVertices - 2 ; i ++ ) { dstBuffer [ dst ++ ] = baseVertex + 0 ; dstBuffer [ dst ++ ] = baseVertex + i + 1 ; dstBuffer [ dst ++ ] = baseVertex + i + 2 ; } } else if ( topology === GfxTopology . QUADSTRIP ) { for ( let i = 0 ; i < numVertices - 2 ; i += 2 ) { dstBuffer [ dst ++ ] = baseVertex + i + 0 ; dstBuffer [ dst ++ ] = baseVertex + i + 1 ; dstBuffer [ dst ++ ] = baseVertex + i + 2 ; dstBuffer [ dst ++ ] = baseVertex + i + 2 ; dstBuffer [ dst ++ ] = baseVertex + i + 1 ; dstBuffer [ dst ++ ] = baseVertex + i + 3 ; } } else if ( topology === GfxTopology . TRIANGLES ) { for ( let i = 0 ; i < numVertices ; i ++ ) dstBuffer [ dst ++ ] = baseVertex + i ; } } export function convertToTriangleIndexBuffer ( topology , indexBuffer ) { if ( topology === GfxTopology . TRIANGLES ) return indexBuffer ; const newSize = getTriangleIndexCountForTopologyIndexCount ( topology , indexBuffer . length ) ; const newBuffer = new Uint16Array ( newSize ) ; convertToTriangles ( newBuffer , 0 , topology , indexBuffer ) ; return newBuffer ; } function range ( start , length ) { const r = new Uint16Array ( length ) ; for ( let i = 0 ; i < length ; i ++ ) r [ i ] = start + i ; return r ; } export function makeTriangleIndexBuffer ( topology , baseVertex , numVertices ) { return convertToTriangleIndexBuffer ( topology , range ( baseVertex , numVertices ) ) ; } export function getTriangleCountForTopologyIndexCount ( topology , indexCount ) { switch ( topology ) { case GfxTopology . TRIANGLES : return indexCount / 3 ; case GfxTopology . TRISTRIP : case GfxTopology . TRIFAN : return ( indexCount - 2 ) ; case GfxTopology . QUADS : return 2 * ( indexCount / 4 ) ; case GfxTopology . QUADSTRIP : return 2 * ( indexCount - 2 ) ; } } export function getTriangleIndexCountForTopologyIndexCount ( topology , indexCount ) { return 3 * getTriangleCountForTopologyIndexCount ( topology , indexCount ) ; } export function filterDegenerateTriangleIndexBuffer ( indexData ) { assert ( indexData . length % 3 === 0 ) ; const dst = new Uint16Array ( indexData . length ) ; let dstIdx = 0 ; for ( let i = 0 ; i < indexData . length ; i += 3 ) { const i0 = indexData [ i + 0 ] ; const i1 = indexData [ i + 1 ] ; const i2 = indexData [ i + 2 ] ; const isDegenerate = ( i0 === i1 ) || ( i1 === i2 ) || ( i2 === i0 ) ; if ( ! isDegenerate ) { dst [ dstIdx ++ ] = i0 ; dst [ dstIdx ++ ] = i1 ; dst [ dstIdx ++ ] = i2 ; } } return dst . slice ( 0 , dstIdx ) ; }