Warning
|
Point Cloud was deprecated in 3D Tiles 1.1. See pnts migration guide.
|
The Point Cloud tile format enables efficient streaming of massive point clouds for 3D visualization. Each point is defined by a position and by optional properties used to define its appearance, such as color and normal, as well as optional properties that define application-specific metadata.
Using 3D Tiles terminology, each point is a feature.
A Point Cloud tile is a binary blob in little endian.
A tile is composed of a header section immediately followed by a body section. The following figure shows the Point Cloud layout (dashes indicate optional fields):
A tile’s byteLength
shall be aligned to an 8-byte boundary. The contained Feature Table and Batch Table shall conform to their respective padding requirement.
The 28-byte header contains the following fields:
Field name | Data type | Description |
---|---|---|
|
4-byte ANSI string |
|
|
|
The version of the Point Cloud format. It is currently |
|
|
The length of the entire tile, including the header, in bytes. |
|
|
The length of the Feature Table JSON section in bytes. |
|
|
The length of the Feature Table binary section in bytes. |
|
|
The length of the Batch Table JSON section in bytes. Zero indicates that there is no Batch Table. |
|
|
The length of the Batch Table binary section in bytes. If |
The body section immediately follows the header section, and is composed of a Feature Table
and Batch Table
.
Contains per-tile and per-point values that define where and how to render points. More information is available in the Feature Table specification.
The full JSON schema can be found in
pnts.featureTable.schema.json
.
These semantics map to an array of feature values that define each point. The length of these arrays shall be the same for all semantics and is equal to the number of points. The value for each point semantic shall be a reference to the Feature Table binary body; they cannot be embedded in the Feature Table JSON header.
If a semantic has a dependency on another semantic, that semantic shall be defined.
If both POSITION
and POSITION_QUANTIZED
are defined for a point, the higher precision POSITION
will be used.
If both NORMAL
and NORMAL_OCT16P
are defined for a point, the higher precision NORMAL
will be used.
Semantic | Data Type | Description | Required |
---|---|---|---|
|
|
A 3-component array of numbers containing |
Yes, unless |
|
|
A 3-component array of numbers containing |
Yes, unless |
|
|
A 4-component array of values containing the |
No. |
|
|
A 3-component array of values containing the |
No. |
|
|
A lossy compressed color format that packs the |
No. |
|
|
A unit vector defining the normal of the point. |
No. |
|
|
An oct-encoded unit vector with 16 bits of precision defining the normal of the point. |
No. |
|
|
The |
No. |
These semantics define global properties for all points.
Semantic | Data Type | Description | Required |
---|---|---|---|
|
|
The number of points to render. This must be greater than zero. The length of each array value for a point semantic should be equal to this. |
Yes. |
|
|
A 3-component array of numbers defining the center position when point positions are defined relative-to-center. |
No. |
|
|
A 3-component array of numbers defining the offset for the quantized volume. |
No, unless |
|
|
A 3-component array of numbers defining the scale for the quantized volume. |
No, unless |
|
|
A 4-component array of values defining a constant |
No. |
|
|
The number of unique |
No, unless |
Examples using these semantics can be found in the examples section below.
POSITION
defines the position for a point before any tileset transforms are applied.
3D Tiles local coordinate systems use a right-handed 3-axis (x, y, z) Cartesian coordinate system; that is, the cross product of x and y yields z. 3D Tiles defines the z axis as up for local Cartesian coordinate systems (also see coordinate reference system).
Positions may be defined relative-to-center for high-precision rendering, see Precisions, Precisions. If defined, RTC_CENTER
specifies the center position and all point positions are treated as relative to this value.
If POSITION
is not defined, positions may be stored in POSITION_QUANTIZED
, which defines point positions relative to the quantized volume.
If neither POSITION
nor POSITION_QUANTIZED
is defined, the tile does not need to be rendered.
A quantized volume is defined by offset
and scale
to map quantized positions to a position in local space. The following figure shows a quantized volume based on offset
and scale
:
offset
is stored in the global semantic QUANTIZED_VOLUME_OFFSET
, and scale
is stored in the global semantic QUANTIZED_VOLUME_SCALE
.
If those global semantics are not defined, POSITION_QUANTIZED
cannot be used.
Quantized positions can be mapped to local space using the following formula:
POSITION = POSITION_QUANTIZED * QUANTIZED_VOLUME_SCALE / 65535.0 + QUANTIZED_VOLUME_OFFSET
Compressed attributes should be decompressed before any other transforms are applied.
If more than one color semantic is defined, the precedence order is RGBA
, RGB
, RGB565
, then CONSTANT_RGBA
. For example, if a tile’s Feature Table contains both RGBA
and CONSTANT_RGBA
properties, the runtime would render with per-point colors using RGBA
.
Point colors are defined in sRGB color space.
If no color semantics are defined, the runtime is free to color points using an application-specific default color.
In any case, 3D Tiles Styling may be used to change the final rendered color and other visual properties at runtime.
Per-point normals are an optional property that can help improve the visual quality of points by enabling lighting, hidden surface removal, and other rendering techniques. The normals will be transformed using the inverse transpose of the tileset transform.
Oct-encoding is described in A Survey of Efficient Representations of Independent Unit Vectors. Oct-encoded values are stored in unsigned, unnormalized range ([0, 255]
) and then mapped to a signed normalized range ([-1.0, 1.0]
) at runtime.
Note
|
Informative
An implementation for encoding and decoding these unit vectors can be found in CesiumJS’s AttributeCompression module. |
Compressed attributes should be decompressed before any other transforms are applied.
Points that make up distinct features of the Point Cloud may be batched together using the BATCH_ID
semantic. For example, the points that make up a door in a house would all be assigned the same BATCH_ID
, whereas points that make up a window would be assigned a different BATCH_ID
.
This is useful for per-object picking and storing application-specific metadata for declarative styling and application-specific use cases such as populating a UI or issuing a REST API request on a per-object instead of per-point basis.
The BATCH_ID
semantic may have a componentType
of UNSIGNED_BYTE
, UNSIGNED_SHORT
, or UNSIGNED_INT
. When componentType
is not present, UNSIGNED_SHORT
is used.
The global semantic BATCH_LENGTH
defines the number of unique batchId
values, similar to the batchLength
field in the Batched 3D Model header.
This section is informative
These examples show how to generate JSON and binary buffers for the Feature Table.
This minimal example has four points on the corners of a unit length square:
var featureTableJSON = {
POINTS_LENGTH : 4,
POSITION : {
byteOffset : 0
}
};
var featureTableBinary = new Buffer(new Float32Array([
0.0, 0.0, 0.0,
1.0, 0.0, 0.0,
0.0, 0.0, 1.0,
1.0, 0.0, 1.0
]).buffer);
The following example has four points (red, green, blue, and yellow) above the globe. Their positions are defined relative to center:
var featureTableJSON = {
POINTS_LENGTH : 4,
RTC_CENTER : [1215013.8, -4736316.7, 4081608.4],
POSITION : {
byteOffset : 0
},
RGB : {
byteOffset : 48
}
};
var positionBinary = new Buffer(new Float32Array([
0.0, 0.0, 0.0,
1.0, 0.0, 0.0,
0.0, 0.0, 1.0,
1.0, 0.0, 1.0
]).buffer);
var colorBinary = new Buffer(new Uint8Array([
255, 0, 0,
0, 255, 0,
0, 0, 255,
255, 255, 0,
]).buffer);
var featureTableBinary = Buffer.concat([positionBinary, colorBinary]);
In this example, the four points will have normals pointing up [0.0, 1.0, 0.0]
in oct-encoded format, and they will be placed on the corners of a quantized volume that spans from -250.0
to 250.0
units in the x
and z
directions:
var featureTableJSON = {
POINTS_LENGTH : 4,
QUANTIZED_VOLUME_OFFSET : [-250.0, 0.0, -250.0],
QUANTIZED_VOLUME_SCALE : [500.0, 0.0, 500.0],
POSITION_QUANTIZED : {
byteOffset : 0
},
NORMAL_OCT16P : {
byteOffset : 24
}
};
var positionQuantizedBinary = new Buffer(new Uint16Array([
0, 0, 0,
65535, 0, 0,
0, 0, 65535,
65535, 0, 65535
]).buffer);
var normalOct16PBinary = new Buffer(new Uint8Array([
128, 255,
128, 255,
128, 255,
128, 255
]).buffer);
var featureTableBinary = Buffer.concat([positionQuantizedBinary, normalOct16PBinary]);
In this example, the first two points have a batchId
of 0, and the next two points have a batchId
of 1. Note that the Batch Table only has two names:
var featureTableJSON = {
POINTS_LENGTH : 4,
BATCH_LENGTH : 2,
POSITION : {
byteOffset : 0
},
BATCH_ID : {
byteOffset : 48,
componentType : "UNSIGNED_BYTE"
}
};
var positionBinary = new Buffer(new Float32Array([
0.0, 0.0, 0.0,
1.0, 0.0, 0.0,
0.0, 0.0, 1.0,
1.0, 0.0, 1.0
]).buffer);
var batchIdBinary = new Buffer(new Uint8Array([
0,
0,
1,
1
]).buffer);
var featureTableBinary = Buffer.concat([positionBinary, batchIdBinary]);
var batchTableJSON = {
names : ['object1', 'object2']
};
In this example, each of the 4 points will have metadata stored in the Batch Table JSON and binary.
var featureTableJSON = {
POINTS_LENGTH : 4,
POSITION : {
byteOffset : 0
}
};
var featureTableBinary = new Buffer(new Float32Array([
0.0, 0.0, 0.0,
1.0, 0.0, 0.0,
0.0, 0.0, 1.0,
1.0, 0.0, 1.0
]).buffer);
var batchTableJSON = {
names : ['point1', 'point2', 'point3', 'point4']
};
The Batch Table contains application-specific metadata, indexable by batchId
, that can be used for declarative styling and application-specific use cases such as populating a UI or issuing a REST API request.
-
If the
BATCH_ID
semantic is defined, the Batch Table stores metadata for eachbatchId
, and the length of the Batch Table arrays will equalBATCH_LENGTH
. -
If the
BATCH_ID
semantic is not defined, then the Batch Table stores per-point metadata, and the length of the Batch Table arrays will equalPOINTS_LENGTH
.
See the Batch Table reference for more information.
The following extensions can be applied to a Point Cloud tile.
Point cloud tiles use the .pnts
extension and application/octet-stream
media type.
An explicit file extension is optional. Valid implementations may ignore it and identify a content’s format by the magic
field in its header.
This section is informative
Code for reading the header can be found in PntsParser.js
in the CesiumJS implementation of 3D Tiles.