Floating in Space

Feature #1: Space Merchants (Yes I will think of a better name at some point) will be set entirely in our solar system.

Sounds small? Well consider that there are 8 major planets, 5 dwarf planets, 166 known moons, billions of small objects and 1 sun contained in roughly 2 light years or 125, 000 AU or 18,700,000,000,000 km/11,619,641,290,400 miles out from the sun.
I’m hoping that will give enough space and interesting locations to visit, and that’s before you start adding space stations and the like.

However, I’m planning on constraining the game area to a mere 50AU or roughly 7,480,000,000 km from the sun.
Which gives me Pluto and most of the Kuplier belt (a mass of ice particles and asteroids which is incidentally a nice design point for why you can’t go any further) but not Eris (the bugger that caused Pluto to lose it’s planet title).

The problem comes with the numbers involved, I’m planning on scaling to the metre so at the furthest extent it’s  7,480,000,000,000 m from the Sun.

Most game engines, XNA included, and graphics cards use single precision floating point numbers, aka floats, to store positions in screen space.

This is fine for most situations, however, the way floats work is that it uses 32 bits of memory and stores the number as 24 bits for the significant (the number part) and the remaining 8 bits for an exponential value.
This means that floats theoretically can store numbers up to 2^128, which gives up to 1.7014118346046923173168730371588e+38 including the sign bit (according to the Windows calculator).

However, you only have 24 bits for actual the range of numbers and one of those bits is used for the sign bit.
So even if the exponential value is 0, you only have actual numbers between -8,388,608 and 8,388,608, compared to n integer which can store every value between -2,147,483,648 and 2,147,483,648.

There was recently a very good article on Gamasutra about the problem, which is well worth the read. 

Basically what happens is that you lose precision at the large end of the scale.

You can see this by viewing Pluto in the following two movies;


Single Precision Floating Point Test


Double Precision Floating Point Test


As you can see the float version jerks like mad, while the double version is nice and smooth.

The problems with doubles is that hardware doesn’t currently support them very well, so they’re slow and they take up twice as much memory.
Also the buffers used in graphics are all 32bit floats, e.g. the Z buffer, so you’ll need to convert to eventually floats for rendering.

In my prototypes, I’m currently storing the positions as doubles and have written a double version of Vector3 (called Vector3D unsurprisingly) to help.
I store the planet orbits using spherical coordinates (using doubles) and then convert to the Cartesian Vector3D when needed.
All coordinates are then converted to the floating point Vector3’s in camera space, that is I take the current position of the camera as 0,0,0 and subtract the position of each object from the actual camera position in space.
Any shake you would see occours so far away from the camera as to be unnoticable.

It needs more doing to it but so far seems to work quite nicely.
There are some obvious artifacts with lights, and a few other things, but I think this is more of a bug in my maths than any serious issue.

Tags: , , , , February 26th, 2009 Posted in Game Development, XNA

Powered by WordPress | Blue Weed by Blog Oh! Blog | Entries (RSS) and Comments (RSS).

Nutter’s World is Stephen Fry proof thanks to caching by WP Super Cache