Network compression: packed vectors

Originally posted to Shawn Hargreaves Blog on MSDN, Wednesday, December 26, 2007

The Microsoft.Xna.Framework.Graphics.PackedVector namespace contains types that could be described as "quantization for lazy people". This functionality was originally designed for packing textures and vertex buffers into smaller GPU formats, but is equally useful for compressing network packets.

Consider this line from our Peer-to-Peer sample:

    packetWriter.Write(localTank.Position);

The tank position is a Vector2, which contains two floating point fields, each 32 bits in size. Using a HalfVector2 struct, we can convert the floats to 16 bit format, then send them both over the wire as a single 32 bit integer:

    HalfVector2 packedVector = new HalfVector2(localTank.Position);

packetWriter.Write(packedVector.PackedValue);

This 16 bit half-float format has less range and precision than a regular 32 bit float, but is often good enough to get the job done, and a 50% compression ratio is nothing to sneeze at!

To read the data, change this line from the original sample:

    remoteTank.Position = packetReader.ReadVector2();

to:

    HalfVector2 packedVector = new HalfVector2();

packedVector.PackedValue = packetReader.ReadUInt32();

remoteTank.Position = packedVector.ToVector2();

All the PackedVector types have their uses, but here are the ones you will encounter most often:

Blog index   -   Back to my homepage