Huge world size

Started by
27 comments, last by RichardS 19 years, 1 month ago
Quote:Original post by Trap
int pos = pos + (int)(v*dt);


And there lies my problem: with small position increments the int cast truncates to zero. So from what I can see, using int's will require the fixed-point manipulations I've been doing :-/

I do the relative camera thing for rendering so that the gfx api receives only 'well-conditioned' floats (i.e. near enough to the origin to be accurate enough for my purposes)

Well... I'm in the middle of totally encapsulating my WorldPosition so hopefully I can interchange the underlying types more easily in the future.
Advertisement
In Game Programming Gems 4 there's an article about solving accuracy problems in large world coordinates (presenting "far positions"), with the basic idea of decoupling position to a segment and a local offset inside the segment.
--Jetro Lauha - tonic - http://jet.ro
Hi,

just a few things.
What are you working on?
Why do you need things that have an so low accel?
What is your accel base on? (per sec?)

If you do the section stuff you can incooparete stuff like culling.
“Always programm as if the person who will be maintaining your program is a violent psychopath that knows where you live”
Quote:Original post by Aph3x
Quote:Original post by Trap
int pos = pos + (int)(v*dt);


And there lies my problem: with small position increments the int cast truncates to zero. So from what I can see, using int's will require the fixed-point manipulations I've been doing :-/

Sure it does truncate to 0. But floats truncate there too: bigfloat+tinyfloat==bigfloat
This truncation problem is 256 times smaller with ints than it is with floats. Try it!

If you need even finer position resolution you can use double with 53 bit resolution or int64 with 64 bit resolution.

If the smallest size a single pixel ever is is 0.1 mm than you can use ints without truncation problem up to world sizes up to around 400 km.
@Jetro: yer I mentioned how nasty that looks to Motoherp.

@Dragon:
I'm working on this.
The low accel is for a ~20,000 ton ship, currently 'feels about right' with 0.00006 ft/ms accel.
I have spatial partitioning/culling based on using each island as a locality, defined by a Delaunay triangulation.

@Trap: Hmmm... I'll see what happens when I finally get it to build again!
well, Trap's idea very good for continuous worlds, especially when implemented with graphics hardware (which internally only uses floating point precision). And it is very simple to implement.

The problem is as Aph3x says that when rendering the entire map, you get problems. But actually who wants to map the entire floating point plane to the screen? Talk about a "anti-injective" map...

regards
Acceleration to velocity doesn't truncate, as both can be stored as floats regardless of how you store your position.
Velocity to position truncates. If you have something that should move 1mm/s it will not move at all if your positions are 0.1 mm apart and each step is smaller than 100 ms. You could use accumulation of the (+v*dt)-terms over several steps to reduce this but choosing a bigger datatype should both be easier and faster.

You could use doubles for position and be done with it. You can then store every position on earth on a grid of 4 nm...
If you understand the IEEE 754 standard very well, you can easilly see how to mix the best of both worlds :
- a fixed precision, so that no jerks appear in the rendering (through the matrix combos) when the camera moves.
- have the flexible accuracy required by the physics when small values (derivatives) are combined and then added to bigger ones (positions)

I made a demo of a huge terrain in the past (65*65kms, could have been bigger), stable precision for rendered details, that also worked well with typical physics.

To solve rendering unstabilities, I simply biased the vertex positions by a huge power of two, just higher than the size of the world (say 2^16). This worked in theory up to the limits I mentionned.

Next to do that on a really big scale you must combine the ideas of clustering and biased floats. To have the most stable coordinates, according to the integer representation of the floating points, simply choose power of two sizes for your chunks. It's a worthy constraint.

Once done, this will have the effect to clamp the precision of your floating points as if they were of a constant metric precision, as if you used fixed points. They will not be less precise when far from your center (the biased origin). And then you are left with floating points only, which are far more practical to use and code than fixed point.
- because you don't need fixed point classes.
- because most libs prefer it (physics, geometry)
- because the CPU is faster with them
- because the GPU prefers them

Depending on your requirements you can apply these ideas to 32bits floats (24 bits mantissa) or 64 bits floats (53 bits mantissa). And also make something hybrid, for instance store positions as double floats, velocities as (single) floats.
"Coding math tricks in asm is more fun than Java"
Quote:Original post by Puppet
Check out the article "the continious world of dungeon seige".

It's worth checking out only to see how you would overengineer a solution to the problem. I'd stay away from that approach if I were, well, anyone. Seriously.

A more practical solution to the problem involves using integers (or fixed point numbers, same thing) for world positions and using floating-point numbers for vectors. Per Vognsen gave a good description here:

http://www.flipcode.com/cgi-bin/fcmsg.cgi?thread_show=11105

There are several other variations of the same theme, but they all amount to essentially the same thing (integer positions, float vectors).
@Charles: I keep attempting to read "What every computer scientist should know about floats etc"... but its *such* hard going ;)

@Christer: Nice link - in fact that appears to be the exact way I'm now trying. Encapsulated fixed-point int64's in a WorldPosition, and e.g. a method RelativeTo(const WorldPosition& aOrigin) that returns a 'well-conditioned' vector3 of floats being the difference between positions.
Also a method ApproxVector() that returns a float vector version of the world positions.

Moving the code over is proving to be one hell of a refactoring session!! :(

This topic is closed to new replies.

Advertisement