Coordinate System
Home -->
Programming Projects -->
Fractal Block Engine -->
Coordinate Systems
The 6 Directions
- positive x = RIGHT
- negative x = LEFT
- positive y = FRONT
- negative y = BACK
- positive z = UP
- negative z = DOWN
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:
- The path of the chunk (its chunk path)
- The level of the chunk together with the chunk's VCP
- The chunk id of the 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.