Coordinate System

Home --> Programming Projects --> Fractal Block Engine --> Coordinate Systems

The 6 Directions


Viewer Centric Positions

The viewer (the eye of the player) is always in a chunk in the active chunk tree. In a sense, a chunk which contains the viewer position is the center of the world.

The viewer is always "on a certain level" which we call the viewer level.

The chunk of the viewer is the chunk which contains the viewer which is on the viewer's level.

A chunk is a center chunk iff it is the (unique) chunk of a level which contains the viewer position. In other words, a chunk is a center chunk iff it is an ancestor of the chunk of the viewer.

Within a level, the center chunk is said to have viewer centric position (0,0,0). The chunk of that same level that is 1 chunk to the right (right is the positive x direction) is (1,0,0), etc.

We call the viewer centric position of a chunk the VCP of the chunk for short.

So the viewer's chunk has vcp (0,0,0). The parent of the viewer's chunk also has vcp (0,0,0), etc.

When the viewer moves from one chunk to an adjacent one, this will change the vcp's of the chunks on his level L. However the vcp's of chunks on level L-1 may or may not change, etc. The movement of the player is like walking on a treadmill: when the player moves from chunk to chunk, he keeps looping back and the world is the thing that actually moves.

Ways to Describe the Position of a Chunk

There are 3 main ways to describe the position of a chunk:

Method #1: Chunk path (also called a block path)

The path of the chunk (or the chunk path of a chunk) is the path of the chunk from the root of the chunk tree.

This is described as a string of triples of hex characters, separated by underscores. For example 7a3_221 is the path of a chunk C_2 on level 2 which we can reach as follows: start at the root C_0 and go to block (7,10,3) of that chunk. That block is the same as lets say chunk C_1. Then in C_1 we go to the block (2,2,1). That block is the chunk for C_2.

The root is special and it has chunk path "EMPTY_PATH". Note that the root chunk is on level 0, its children are on level 1, etc.

See here for more on block paths and how to compute the path of an adjacent chunk.

The main advantages of using the chunk path to refer to a chunk are 1) these paths do not change when the player moves or restarts the program and 2) the path of a chunk is valid even if the chunk is not in the active chunk tree.

The main disadvantage of using the chunk path to refer to a chunk is that this is slower than the other methods (when the chunk is very deep in the tree).

Method #2: Level + VCP

We can also refer to the position of a chunk using the level it is on (which is an integer) and its VCP (viewer centric position).

An advantage of this method is that the level + VCP combination only uses 4 integers. Another advantage is the level + VCP combination makes it easy to talk about the positions of vectors in a level. We discuss this later with "level positions".

The main disadvantage of this method is that VCP's will likely change whenever the viewer moves from one chunk to another.

Method #3: Chunk Id

Every chunk in the active chunk tree has a chunk id (which is an integer). The system that maintains the active chunk tree has a counter N which starts at zero. Every time a chunk is added to the active chunk tree, is gets assigned the chunk id N and then N gets incremented.

An advantage of this method is that each chunk id is a single integer, so this is very simple.

Here are some disadvantages: 1) Every time the user loads a game, the active chunk tree is rebooted and so the chunk id counter goes back to zero. For this reason, chunk ids CANNOT be used for long term storage. 2) Chunk ids cannot refer to chunks that are not in the active chunk tree.


Ways to Describe the Position of a Vector (Point)

(Level and Local Positions)

Consider an entity, like a bullet or a rocket. This entity exists on some level L. We want to represent its position as a vector (x,y,z). There are two ways to do this: with a local position or with a level position.

Method #1: Local Positions

Every chunk has its own coordinate system. The origin of this coordinate system is in the left back bottom position of the chunk. So if (x,y,z) is a point in the chunk then each of x,y,z is between 0.0 and 16.0 inclusive.

Given a point in a chunk, we call the point's position relative to the chunk's coordinate system the local position of the point. For example, if a bullet is at the center of chunk C, then the bullet has the local position (8.0, 8.0, 8.0).

Method #2: Level Positions

Consider a point on level L. The level position (LP) of the point is the position of the point relative to the center chunk of level L.

For example, if a point is in the center chunk of a level, then its local position is the same as its level position.

In a sense a point in space exists in more than one level. So for example we can convert a point's level position for level 13 into its level position for level 12, etc.

Note that when the player moves from one chunk to another, this will likely change the level positions of other entities.


Ways to Describe the Position of a Block

(Block Positions (BP) and Local Block Positions (LBP))

Block Positions are to Level Positions as Local Block Positions are to Local Positions.

Method #1: Local Block Positions (LBP)

A chunk contains 16x16x16 blocks (either solid or empty). The positions of these blocks within the chunk are called the local block positions (LBPs) of the blocks. The left back bottom block in a chunk has the lbp (0,0,0). The right front top block in a chunk as the lbp (15,15,15). So an lbp for a block in a chunk is a triple (x,y,z) of integers such that each x,y,z is between 0 and 15 inclusive.

Actually each of x,y,z is a signed 8 bit integer (signed char). This allows representing the positions of blocks that are slightly outside the current chunk. This is sometimes useful.

A local block position can be represented by a single 4 byte integer, which we call a local block position hashcode.

Note: to refer to a block in a level of the chunk tree, all you need is a way to refer to the chunk that contains the block together with the local block position of the block within that chunk.

Method #2: Block Positions (BP)

Every block is in some level. If a chunk C is in level L, then the blocks of C we also say are in level L (but when we subdivide each such block, the chunk that the block becomes is in level L+1).

The block position (BP) of a block is the position of the block relative to the center chunk of whatever level the block is in. A block position is a triple (x,y,z) of integers.

For example, if a block is in the center chunk of a level, then the block's block position is the same as its local block position.

Consider the block B_1 with block position (15,3,4) of the center chunk of a level. The block B_2 one to the right of this has block position (16,3,4). This is not located in the center chunk C_1, but instead it is the chunk C_2 one to the right of the center chunk. The block B_2 has local block position (0,3,4) inside the chunk C_2.