This ended up being far more complicated than anticipated -- the utils
now make use of filterExceptAttributes() in order to properly preserve
the index type when passing a MeshData through. Before an
implementation-specific index type was lost in the process due to
passing just the view to MeshIndexData constructor and not also the
type, and because keeping the metadata is a bit involved process, this
had to wait until there's an alternative to reference() that allows me
to drop all attribute information. And that's what
filterExceptAttributes() does.
Then, interleave() implicitly doesn't preserve strided index buffers
because GPUs don't like them, and since implementation-specific index
types always result in strided index buffers, this was then immediately
dying inside interleave() as it's not possible to tightly-pack an index
buffer of an unknown type. Thus, the function now has to expose
InterleaveFlags and propagate them to interleave() in order to allow the
user to preserve the index buffer without repacking it.
And doing all the automagic of unpacking packed types, converting
positions *and* normals/tangents/bitangents, and also an overload for
transforming texture coordinates.
Such a simple thing and yet so complex and nasty to test.