Skip to content

Commit

Permalink
Bring the code closer to original
Browse files Browse the repository at this point in the history
  • Loading branch information
xPaw committed Jun 22, 2019
1 parent 4fd8ad1 commit 892c5f8
Showing 1 changed file with 46 additions and 42 deletions.
88 changes: 46 additions & 42 deletions ValveResourceFormat/ThirdParty/MeshOptimizerIndexDecoder.cs
Expand Up @@ -3,7 +3,6 @@
*/
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.IO;

namespace ValveResourceFormat.ThirdParty
Expand All @@ -12,19 +11,16 @@ public class MeshOptimizerIndexDecoder
{
private const byte IndexHeader = 0xe0;

private static void PushEdgeFifo(Queue<(uint, uint)> fifo, uint a, uint b)
private static void PushEdgeFifo(ValueTuple<uint, uint>[] fifo, ref int offset, uint a, uint b)
{
fifo.Enqueue((a, b));
fifo[offset] = (a, b);
offset = (offset + 1) & 15;
}

private static void PushVertexFifo(Queue<uint> fifo, uint v, bool cond = true)
private static void PushVertexFifo(uint[] fifo, ref int offset, uint v, bool cond = true)
{
if (!cond)
{
fifo.Dequeue();
}

fifo.Enqueue(v);
fifo[offset] = v;
offset = (offset + (cond ? 1 : 0)) & 15;
}

private static uint DecodeVByte(BinaryReader data)
Expand Down Expand Up @@ -90,8 +86,10 @@ public static byte[] DecodeIndexBuffer(int indexCount, int indexSize, Span<byte>
throw new ArgumentException("Expected indexSize to be either 2 or 4");
}

var dataOffset = 1 + (indexCount / 3);

// the minimum valid encoding is header, 1 byte per triangle and a 16-byte codeaux table
if (buffer.Length < 1 + (indexCount / 3) + 16)
if (buffer.Length < dataOffset + 16)
{
throw new ArgumentException("Index buffer is too short.");
}
Expand All @@ -101,16 +99,18 @@ public static byte[] DecodeIndexBuffer(int indexCount, int indexSize, Span<byte>
throw new ArgumentException("Incorrect index buffer header.");
}

var vertexFifo = new Queue<uint>(16);
var edgeFifo = new Queue<(uint, uint)>(16);
var vertexFifo = new uint[16];
var edgeFifo = new ValueTuple<uint, uint>[16];
var edgeFifoOffset = 0;
var vertexFifoOffset = 0;

var next = 0u;
var last = 0u;

var code = buffer.Slice(1);
var data = code.Slice(indexCount / 3);
var bufferIndex = 1;
var data = buffer.Slice(dataOffset, buffer.Length - 16 - dataOffset);

var codeauxTable = code.Slice(buffer.Length - 17);
var codeauxTable = buffer.Slice(buffer.Length - 16);

var destination = new Span<byte>(new byte[indexCount * indexSize]);

Expand All @@ -119,41 +119,40 @@ public static byte[] DecodeIndexBuffer(int indexCount, int indexSize, Span<byte>
{
for (var i = 0; i < indexCount; i += 3)
{
var codetri = code[0];
code = code.Slice(1);
var codetri = buffer[bufferIndex++];

if (codetri < 0xf0)
{
var fe = codetri >> 4;

var (a, b) = edgeFifo.Dequeue();
var (a, b) = edgeFifo[(edgeFifoOffset - 1 - fe) & 15];

var fec = codetri & 15;

if (fec != 15)
{
var c = fec == 0 ? next : vertexFifo.Dequeue();
var c = fec == 0 ? next : vertexFifo[(vertexFifoOffset - 1 - fec) & 15];

var fec0 = fec == 0;
next += fec0 ? 1u : 0u;

WriteTriangle(destination, i, indexSize, a, b, c);

PushVertexFifo(vertexFifo, c, fec0);
PushVertexFifo(vertexFifo, ref vertexFifoOffset, c, fec0);

PushEdgeFifo(edgeFifo, c, b);
PushEdgeFifo(edgeFifo, a, c);
PushEdgeFifo(edgeFifo, ref edgeFifoOffset, c, b);
PushEdgeFifo(edgeFifo, ref edgeFifoOffset, a, c);
}
else
{
var c = last = DecodeIndex(dataReader, next, last);

WriteTriangle(destination, i, indexSize, a, b, c);

PushVertexFifo(vertexFifo, c);
PushVertexFifo(vertexFifo, ref vertexFifoOffset, c);

PushEdgeFifo(edgeFifo, c, b);
PushEdgeFifo(edgeFifo, a, c);
PushEdgeFifo(edgeFifo, ref edgeFifoOffset, c, b);
PushEdgeFifo(edgeFifo, ref edgeFifoOffset, a, c);
}
}
else
Expand All @@ -167,25 +166,25 @@ public static byte[] DecodeIndexBuffer(int indexCount, int indexSize, Span<byte>

var a = next++;

var b = (feb == 0) ? next : vertexFifo.Dequeue();
var b = (feb == 0) ? next : vertexFifo[(vertexFifoOffset - feb) & 15];

var feb0 = feb == 0 ? 1u : 0u;
next += feb0;

var c = (fec == 0) ? next : vertexFifo.Dequeue();
var c = (fec == 0) ? next : vertexFifo[(vertexFifoOffset - fec) & 15];

var fec0 = fec == 0 ? 1u : 0u;
next += fec0;

WriteTriangle(destination, i, indexSize, a, b, c);

PushVertexFifo(vertexFifo, a);
PushVertexFifo(vertexFifo, b, feb0 == 1u);
PushVertexFifo(vertexFifo, c, fec0 == 1u);
PushVertexFifo(vertexFifo, ref vertexFifoOffset, a);
PushVertexFifo(vertexFifo, ref vertexFifoOffset, b, feb0 == 1u);
PushVertexFifo(vertexFifo, ref vertexFifoOffset, c, fec0 == 1u);

PushEdgeFifo(edgeFifo, b, a);
PushEdgeFifo(edgeFifo, c, b);
PushEdgeFifo(edgeFifo, a, c);
PushEdgeFifo(edgeFifo, ref edgeFifoOffset, b, a);
PushEdgeFifo(edgeFifo, ref edgeFifoOffset, c, b);
PushEdgeFifo(edgeFifo, ref edgeFifoOffset, a, c);
}
else
{
Expand All @@ -196,8 +195,8 @@ public static byte[] DecodeIndexBuffer(int indexCount, int indexSize, Span<byte>
var fec = codeaux & 15;

var a = (fea == 0) ? next++ : 0;
var b = (feb == 0) ? next++ : vertexFifo.Dequeue();
var c = (fec == 0) ? next++ : vertexFifo.Dequeue();
var b = (feb == 0) ? next++ : vertexFifo[(vertexFifoOffset - feb) & 15];
var c = (fec == 0) ? next++ : vertexFifo[(vertexFifoOffset - fec) & 15];

if (fea == 15)
{
Expand All @@ -216,16 +215,21 @@ public static byte[] DecodeIndexBuffer(int indexCount, int indexSize, Span<byte>

WriteTriangle(destination, i, indexSize, a, b, c);

PushVertexFifo(vertexFifo, a);
PushVertexFifo(vertexFifo, b, (feb == 0) || (feb == 15));
PushVertexFifo(vertexFifo, c, (fec == 0) || (fec == 15));
PushVertexFifo(vertexFifo, ref vertexFifoOffset, a);
PushVertexFifo(vertexFifo, ref vertexFifoOffset, b, (feb == 0) || (feb == 15));
PushVertexFifo(vertexFifo, ref vertexFifoOffset, c, (fec == 0) || (fec == 15));

PushEdgeFifo(edgeFifo, b, a);
PushEdgeFifo(edgeFifo, c, b);
PushEdgeFifo(edgeFifo, a, c);
PushEdgeFifo(edgeFifo, ref edgeFifoOffset, b, a);
PushEdgeFifo(edgeFifo, ref edgeFifoOffset, c, b);
PushEdgeFifo(edgeFifo, ref edgeFifoOffset, a, c);
}
}
}

if (stream.Position != stream.Length)
{
throw new InvalidDataException("we didn't read all data bytes and stopped before the boundary between data and codeaux table");
}
}

return destination.ToArray();
Expand Down

0 comments on commit 892c5f8

Please sign in to comment.