Exterior Space

Space System

Defining the layout

The space system defines the Form object, which is data that defines the layout of the virtual space.

Before specifying how layouts are represented, we first need to define what it means to "place" something in a virtual space. The standard then defines how data is related to the virtual space. In other words, it standardizes how the virtual space is reconstructed from the data.

A virtual space is modeled as a three-dimensional space (right-handed R3\mathbb{R}^3), with one distinguished "up" direction that determines the ground plane.

The ground plane is defined as the plane passing through the origin and orthogonal to the "up" direction. We then choose an orthonormal basis of the space such that two of its elements lie on this plane. so that any location on the ground can be expressed by a two-dimensional coordinate (x,y)(x, y), which we refer to as a Position.

type Position = [number, number]

Any location in the space can be expressed by a three-dimensional coordinate (x,y,z)(x, y, z). The third coordinate, called height, measures vertical displacement relative to the ground plane.

Together, a Position and a height determine any point in the virtual space. From this basis, we can now define the layout structure through a Form object.

Specification

Form: The layout

A Form object has following data:

interface Form {
    version: string // required
    layout: Embedding[] // required
    layoutMode: 'freeform' | `discrete` | `continuous` // recommended
    metadata: FormMetadata // optional
    ... // other possible modules
}

where

  • version is required for version control, allowing implementations to maintain backward compatibility.
  • layout is required, and its data is an array of Embedding, representing placed artifacts in the space.
  • layoutMode is recommended. It specifies which layout mode is used. If not provided, the freeform layout mode is used as the default.
  • metadata is optional. It is used to hold any additional data about the scene.

Embedding: Placed artifact

An Embedding represents a placed artifact, it has following data:

interface Embedding {
    artifact : Artifact // required
    position: Position // required
    height: number // optional for discrete and continuous; required for freeform
    rotation: number  // required
    stackIndex: number // required for discrete and continuous; optional for freeform
    ... // other possible modules
}

where

  • artifact is required, and its type must be model; it is the Artifact that is placed at the position. The local origin of the Artifact is used for the alignment.
  • position is required; it defines where the artifact is placed.
  • rotation is required; it defines the rotation of the artifact around the up direction.
  • height is optional for the discrete and continuous layout mode (and will be ignored if provided), but required for the freeform layout mode.
  • stackIndex is required for the discrete and continuous layout mode, but optional for the freeform layout mode (and will be ignored if provided). All Embedding in the layout must have distinct stackIndex.
In the reference implementation, Exterior Space, the convention is that the volume.width corresponds to the xx direction before rotation.

We are now ready to explain the three layout modes:

The discrete layout mode

The discrete layout mode requires position to be discrete, usually aligned with a lattice or cell-based coordinate logic. The rotation must be only 0, 90, 180, or 270 degrees. For all Embeddings, embedding.artifact.content is recommended to have its local origin at the lowest point of its mesh. It also requires the layout to follow the stacking logic. The zz coordinate in space is calculated by the stacking logic; thus, an explicitly provided height will be ignored.

The continuous layout mode

The continuous layout mode does not require position to be discrete. The model stored in artifact is recommended to have its local origin at the lowest point of its mesh. It requires the layout to follow the stacking logic. The zz coordinate in space is calculated by the stacking logic; thus, an explicitly provided height will be ignored.

The freeform layout mode

The freeform layout mode does not require position to be discrete, and the layout does not need to follow the stacking logic. The height will be used as the zz coordinate; thus, the stackIndex will be ignored. In practice, one can combine the position and height into coordinate:

interface Embedding {
    artifact : Artifact // required
    coordinate: [number, number, number] // required
    rotation: number  // required
    ... // other possible modules
}

which simply represents the space coordinate (x,y,z)(x, y, z).

Euler angles module

If the freeform layout mode is used, one can also use the optional Euler angles module. The Euler angles module replace the rotation by an EulerAngles

type EulerAngles = [number, number, number]

which describes the orientation of the artifact by Euler angles.

Block layout mode module

The block layout mode module is an optional extension applicable exclusively to the freeform layout mode.

In the block layout mode:

  • It is recommended that all used Artifact has volume metadata and its dimensions (length, width, height) are either exactly 1 or an integer. If not specified, their dimensions will be taken to be 1.
  • It is required that each component of a coordinate — that is, each of its three numbers — must individually be an integer.
  • The rotation of each Embedding must be either 0, 90, 180, or 270 degrees. If the Euler Angles Module is used, then each component of the EulerAngles must also be either 0, 90, 180, or 270 degrees.

flat layout mode and platform layout mode module

The flat layout mode and platform layout mode are two-dimensional layout modes, providing a top-down perspective space or side-scrolling space.

flat layout mode and platform layout mode are for future plan.

Stacking Logic

In the discrete and continuous layout modes, the placement of artifacts must follow a stacking logic to ensure physical consistency. The stacking logic defines how artifacts are placed vertically on top of existing artifacts, ensuring physical consistency.

All Embeddings in a layout must have distinct stackIndex values. It is recommended that all used Artifact has volume metadata. If not specified, their dimensions (length, width, height) will be taken to be 1.

The stacking logic has an optional even placement module with a threshold for evenness.

The stacking logic operates as follows:

  1. Order all Embeddings in layout by their stackIndex, in ascending order.
  2. For each to-be-placed Embedding:
  3. Find all Embeddings whose footprints overlap with the to-be-placed Embedding's footprint.
  4. For each found Embedding, determine its top. For each point in the footprint, keep only the Embedding that has the highest top at that point.
  5. If using the even placement module, and the evenPlacement property of the to-be-placed Embedding's Artifact is found and is true:
  • Calculate the difference between the highest top and the lowest top. If the difference exceeds the threshold, the layout is invalid.
  • Check the stackable property of all found Embeddings' Artifacts. If any of them is false, the layout is invalid.
  1. Otherwise, if even placement module is not used:
  • Find the Embedding with the highest top and check the stackable property of its associated Artifact. If it is false, the layout is invalid.
  1. Place the Artifact at the highest top. That is, the zz coordinate is set to the height of the highest top.
  2. If no overlapping Embedding occurs within the footprint, the current Embedding is placed at height zero (the floor).

The "top" of an Embedding is defined as the sum of its zz coordinate and the volume.height of its corresponding Artifact.

In freeform layout mode, stacking logic is not applied. Height must be explicitly specified per Embedding.

Reconstruct layout

We now relate the layout to the space.

  1. Calculate the zz coordinate for each Embedding by either applying stacking logic to the layout if freeform layout mode is not used, or using the height if freeform layout mode is used.
  2. For each Embedding in the layout:
    • Place the content model at the point in space corresponding to the coordinate defined by the position and the calculated zz coordinate.

Tile module

In many use cases, a boundary is necessary to define for a virtual space. Optional tile module provides an explicit way of doing so.

interface Form {
    ...
    tileList: Position[]
    tileVisibility?: boolean
    tileModel: Artifact
}

where

  • tileList is required if the tile module is used. It is an array of two-dimensional coordinates of tiles.
  • tileVisibility is optional if the tile module is used. It defines the visibility of the floor. It is by default true.
  • tileModel is optional if tileVisibility is false and will be ignored; otherwise, it is required and must be a model type Artifact.

A tile is a finite two-dimensional plane that serves as the floor of the space, with its local origin at the center of the plane. A tileList is an array of ground coordinates where tiles will be placed to form the complete floor.

If a tileList is provided, all other artifacts' footprints must be contained within the tiles, otherwise, the layout is not valid.

We define the footprint of an Embedding as the projection of its bounding box (defined by the volume of its corresponding Artifact) onto the ground plane.

In the reference implementation, Exterior Space, a tile has fixed dimensions of 1 by 1 and it is forced to be placed on an integer lattice.

Reconstruct floor

We now associate each tile with the space if tileVisibility is true:

For each Position element in the tileList, place tileModel at the corresponding coordinate, with the zz coordinate set to zero.

One example of cell-based coordinate logic

In discrete layout mode, it is often desirable to restrict placement onto a regular grid to simplify validation and user interaction. Here we provide an example of the cell-based coordinate logic.

The ground is divided into cells of size 12\frac{1}{2} by 12\frac{1}{2}. The cells are placed such that the origin of the space coincides with the corner points of nearby cells. Therefore,

  • the center of a cell belongs to the set {(a,b)  a, bZ+{±14}}\left\{(a, b)\ |\ a,\ b \in \mathbb{Z} + \{\pm\frac{1}{4}\}\right\}, known as the cell lattice,
  • the corners (vertices) of the cells belong to the set {(a,b)  a,b12Z}\{(a, b)\ |\ a, b \in \frac{1}{2}\mathbb{Z}\}, where 12Z\frac{1}{2}\mathbb{Z} denotes all integers and half-integers, known as the vertex lattice.

A valid placement of an Embedding must have its footprint’s corners exactly coinciding with some points in the vertex lattice. This restricts the Artifact to have only 12Z\frac{1}{2}\mathbb{Z} values for volume.length and volume.width.

Moreover:

  • If the volume.length is an integer, then the coordinate in the length direction must lie in 12Z\frac{1}{2}\mathbb{Z}.
  • If the volume.length is a half-integer, then the coordinate in the length direction must lie in Z+{±14}\mathbb{Z} + \{\pm\frac{1}{4}\}.
  • The same rule applies to volume.width.
In the reference implementation, Exterior Space, such cell-based coordinate logic is used.

Implementation hints

This section provides practical hints for implementing the space system.

Storage

In practice, Form is ideally stored on-chain as a digital asset. When a user visits their space, the client fetches the digital asset and reconstructs the scene of the space from it.

Therefore, the space system in practice simply introduces a new kind of digital asset; there is no additional development needed on-chain.

Invalid layout

In practice, invalid layout judgment happens per Embedding, i.e., it occurs if the to-be-placed Embedding is either beyond the boundary or cannot be placed according to the stacking logic. Thus, the stacking logic can be thought of as placing Artifacts one by one, where each placement may be valid or invalid.

For a smooth user experience, the client usually just skips invalid placements by removing the invalid Embedding and continuing with the next Embedding in the layout list.

Other modules

Optional modules can be added so that the Form can define global properties of the space.

Global shader module

The global shader module provides a default shader for all objects in the space.

interface Form {
    ...
    shader: Artifact
}

where shader must store an implementation of a shader, for example, using GLSL.

In practice, shaders are often specified individually within each Artifact; the global shader provides an optional fallback mechanism.

Global lighting module

The global lighting module provides a global lighting to the space.

interface Form {
    ...
    lighting: Artifact
}

where lighting must store a model. It is recommended that the model contains only directional lights. The model is placed at the space origin.

Global Scene module

Global scene module provides a global scene to the space.

interface Form {
    ...
    scene: Artifact
}

where scene must store a model. The model is placed at the space origin.

Global environment map module

Global environment map module provided a global environment map to the space.

interface Form {
    ...
    environment: Artifact
}

where environment must store an environment map (also known as HDRIs), which will be applied to the space.