-
Notifications
You must be signed in to change notification settings - Fork 470
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
Feature Table Specification #118
Conversation
|
||
This may vary between implementations, but in javascript, a `TypedArray` cannot be created on data unless it is byte-aligned. | ||
This means that a `Float32Array` must be stored in memory such that its data begins on a byte multiple of four since each `float` contains four bytes. | ||
The data types used in 3D Tiles have a maximum length of four bytes, so padding to a multiple of four will work for all cases, since smaller types with lengths of one and two will also be byte-aligned. |
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.
We support doubles too.
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.
At least, maybe not yet but potentially.
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.
Okay, I'll make this less specific.
@lasalvavida @lilleyse when you open spec PRs, please include a link like https://github.com/lasalvavida/3d-tiles/tree/feature-table/TileFormats/FeatureTable |
|
||
## Contributors | ||
|
||
* Sean Lilley, [@lilleyse](https://twitter.com/lilleyse) |
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.
Add
Dan Bagnell, [@bagnell](https://github.com/bagnell)
The order can be Sean, you, Dan, and me.
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.
I'll make this change along with some other edits.
Check out my note here which may be relevant to this PR: #22 (comment) |
Made some tweaks in 877ffb9 |
In the context of this spec, the Keep |
Include an complete-ish example like the tile format specs have. |
Create a JSON schema for the JSON header. It should be pretty small, but we need to be precise, e.g., right now For JSON schema examples, see
Use JSON Schema 3. You will not be able to represent all requirements/relationships, but others can be put in the description and the spec's text. Make the schema a subdirectory of this new directory and include a link to it from the spec. |
Merge in master and you can do this. |
|
||
## Implementation Notes | ||
|
||
In JavaScript, a `TypedArray` cannot be created on data unless it is byte-aligned to the data type. |
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.
Do we have to pad the JSON string as opposed to the start of the binary body?
I would like this spec to include language similar to this from b3dm:
The body section immediately follows the header section, and is composed of two fields: Batch Table and Binary glTF.
I guess in either padding case, this is still true.
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.
Padding at the start of the binary body is not easily possible. When you add padding to the binary the byteOffset
values in the JSON need to change, which then may extend the JSON length and breaks the alignment of the binary.
I believe this is the same reason why binary gltf appends whitespace to the JSON rather than padding the binary.
@pjcozzi Is there a particular reason we are tied to v3 of the json-schema spec? I haven't found a way to define that featureTable.schema.json {
"$schema" : "http://json-schema.org/draft-04/schema",
"title" : "featureTable",
"type" : "object",
"description" : "A set of tile-format-specific semantics defining behavior for each feature in a tile.",
"patternProperties" : {
".*" : {
"properties" : {
"byteOffset" : {
"type" : "integer",
"minimum" : 0
}
},
"required" : ["byteOffset"]
}
}
} i3dm.featureTable.schema.json {
"$schema": "http://json-schema.org/draft-04/schema",
"title": "i3dm featureTable",
"type": "object",
"description": "A set of Instanced3DModel semantics defining behavior for each instance.",
"extends": { "$ref" : "featureTable.schema.json" },
"properties": {
"POSITION": {},
"POSITION_QUANTIZED": {},
"NORMAL_UP": {},
"NORMAL_RIGHT": {},
"NORMAL_UP_OCT32P": {},
"NORMAL_RIGHT_OCT32P": {},
"SCALE": {},
"SCALE_NON_UNIFORM": {},
"BATCH_ID": {},
"INSTANCES_LENGTH": {},
"QUANTIZED_VOLUME_OFFSET": {},
"QUANTIZED_VOLUME_SCALE": {}
},
"anyOf" : [
{
"required": ["POSITION"]
},
{
"required": ["POSITION_QUANTIZED"]
}
],
"dependencies": {
"POSITION_QUANTIZED": [
"QUANTIZED_VOLUME_OFFSET",
"QUANTIZED_VOLUME_SCALE"
],
"NORMAL_UP": [
"NORMAL_RIGHT"
],
"NORMAL_RIGHT": [
"NORMAL_UP"
],
"NORMAL_UP_OCT32P": [
"NORMAL_RIGHT_OCT32P"
],
"NORMAL_RIGHT_OCT32P": [
"NORMAL_UP_OCT32P"
]
},
"additionalProperties" : false
} |
Tooling. There are more tools for v3 than v4, e.g., like this tool we wrote: https://github.com/AnalyticalGraphicsInc/wetzel With that said, the v4 features look handy and we actually don't have that much JSON schema for 3D Tiles (we are definitely not updating glTF to v4 right now). If you want to update all of the 3D Tiles JSON schema to v4 right now, go for it, but please stay focused on the end goal of 3D Tiles and don't get too caught up in schema land. I have been there. |
Sounds good to me. Changes should be pretty minimal for the schema we already have. |
This should be ready for a look. |
Made some tweaks in d161ccb. |
"title" : "Feature Table", | ||
"type" : "object", | ||
"description" : "A set of semantics containing per-tile and per-feature values defining the position and appearance properties for features in a tile.", | ||
"patternProperties" : { |
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.
If a property is an object, does it have to have a byteOffset
property?
For example, if a tile format wants to define a Feature Table with a global semantic like
"KEY" : {
"some-property" : 0.0,
"another-property" : [1, 2, 3]
}
Can it do so as the schema is written here? (It might, I just don't know v4).
I suggest that we let the schema be flexible (and note this in the Feature Table spec) and rely on each tile format to specifically scope what is valid. This will be forward-compatible as we and others add new tile formats.
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.
Your example currently will fail since it doesn't have a byteOffset
. Do you want to just make byteOffset
optional?
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.
To elaborate, a semantic value is currently defined as either an object with a byteOffset
referencing the binary, an array, or a single value, and I think we currently forbid using semantics not defined for a tile format, so if it is an object, I think you should always have a byteOffset
.
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.
I read that in the spec, but this schema doesn't, for example, explicitly disallow strings.
I would make the schema for the generic Feature Table as generic as possible. Basically all we can say is that if a key is an object, and that object has a byteOffset
property, then byteOffset
should be:
"type" : "integer",
"minimum" : 0
Then let each tile format specifically scope what is valid for its Feature Table. This is no more work for an implementation with our current tile formats, and allows future tile formats maximum flexibility to define their data structures.
"$ref" : "featureTable.schema.json" | ||
}, | ||
{ | ||
"properties": { |
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.
Each of these need to define the value values, e.g., is it a scalar or an array, min/max, etc.
The validator, CesiumGS/3d-tiles-validator#5, would do full validation. The runtime could just throw an exception if the semantic is not an object with a Each semantic should also be explicit that it needs to be binary. |
Updated |
@@ -1,6 +1,7 @@ | |||
{ | |||
"$schema" : "http://json-schema.org/draft-03/schema", | |||
"title" : "boundingVolume", | |||
"$schema" : "http://json-schema.org/draft-04/schema", |
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.
In JSON schema v4, is there a way to say that only one of the three properties below can be present? I changed this in #123.
Very nice, @lasalvavida. @lilleyse can you do a final read and merge? That will also help you prep for the Batch Table spec. |
The schema has now been updated to reflect this. |
Nice! |
Everything looks good to me. This will be good to go after clarifying the byte alignment for the embedded glTF. |
Made the edit, let me know what you think. |
Add a note that this is suggested to keep proper btye alignment for the embedded glTF for the b3dm and i3dm formats. |
Updated |
Looks good to me, @pjcozzi do you want to do a quick read? Then I can merge. |
@@ -70,4 +70,4 @@ In JavaScript, a `TypedArray` cannot be created on data unless it is byte-aligne | |||
For example, a `Float32Array` must be stored in memory such that its data begins on a byte multiple of four since each `float` contains four bytes. | |||
|
|||
The string generated from the JSON header should be padded with space characters in order to ensure that the binary body is byte-aligned. | |||
The binary body should also be padded if necessary when there is data following the Feature Table. | |||
The binary body should also be padded to a multiple of eight bytes. This ensures byte-alignment for the embedded glTF in Batched 3D Models and Instanced 3D Models. |
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.
Are we sure about this? I thought the guarantees would be:
- Typed arrays in the Feature Table's binary body are byte-aligned to the size of their component type, e.g., 4 bytes for
float
. - Typed arrays in the Batch Table's binary body are byte-aligned to the size of their component type, e.g., 4 bytes for
float
. - In
b3dm
andi3dm
(put the wording in their specs), the Binary glTF is 8-byte aligned, so glTF's byte-alignment guarantees can be meet with respect to the tile's entire arraybuffer.
Updated. Is that better? |
Actually I'm not sure about this now. For the i3dm it works fine since the header is 32 bytes. For batched it's only 20 right now. If you don't have a batch table to pad, how are you supposed to start it on a multiple of 8? |
Good catch. I hate to say that the header (both Also, on the implementation side, I would like to merge all breaking b3dm changes in one PR since b3dm is so widely used. |
We could make it implicit that if there's no batch table, the glTF starts at the next multiple of 8 (24) |
Or alternatively pad the beginning and read until you hit the glTF magic. |
Well the simplest thing to do right now is nothing since the b3dm header is about to change to 24 bytes. |
Alrighty, then this is probably good to merge, unless anyone has anything else? |
Nice, big progress here! |
Feature Table specification document.