MeshSerializer

Author: Aras Pranckevicius

Description
'''Note: You should probably use MeshSerializer2 now. It produces much smaller file sizes!'''

A set of scrtipts for saving/loading meshes to a simple binary format. Possible use case is saving them to files, uploading them somewhere and then using WWW interface to download meshes dynamically.

The package contains an example scene; where one mesh is saved to file and the other is downloaded.

Usage

 * MeshSerializer.js is an utility class to do the actual mesh serialization. Has comments inside.
 * SaveMeshForWeb.js and LoadMeshFromWeb.js are example usage scripts.

The package
Zipped Unity package: [[Media:MeshSerializer.zip]] (should work both in Unity 1.x and 2.x)

File format used
Note that such a file format is pretty fragile to changes - it does not have any concept of "format version" built in. It's fully enough if you save and load meshes yourself (you know which format are you using), but if you want a generic mesh-loading-format, you'd have to implement something more complex.

The file format used now:
 * 4 bytes vertex count
 * 4 bytes triangle count
 * 4 bytes vertex format (bits: 0=vertices, 1=normals, 2=tangents, 3=uvs)
 * After that come vertex component arrays, each optional except for positions. Which ones are present depends on vertex format:
 * Positions (12 bytes/vertex - 3 floats)
 * Normals (12 bytes/vertex - 3 floats)
 * Tangents (16 bytes/vertex - 4 floats)
 * UVs (8 bytes/vertex - 2 floats)
 * Finally the triangle indices array: 12 bytes per triangle (3 int indices)

Notes and ideas
There is a related article about saving unity meshes in .obj format: ObjExporter.

For smaller file sizes, a whole range of ideas can be tried. Actually, some of them are implemented in MeshSerializer2, so go check it out!


 * Normals and tangents could be encoded in a more compact way:
 * One byte per component (vs. 4 bytes/component); with 0 meaning -1.0; 128 meaning 0.0; 255 meaning 1.0. That's four times smaller than it uses now for a slight accuracy reduction.
 * 3 bytes per normal, using 11 bits for two components, and storing a sign of the third component. At load time, recalculate the third from the first two and the sign. The quality should be very good.
 * Same for tangents: 3 bytes for tangent: 11 bits for two components, sign of the third, and sign of the fourth (4th is always either +1 or -1).
 * Positions components could be stored as 2 byte integers, quantizing to the bounding box size.
 * Just drop the 4th byte from floats. A slight accuracy reduction, but a 25% space savings (a trick used by 64KB demo coders a lot :)).

When this script was originally written (Unity 1.5.0), one limitation of WWW interface is that it only supported textual data. So this package encodes binary format into a 2-characters-per-byte textual format. This restriction was lifted in a later Unity release, so nowadays the encoding is not actually necessary.

Changelog

 * 2008 Mar 14 - Bugfix, where in some cases the encode-to-text-characters step would produce out of range results. Interface change, now has to yield the download before creating mesh.
 * 2006 Aug 23 - Initial version

Source code
All the source code is included in the provided Unity Package above. This is only for easy-browsing purposes.