2014-09-30 00:57:14 -04:00
|
|
|
/*
|
|
|
|
Copyright (c) 2014, Conor Stokes
|
|
|
|
All rights reserved.
|
|
|
|
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
|
|
modification, are permitted provided that the following conditions are met:
|
|
|
|
|
|
|
|
1. Redistributions of source code must retain the above copyright notice, this
|
|
|
|
list of conditions and the following disclaimer.
|
|
|
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
|
|
this list of conditions and the following disclaimer in the documentation
|
|
|
|
and/or other materials provided with the distribution.
|
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
|
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
|
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
|
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
|
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
|
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
|
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
|
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
|
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
#include "IndexBufferDecompression.h"
|
|
|
|
#include "ReadBitstream.h"
|
|
|
|
#include "IndexCompressionConstants.h"
|
|
|
|
#include <assert.h>
|
|
|
|
|
2014-09-30 00:58:29 -04:00
|
|
|
template <typename Ty>
|
|
|
|
void DecompressIndexBuffer( Ty* triangles, uint32_t triangleCount, ReadBitstream& input )
|
2014-09-30 00:57:14 -04:00
|
|
|
{
|
2014-09-30 00:58:29 -04:00
|
|
|
Edge edgeFifo[ EDGE_FIFO_SIZE ];
|
|
|
|
uint32_t vertexFifo[ VERTEX_FIFO_SIZE ];
|
2014-09-30 00:57:14 -04:00
|
|
|
|
2014-09-30 00:58:29 -04:00
|
|
|
uint32_t edgesRead = 0;
|
|
|
|
uint32_t verticesRead = 0;
|
|
|
|
uint32_t newVertices = 0;
|
|
|
|
const Ty* triangleEnd = triangles + ( triangleCount * 3 );
|
2014-09-30 00:57:14 -04:00
|
|
|
|
|
|
|
// iterate through the triangles
|
2014-09-30 00:58:29 -04:00
|
|
|
for ( Ty* triangle = triangles; triangle < triangleEnd; triangle += 3 )
|
2014-09-30 00:57:14 -04:00
|
|
|
{
|
|
|
|
int readVertex = 0;
|
|
|
|
bool skipFirstEdge = false;
|
|
|
|
|
|
|
|
while ( readVertex < 3 )
|
|
|
|
{
|
|
|
|
IndexBufferCodes code = static_cast< IndexBufferCodes >( input.Read( IB_CODE_BITS ) );
|
|
|
|
|
|
|
|
switch ( code )
|
|
|
|
{
|
|
|
|
case IB_NEW_VERTEX:
|
|
|
|
|
|
|
|
triangle[ readVertex ] =
|
|
|
|
vertexFifo[ verticesRead & VERTEX_FIFO_MASK ] = newVertices;
|
|
|
|
|
|
|
|
++readVertex;
|
|
|
|
++verticesRead;
|
|
|
|
++newVertices;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IB_CACHED_EDGE:
|
|
|
|
|
|
|
|
{
|
|
|
|
assert( readVertex == 0 );
|
|
|
|
|
|
|
|
uint32_t fifoIndex = input.Read( CACHED_EDGE_BITS );
|
|
|
|
const Edge& edge = edgeFifo[ ( ( edgesRead - 1 ) - fifoIndex ) & EDGE_FIFO_MASK ];
|
|
|
|
|
|
|
|
triangle[ 0 ] = edge.second;
|
|
|
|
triangle[ 1 ] = edge.first;
|
|
|
|
|
|
|
|
readVertex += 2;
|
|
|
|
skipFirstEdge = true;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case IB_CACHED_VERTEX:
|
|
|
|
|
|
|
|
{
|
|
|
|
uint32_t fifoIndex = input.Read( CACHED_VERTEX_BITS );
|
|
|
|
|
|
|
|
triangle[ readVertex ] = vertexFifo[ ( ( verticesRead - 1 ) - fifoIndex ) & VERTEX_FIFO_MASK ];
|
|
|
|
|
|
|
|
++readVertex;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case IB_FREE_VERTEX:
|
|
|
|
|
|
|
|
{
|
|
|
|
uint32_t readByte = 0;
|
|
|
|
uint32_t bitsToShift = 0;
|
|
|
|
uint32_t relativeVertex = 0;
|
|
|
|
|
|
|
|
// V-int decoding, done inline.
|
|
|
|
do
|
|
|
|
{
|
|
|
|
readByte = input.Read( 8 );
|
|
|
|
|
|
|
|
relativeVertex |= ( readByte & 0x7F ) << bitsToShift;
|
|
|
|
bitsToShift += 7;
|
|
|
|
|
|
|
|
} while ( readByte & 0x80 );
|
|
|
|
|
|
|
|
uint32_t vertex = ( newVertices - 1 ) - relativeVertex;
|
|
|
|
|
|
|
|
triangle[ readVertex ] =
|
|
|
|
vertexFifo[ verticesRead & VERTEX_FIFO_MASK ] = vertex;
|
|
|
|
|
|
|
|
++verticesRead;
|
|
|
|
++readVertex;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !skipFirstEdge )
|
|
|
|
{
|
2014-09-30 00:58:29 -04:00
|
|
|
edgeFifo[ edgesRead & EDGE_FIFO_MASK ].set(triangle[ 0 ], triangle[ 1 ]);
|
2014-09-30 00:57:14 -04:00
|
|
|
|
|
|
|
++edgesRead;
|
|
|
|
}
|
|
|
|
else // first 2 verts were an edge case, so insert them into the vertex fifo.
|
|
|
|
{
|
|
|
|
vertexFifo[ verticesRead & EDGE_FIFO_MASK ] = triangle[ 0 ];
|
|
|
|
|
|
|
|
++verticesRead;
|
|
|
|
|
|
|
|
vertexFifo[ verticesRead & EDGE_FIFO_MASK ] = triangle[ 1 ];
|
|
|
|
|
|
|
|
++verticesRead;
|
|
|
|
}
|
|
|
|
|
2014-09-30 00:58:29 -04:00
|
|
|
edgeFifo[ edgesRead & EDGE_FIFO_MASK ].set(triangle[ 1 ], triangle[ 2 ]);
|
2014-09-30 00:57:14 -04:00
|
|
|
|
|
|
|
++edgesRead;
|
|
|
|
|
2014-09-30 00:58:29 -04:00
|
|
|
edgeFifo[ edgesRead & EDGE_FIFO_MASK ].set(triangle[ 2 ], triangle[ 0 ]);
|
2014-09-30 00:57:14 -04:00
|
|
|
|
|
|
|
++edgesRead;
|
|
|
|
}
|
2014-09-30 00:58:29 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void DecompressIndexBuffer( uint16_t* triangles, uint32_t triangleCount, ReadBitstream& input )
|
|
|
|
{
|
|
|
|
DecompressIndexBuffer<uint16_t>( triangles, triangleCount, input );
|
|
|
|
}
|
|
|
|
|
|
|
|
void DecompressIndexBuffer( uint32_t* triangles, uint32_t triangleCount, ReadBitstream& input )
|
|
|
|
{
|
|
|
|
DecompressIndexBuffer<uint32_t>( triangles, triangleCount, input );
|
|
|
|
}
|