message: vertexcodec: Encode blocks of vertex data with delta-encoding
  This reduces the post-deflate size (72.9 -> 70.6 on nyra.obj) and makes
  decoding cache-efficient. The deltas are currently linear based on post
  vertex fetch order since we don't use index information just yet.
diff: // TODO: references
  namespace meshopt
  {
  +
  +const size_t kVertexBlockSize = 256;
  +
  +static unsigned char* encodeVertexBlock(unsigned char* data, const unsigned char* vertex_data, size_t vertex_count, size_t vertex_size)
  +{
  + assert(vertex_count > 0);
  +
  + for (size_t k = 0; k < vertex_size; ++k)
  + {
  + *data++ = vertex_data[k];
  + }
  +
  + for (size_t k = 0; k < vertex_size; ++k)
  + {
  + size_t vertex_offset = k;
  +
  + for (size_t i = 1; i < vertex_count; ++i)
  + {
  + *data++ = vertex_data[vertex_offset + vertex_size] - vertex_data[vertex_offset];
  +
  + vertex_offset += vertex_size;
  + }
  + }
  +
  + return data;
  +}
  +
  }
  size_t meshopt_encodeVertexBuffer(unsigned char* buffer, size_t buffer_size, const void* vertices, size_t vertex_count, size_t vertex_size, size_t index_count, const unsigned char* index_buffer, size_t index_buffer_size)
  {
  + using namespace meshopt;
  +
  assert(vertex_size > 0 && vertex_size <= 256);
  assert(index_count % 3 == 0);
  @@ -22,12 +51,11 @@ size_t meshopt_encodeVertexBuffer(unsigned char* buffer, size_t buffer_size, con
  unsigned char* data = buffer;
  - for (size_t k = 0; k < vertex_size; ++k)
  - {
  - for (size_t i = 0; i < vertex_count; ++i)
  + for (size_t i = 0; i < vertex_count; i += kVertexBlockSize)
  {
  - *data++ = vertex_data[i * vertex_size + k];
  - }
  + size_t block_size = (i + kVertexBlockSize < vertex_count) ? kVertexBlockSize : vertex_count - i;
  +
  + data = encodeVertexBlock(data, vertex_data + i * vertex_size, block_size, vertex_size);
  }
  assert(size_t(data - buffer) <= buffer_size);
  