Expand description

Voxel geometry and coordinate systems.

block-mesh is designed to work for any 3-dimensional coordinate system. Doing this requires a somewhat complicated interplay between the types in this module. This documentation attempts to clarify what’s going on.

Quads and Faces

As most will know, a cube is composed of six faces.

    O--------O
  / |      / |
O--------O   |
|   |    |   |
|   O----|---O
| /      | /
O--------O

Fig 1: Cube

When rendering a cube to the screen, this will involve rendering six quads. A quad has four vertices, each with a unique UV texture coordinate and the same normal vector. The quad is rendered as two triangles, typically as four vertices and six indices.

           (U, V)                                         3    
             3                    3------> N            / ^     
           / |                  / |                   /   |     
 (U, V)  /   |                /   |                 2     |     
       2     |              2------> N                \   |     
       | \   |              | \   |                 2   \ |     
       |   \ |              |   \ |                 | \   1     
       |     1              |     1------> N        |   \       
       |   /   (U, V)       |   /                   |     1     
       | /                  | /                     |   /       
       0                    0------> N              V /         
    (U, V)                                          0           

Fig 2: Quad with vertices [A, B, C, D].
- (left) UVs.
- (middle) Normals.
- (right) Two triangles rendered using indices [0, 1, 2, 3, 2, 1].

Coordinate System

Different domains (e.g., your game engine or 3D modeling application) use different coordinate systems. Generating correct vertex positions, normals, and UV coordinates requires knowing the specifics of the coordinate system.

      +Y                 +Y                 -Y      
      | +Z               | -Z               | -Z    
-X____|/____+X     -X____|/____+X     +X____|/____-X
     /|                 /|                 /|       
   -Z |               +Z |               +Z |       
      -Y                 -Y                 +Y      

Fig 3: Various coordinate systems.
- (left) Left-handed coordinate system with Y up.
- (middle) Right-handed coordinate system with Y up.
- (right) Right-handed coordinate system with Y down.

Handedness

Handedness (also called chirality) is this weird property of 3D things. If two 3D things have different handedness, then it is impossible to rotate or translate one to look like the other; it’s only possible if you mirror it.

Most often, in games and 3D modeling, this corresponds to which way the Z axis grows. Often, +X is right, +Y is up, and the handedness determines whether +Z is into or out of the screen.

See wikipedia for more information on handedness:

Orientation

The orientation of the coordinate system determines which way textures are displayed on cube faces. Most often, the orientation is “Y up”, meaning that textures are displayed with the top of the image toward the +Y axis.

{N, U, V} Space

{N, U, V} space” is basically the face-local coordinate space (Normal, U, V).

The notion of an {N, U, V} space is convenient because we can return vertices, UVs, and indices in a consistent order regardless of the face. See OrientedBlockFace::quad_corners.

Putting It All Together

The output of the block-mesh algorithms are UnorientedQuads. These simply specify the size and minimum {X, Y, Z} coordinate of the cube they are a part of.

In order to get vertex positions, UV coordinates, normals, and mesh indices for an UnorientedQuad, it must be paired with an OrientedBlockFace, which specifies the {N, U, V} –> {X, Y, Z} mapping and the sign of the normal vector.

Six OrientedBlockFace definitions combine to form a QuadCoordinateConfig, which also implicitly defines the coordinate system.

Structs

Metadata that’s used to aid in the geometric calculations for one of the 6 possible cube faces.

A configuration of XYZ –> NUV axis mappings and orientations of the cube faces for a given coordinate system.

The minimum voxel and size of a quad, without an orientation. To get the actual corners of the quad, combine with an [OrientedBlockFace].

A quad covering a single voxel (just a single block face), without an orientation. To get the actual corners of the quad, combine with an [OrientedBlockFace].

Enums

Either the X, Y, or Z axis.

One of the six possible {N, U, V} –> {X, Y, Z} mappings.

Either the -X, +X, -Y, +Y, -Z, or +Z axis.

Constants

Coordinate configuration for a right-handed coordinate system with Y up.