-
Notifications
You must be signed in to change notification settings - Fork 473
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
Instanced 3D Model spec #34
Merged
Changes from 6 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
ae4bab0
Start of i3dm spec
pjcozzi 441375f
Tweaks
pjcozzi 93d7d73
Tweaks
pjcozzi 62b6928
Merge remote-tracking branch 'origin/composite' into i3dm
pjcozzi 8eaee4b
Add link
pjcozzi 01c852a
Copyedit
slchow 370e9af
Merge composite to i3dm
pjcozzi 17743a0
Optional batchId
pjcozzi 1098b64
Change uint32 to uint16
pjcozzi 790ce7a
i3dm renames: url, gltfByteLength, gltfFormat, batchTableByteLength
pjcozzi dff81e1
Merge branch 'composite' into i3dm
pjcozzi 02e19c2
Copyedit
slchow 9708dde
Merge remote-tracking branch 'origin/master' into i3dm
pjcozzi a162908
Change figure to uint16
pjcozzi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,113 @@ | ||
# Instanced 3D Model | ||
|
||
## Notes | ||
## Contributors | ||
|
||
**Use cases**: Trees, fire hydrants, sewer caps, lamps, traffic lights, etc. | ||
* Sean Lilley, [@lilleyse](https://twitter.com/lilleyse) | ||
* Patrick Cozzi, [@pjcozzi](https://twitter.com/pjcozzi) | ||
|
||
**Format** | ||
* Pointers to one or more internal or external (to share across tiles) glTF models. More than one model could also be handled with a `Composite` tile, should only that be supported? | ||
* Per-instance properties, e.g., position/translation, scale, rotation, and user-defined properties like `Batched 3D Models`. | ||
* Like `Batched 3D Model`, this needs to support per-instance metadata (and runtime interaction). | ||
* If it makes sense for glTF itself to support instancing, perhaps through an extension, is this tile format needed? | ||
## Overview | ||
|
||
**Cesium implementation**: can prototype something with separate `Model` instances, but it will be slow. Instead, add support for [ANGLE_instanced_arrays](https://www.khronos.org/registry/webgl/extensions/ANGLE_instanced_arrays/) to the Renderer, and then render glTF models with true instancing. | ||
_Instanced 3D Model_ is a tile format for efficient streaming and rendering of a large number of models, called _instances_, with slight variations. In the simplest case, the same tree model, for example, may be located - or _instanced_ - in several places. Each instance references the same model, and has per-instance properties, such as position. | ||
|
||
In addition to trees, Instanced 3D Model is useful for fire hydrants, sewer caps, lamps, traffic lights, etc. | ||
|
||
A Composite tile can be used to create tiles with different types of instanced models, e.g., trees and traffic lights. | ||
|
||
Instanced 3D Model maps well to the [ANGLE_instanced_arrays](https://www.khronos.org/registry/webgl/extensions/ANGLE_instanced_arrays/) extension for efficient rendering with WebGL. | ||
|
||
## Layout | ||
|
||
A tile is composed of a header immediately followed by a body. | ||
|
||
**Figure 1**: Instanced 3D Model layout (dashes indicate optional sections). | ||
|
||
![](figures/layout.png) | ||
|
||
## Header | ||
|
||
The 28-byte header contains: | ||
|
||
* `magic` - 4-byte ANSI string `i3dm`. This can be used to identify the arraybuffer as an Instanced 3D Model tile. | ||
* `version` - `uint32`, which contains the version of the Instanced 3D Model format. It is currently `1`. | ||
* `byteLength` - `uint32`, which contains the length of the entire tile, including the header, in bytes. | ||
* `batchTableLength` - `uint32`, which contains the length of the batch table. This must be greater than or equal to zero. Zero indicates there is not a batch table. | ||
* `glTFLength` - `uint32`, which contains the length of glTF field in bytes. This must be greater than or equal to zero. | ||
* `glTFFormat` - `uint32`, which indicates the format of the glTF field of the body. `0` indicates it is a uri, `1` indicates it is embedded binary glTF. See the glTF section below. | ||
* `instancesLength` - `uint32`, which contains the number of instances. This must be greater than or equal to zero. | ||
|
||
_TODO: code example reading header_ | ||
|
||
If either `glTFLength` or `instancesLength` equal zero, the tile does not need to be rendered. | ||
|
||
The body immediately follows the header, and is composed of three fields: `Batch Table`, `glTF`, and `instances`. | ||
|
||
## Batch Table | ||
|
||
_TODO: create a separate Batch Table spec that b3dm, i3dm, etc. can reference?_ | ||
|
||
The batch table is a `UTF-8` string containing JSON. It immediately follows the header. It can be extracted from the arraybuffer using the `TextDecoder` JavaScript API and transformed to a JavaScript object with `JSON.parse`. | ||
|
||
Each property in the object is an array with its length equal to the number of instances in the tile. Each array is a homogeneous collection of `String`, `Number`, or `Boolean` elements. Elements may be `null`. | ||
|
||
An instance's `batchId` is used to access elements in each array and extract the corresponding properties. For example, the following batch table has properties for two instances: | ||
```json | ||
{ | ||
"id" : ["unique id", "another unique id"], | ||
"displayName" : ["Tree species", "Another tree species"], | ||
"yearPlanted" : [1999, 2003] | ||
} | ||
``` | ||
|
||
The properties for the instance with `batchId = 0` are | ||
```javascript | ||
id[0] = 'unique id'; | ||
displayName[0] = 'Tree species'; | ||
yearBuilt[0] = 1999; | ||
``` | ||
|
||
The properties for `batchId = 1` are | ||
```javascript | ||
id[1] = 'another unique id'; | ||
displayName[1] = 'Another tree species'; | ||
yearBuilt[1] = 2003; | ||
``` | ||
|
||
## glTF | ||
|
||
The glTF field immediately follows the batch table (or immediately follows the header, if `header.batchTableLength` is zero). | ||
|
||
[glTF](https://www.khronos.org/gltf) is the runtime asset format for WebGL. [Binary glTF](https://github.com/KhronosGroup/glTF/tree/master/extensions/Khronos/KHR_binary_glTF) is an extension defining a binary container for glTF. Instanced 3D Model uses glTF 1.0 with the [KHR_binary_glTF](https://github.com/KhronosGroup/glTF/tree/master/extensions/Khronos/KHR_binary_glTF) extension. | ||
|
||
`header.glTFFormat` determines the format of the glTF field. When it is `0`, the glTF field is | ||
|
||
* a UTF-8 string, which contains a uri to a glTF model. | ||
|
||
When the value of `header.glTFFormat` is `1`, the glTF field is | ||
|
||
* a binary blob containing binary glTF. | ||
|
||
In either case, `header.glTFLength` contains the length of the glTF field in bytes. | ||
|
||
## Instances | ||
|
||
The `instances` field immediately follows the `glTF` field (which may be omitted when `header.glTFLength` is `0`). | ||
|
||
The `instances` field contains `header.instancesLength` tightly packed instances. Each instance has three fields: | ||
|
||
* `longitude` - `double`, the longitude, in radians, in the range `[-PI, PI]`. | ||
* `latitude` - `double`, the latitude, in radians, in the range `[-PI / 2, PI / 2]`. | ||
* `batchId` - `uint32` in the range `[0, header.batchTableLength)`, which indicates the corresponding properties. | ||
|
||
_TODO: make this much more memory efficient and more general._ | ||
|
||
Each instance is in the east-north-up reference frame (`x` points east, `y` points north, and `z` points along the geodetic surface normal). | ||
|
||
## File Extension | ||
|
||
`.i3dm` | ||
|
||
## MIME Type | ||
|
||
_TODO_ | ||
|
||
`application/octet-stream` |
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a word missing here? I couldn't make sense of "contains
header.instancesLength
tightly packed instances"There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A word is not missing. That should read as "the instances field contains x tightly packed instances" where the value of "x" is defined by
header.instancesLength
.If you think we could make it more clear, please have at it.