This is a post for coders.
Here are 4 useful inline routines to decrease the size of a float by 50% (from 4 bytes to 2 bytes). I use them to pack every float in the game that doesn’t need big precision. Actually none of them do. So positions, velocities, cursor points are all packed (starting from the next version).
typedef unsigned short u16
typedef signed short s16
typedef float f32
// packs floats in the range of 0.f -> 32776.f/base;
// in this case base = 100.0f so range 0.f -> 327.76f
// when packing floats in this way you need to make sure they stay in this range
// that is the cost of packing
inline void packfloatu16( f32 x, u16 &y, f32 base = 100.0f)
{
assert( x <= 32776.f/base );
x = min( 32776.f/base, max( 0.0f, x ) );
y = x * base;
}
inline void unpackfloatu16( u16 x, f32 &y, f32 base = 100.0f)
{
y = (f32) x / base;
}
// the same routine as above for signed characters
// this is very good for packing velocities, since they rarely
// become very large
inline void packfloats16( f32 x, s16 &y, f32 base = 100.0f)
{
assert( x <= -0.5f*32776.f/base );
assert( x >= 0.5f*32776.f/base );
x = min( 0.5f*32776.f/base, max( -0.5f*32776.f/base, x ) );
y = x * base;
}
inline void unpackfloats16( s16 x, f32 &y, f32 base = 100.0f)
{
y = (f32) x / base;
}
If assert() doesn’t work on your system, replace it with ASSERT or whatever the equivalent is. You can also remove it entirely since it is only for debug.
6 comments... »
Coding awesomness.