Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pnts update #116

Merged
merged 15 commits into from
Aug 22, 2016
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,10 @@ The 3D Tiles spec is pre-1.0 (indicated by `"version": "0.0"` in tileset.json).

Topic | Status
---|---
[tileset.json](#tileset.json) | :white_check_mark: **Good starting point**, will expand as we add new tile formats
[tileset.json](#tileset.json) | :white_check_mark: **Solid base**, a few more features expected
[Batched 3D Model](TileFormats/Batched3DModel/README.md) (b3dm) | :white_check_mark: **Solid base**, only minor changes expected
[Instanced 3D Model](TileFormats/Instanced3DModel/README.md) (i3dm) | :white_check_mark: **Solid base**, only minor changes expected
[Point Cloud](TileFormats/Points/README.md) (pnts) | :rocket: **Prototype**, needs compression and additional attributes
[Point Cloud](TileFormats/Points/README.md) (pnts) | :white_check_mark: **Solid base**, only minor changes expected
[Vector Data](TileFormats/VectorData/README.md) | :white_circle: **In progress**, [#25](https://github.com/AnalyticalGraphicsInc/3d-tiles/issues/25)
[Composite](TileFormats/Composite/README.md) (cmpt) | :white_check_mark: **Solid base**, only minor changes expected
[Declarative Styling](Styling/README.md) | :white_check_mark: **Solid base**, will add features/functions as needed, [#2](https://github.com/AnalyticalGraphicsInc/3d-tiles/issues/2)
Expand All @@ -91,7 +91,7 @@ Topic | Status

Topic | Status
---|---
Terrain | :white_circle: **Not started**, [quantized-mesh](https://cesiumjs.org/data-and-assets/terrain/formats/quantized-mesh-1.0.html) is a good starting point
Terrain | :white_circle: **Not started**, [quantized-mesh](https://cesiumjs.org/data-and-assets/terrain/formats/quantized-mesh-1.0.html) is a good starting point; in the meantime, folks are using [Batched 3D Model](TileFormats/Batched3DModel/README.md)
[OpenStreetMap](TileFormats/OpenStreetMap/README.md) | :white_circle: **Not started**
[Massive Model](TileFormats/MassiveModel/README.md) | :white_circle: **Not started**, might just use `b3dm`
Stars | :white_circle: **Not started**
Expand Down
8 changes: 4 additions & 4 deletions TileFormats/Instanced3DModel/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ var featureTableBinary = new Buffer(new Float32Array([
#### Quantized Positions and Oct-Encoded Normals

In this example, the 4 instances will be placed with an orientation `up` of `[0.0, 1.0, 0.0]` and `right` of `[1.0, 0.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.
and they will be placed on the corners of a quantized volume that spans from `-500.0` to `0.0` units in the `x` and `z` directions.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure if these numbers were supposed to also take the offset into account, so I adjusted them.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lasalvavida can you confirm this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this change is not correct. The offset puts the origin at (-250, 0, -250), then the scale makes the opposite corner -250 + 500 = 250 : (250, 0, 250).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah alright, I mistook the offset as the center. I'll need to update CesiumGS/cesium#4183 as well.


```javascript
var featureTableJSON = {
Expand All @@ -187,21 +187,21 @@ var featureTableJSON = {
}
};

var positionQuantizedBinary = new Buffer(new UInt16Array([
var positionQuantizedBinary = new Buffer(new Uint16Array([
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for catching this!

0, 0, 0,
65535, 0, 0,
0, 0, 65535,
65535, 0, 65535
]).buffer);

var normalUpOct32PBinary = new Buffer(new UInt16Array([
var normalUpOct32PBinary = new Buffer(new Uint16Array([
32768, 65535,
32768, 65535,
32768, 65535,
32768, 65535
]).buffer);

var normalRightOct32PBinary = new Buffer(new UInt16Array([
var normalRightOct32PBinary = new Buffer(new Uint16Array([
65535, 32768,
65535, 32768,
65535, 32768,
Expand Down
203 changes: 192 additions & 11 deletions TileFormats/Points/README.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,210 @@
# Points
# Point Cloud

## Contributors

* Sean Lilley, [@lilleyse](https://github.com/lilleyse)
* Tom Fili, [@CesiumFili](https://twitter.com/CesiumFili)
* Patrick Cozzi, [@pjcozzi](https://twitter.com/pjcozzi)
* Dan Bagnell, [@bagnell](https://github.com/bagnell)
* Sean Lilley, [@lilleyse](https://github.com/lilleyse)

## Overview

_TODO, [#22](https://github.com/AnalyticalGraphicsInc/3d-tiles/issues/22)_
The _Point Cloud_ tile format enables efficient streaming of massive point clouds for 3D visualization. Each point is defined by a position and optional properties used to define its appearance, such as color and normal, and optional properties that define application-specific metadata.

Using 3D Tiles terminology, each point is a _feature_.

## Layout

**Figure 1**: Points layout
A tile is composed of a header section immediately followed by a body section.

**Figure 1**: Point Cloud layout (dashes indicate optional fields).

![](figures/layout.png)

Positions are defined for high-precision rendering with [RTC](http://blogs.agi.com/insight3d/index.php/2008/09/03/precisions-precisions/). [#10](https://github.com/AnalyticalGraphicsInc/3d-tiles/issues/10)
## Header

The 20-byte header contains the following fields:

| Field name | Data type | Description |
| --- | --- | --- |
| `magic` | 4-byte ANSI string | `"pnts"`. This can be used to identify the arraybuffer as a Point Cloud tile. |
| `version` | `uint32` | The version of the Point Cloud format. It is currently `1`. |
| `byteLength` | `uint32` | The length of the entire tile, including the header, in bytes. |
| `featureTableJSONByteLength` | `uint32` | The length of the feature table JSON section in bytes. |
| `featureTableBinaryByteLength` | `uint32` | The length of the feature table binary section in bytes. If `featureTableJSONByteLength` is zero, this will also be zero. |

If `featureTableJSONByteLength` equals zero, the tile does not need to be rendered.

The body section immediately follows the header section, and is composed of a `Feature Table`.

Code for reading the header can be found in [Points3DModelTileContent.js](https://github.com/AnalyticalGraphicsInc/cesium/blob/3d-tiles/Source/Scene/Points3DTileContent.js) in the Cesium implementation of 3D Tiles.

## Feature Table

Contains per-tile and per-point values that define where and how to render points.

### Semantics

#### Point Semantics

These semantics map to an array of feature values that are define each point. The length of these arrays must be the same for all semantics and is equal to the number of points.

If a semantic has a dependency on another semantic, that semantic must 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 |
| --- | --- | --- | --- | --- |
| `POSITION` | `float32[3]` | A 3-component array of numbers containing `x`, `y`, and `z` Cartesian coordinates for the position of the point. | :white_check_mark: Yes, unless `POSITION_QUANTIZED` is defined. |
| `POSITION_QUANTIZED` | `uint16[3]` | A 3-component array of numbers containing `x`, `y`, and `z` in quantized Cartesian coordinates for the position of the point. | :white_check_mark: Yes, unless `POSITION` is defined. |
| `RGBA` | `uint8[4]` | A 4-component array of values containing the `RGBA` color of the point. | :red_circle: No. |
| `RGB` | `uint8[3]` | A 3-component array of values containing the `RGB` color of the point. | :red_circle: No. |
| `NORMAL` | `float32[3]`| A unit vector defining the normal of the point. | :red_circle: No. |
| `NORMAL_OCT16P` | `uint8[2]` | An oct-encoded unit vector with 16-bits of precision defining the normal of the point. | :red_circle: No. |

## Batch Table Semantics
#### Global Semantics

* `TILES3D_RGBA` - per-point colors, tightly packed interleaved RGBA `uint8` (32-bits per point). Byte length: `header.pointsLength * 4`
* `TILES3D_RGB` - per-point colors, tightly packed interleaved RGB `uint8` (24-bits per point). Byte length: `header.pointsLength * 3`
* `TILES3D_COLOR` - constant color for all points. RGBA `uint8`. Byte length: `4`
These semantics define global properties for all points.

If more than one color semantic is defined, the precedence order is `TILES3D_RGBA`, `TILES3D_RGB`, then `TILES3D_COLOR`. For example, if a tile's batch table contains both `TILES3D_RGBA` and `TILES3D_COLOR` properties, the runtime would render with per-point colors using `TILES3D_RGBA`.
| Semantic | Data Type | Description | Required |
| --- | --- | --- | --- |
| `POINTS_LENGTH`| `uint32` | The number of points to render. The length of each array value for a point semantic should be equal to this. | :white_check_mark: Yes. |
| `RTC_CENTER` | `float32[3]` | A 3-component array of numbers defining the center position when point positions are defined relative-to-center. | :red_circle: No. |
| `QUANTIZED_VOLUME_OFFSET` | `float32[3]` | A 3-component array of numbers defining the offset for the quantized volume. | :red_circle: No, unless `POSITION_QUANTIZED` is defined. |
| `QUANTIZED_VOLUME_SCALE` | `float32[3]` | A 3-component array of numbers defining the scale for the quantized volume. | :red_circle: No, unless `POSITION_QUANTIZED` is defined. |
| `CONSTANT_RGBA` | `uint8[4]` | A 4-component array of values defining a constant `RGBA` color for all points in the tile. | :red_circle: No. |

Examples using these semantics can be found in the [examples section](#examples) below.

### Point Positions

`POSITION` defines the position for a point before any tileset transforms are applied. Positions may be defined relative-to-center for high-precision rendering [4]. `RTC_CENTER` defines the center position.

#### Quantized Positions

If `POSITION` is not defined, positions may be stored in `POSITION_QUANTIZED` which defines point positions relative to the quantized volume.
If neither `POSITION` or `POSITION_QUANTIZED` are defined, the tile does not need to be rendered.

A quantized volume is defined by `offset` and `scale` to map quantized positions into model space.

**Figure 2**: A quantized volume based on `offset` and `scale`.

![quantized volume](figures/quantized-volume.png)

`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 model space using the formula:

`POSITION = POSITION_QUANTIZED * QUANTIZED_VOLUME_SCALE + QUANTIZED_VOLUME_OFFSET`

### Point Colors

If more than one color semantic is defined, the precedence order is `RGBA`, `RGB`, 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`.

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](../../Styling/README.md) may be used to change the final rendered color and other visual properties at runtime.

### Point Normals

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-encoded Normal Vectors
Oct-encoding is described in [*A Survey of Efficient Representations of Independent Unit Vectors* by Cigolle et al.](http://jcgt.org/published/0003/02/01/). An implementation for encoding and decoding these unit vectors can be found in Cesium's
[AttributeCompression](https://github.com/AnalyticalGraphicsInc/cesium/blob/master/Source/Core/AttributeCompression.js)
module.

### Examples

These examples show how to generate JSON and binary buffers for the feature table.

#### Positions Only

This minimal example has four points on the corners of a unit length square.

```javascript
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);
```

#### Positions and Colors

The following example has four points (red, green, blue, and yellow) above the globe. Their positions are defined relative-to-center.

```javascript
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]);
```
#### Quantized Positions and Oct-Encoded Normals

In this example, the 4 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 volme that spans from `-500.0` to `0.0` units in the `x` and `z` directions.

```javascript
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]);
```
## File Extension

`.pnts`
Expand All @@ -39,4 +213,11 @@ In any case, [3D Tiles Styling](../../Styling/README.md) may be used to change t

_TODO, [#60](https://github.com/AnalyticalGraphicsInc/3d-tiles/issues/60)_

`application/octet-stream`
`application/octet-stream`

## Resources

1. [*A Survey of Efficient Representations of Independent Unit Vectors* by Cigolle et al.](http://jcgt.org/published/0003/02/01/)
2. [*Mesh Geometry Compression for Mobile Graphics* by Jongseok Lee et al.](http://cg.postech.ac.kr/research/mesh_comp_mobile/mesh_comp_mobile_conference.pdf)
3. Cesium [AttributeCompression](https://github.com/AnalyticalGraphicsInc/cesium/blob/master/Source/Core/AttributeCompression.js) module for oct-encoding
4. [Precisions, Precisions](http://blogs.agi.com/insight3d/index.php/2008/09/03/precisions-precisions/)
Binary file modified TileFormats/Points/figures/Figures.pptx
Binary file not shown.
Binary file modified TileFormats/Points/figures/layout.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added TileFormats/Points/figures/quantized-volume.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading