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

Add versioning info #899

Merged
merged 11 commits into from
Apr 11, 2017
Merged

Add versioning info #899

merged 11 commits into from
Apr 11, 2017

Conversation

sbtron
Copy link
Contributor

@sbtron sbtron commented Apr 7, 2017

Added explanation of how we envision glTF will version with backwards and forwards compatibility in the 2.x timeframe.

https://github.com/sbtron/glTF/tree/Versioning/specification/2.0#versioning

Updated schema to allow for forwards compatibility

  • additionalProperties:false is removed so that future versions can add additional properties and a 2.0 loader can still validate a 2.x file using schema.
  • All enums now use anyOf with an additional generic type object to allow for additional enums in future versions. This also addresses Replace 'gltf_enumNames' with 'oneOf', and other schema cleanup #891
  • Added optional minVersion property to allow asset authors to opt out of forwards compat and require a minimum supported version (similar to extensionsRequired concept).

"description": "FLOAT"
},
{
"type": "integer"
Copy link
Member

Choose a reason for hiding this comment

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

Why is this needed? Are there integers that are valid here, other than the ones listed above?

"enum": [ "MAT4" ]
},
{
"type": "string"
Copy link
Member

Choose a reason for hiding this comment

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

Same comment here with string. I'm not a JSON Schema expert, but I tried actually loading this branch into VSCode's JSON validator, and having this type at the end of the enum list allows arbitrary strings (or arbitrary ints in the comment above) to validate as correct. Removing this type means it will only validate with an exact match to one of the named enum values.

Copy link
Member

Choose a reason for hiding this comment

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

For example:

            "componentType": 99999,
            "type": "UNKNOWN"

This validates as allowed, because it matches anyOf integer and anyOf string.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There are a couple of ways these schemas will get used;

  • Viewers/Loaders can validate a file before trying to display it. The additional objects in anyOf allow loaders to validate a future version and continue to load it while ignoring any new elements.
  • Validators like in vs-code or glTF-validator may want to ensure the file is exactly 2.0 and not 2.1. Loosening up the schema will not be useful for this type of use case. If strict validations are required then these tools will need to use a stricter version of the schema that is specific to a version and doesn't do the forwards compatibility.

Do we need to consider making a "strict" version of the schema? By default the schema should be flexible because its still valid 2.0 with the forwards compat capabilities. We could do some script to create the stricter version that specifically checks for 2.0 without forwards compat.

Copy link
Member

Choose a reason for hiding this comment

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

I see. What behavior should a 2.0-capable loader take if it finds a "future" value that it doesn't understand? Will it just look for a default value in the schema?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The short answer is - it can be ignored. The long answer is - future updates will have to be designed such that new values can be ignored safely. Just pasted some examples we have been discussing below that goes into more detail.

@sbtron
Copy link
Contributor Author

sbtron commented Apr 8, 2017

The working group has been discussing this. Pasting it here so everyone can read. The examples are speculations of features that could be added in future versions and are only meant to show potential approaches of adding them.

To support forwards compatibility, whenever a new feature is added the spec needs to allow for the following requirements:

  1. Only specifying old the feature set (no new features used)
  2. Specifying the new feature but allowing for a fallback
    a. The fallback could be allowing older parsers to completely ignore the feature.
    b. If the new feature is not supported then use the old feature.
  3. Allowing authors to require that a runtime supports a new feature in order to load the asset

Requirement 1. is essentially backwards compatibility- you cannot change existing behavior in a spec update.

For requirement 2.a a glTF 2.0 parser should still be able to read a 2.1 file and completely ignore any new features.

For example say glTF 2.1 adds lighting capability by:

  • Adding a new light node at root
  • Added a new light property under the nodes property

(This is a completely made up example to show how this will work)

"lights": [
    "directional" : {
        "color": [ 1, 1, 1 ]
    },
],
"nodes": [
    {
        "children": [ ],
        "light": 0,
    }
]

A 2.0 parser can ignore any additional properties it finds whereas a 2.1 parser can correctly interpret those additional parameters.

For requirement 2.b any new features are ignored but a fall back behavior to 2.0 should exist.
For example say Draco Mesh compression is added to core glTF 2.1. To stay compatible with 2.0 clients, the compressed mesh should be provided along with the uncompressed mesh to allow for a fallback.
(Example only, not meant to be exact)

"primitives": [
    {
        "attributes": {
            "POSITION": 11,
            "NORMAL": 12,
            "TEXCOORD_0": 13
        },
        "indices": 10,
        "mode": 4,
        "draco_mesh": {
            "bufferView": 5,
            "indexCount": 1000,
            "vertexCount": 500,
            "attributes": [ "POSITION", "NORMAL", "TEXCOORD_0" ],
            "version": "0.9.1"
        }
    }
]

A 2.1 client can read and understand the “draco_mesh” element. A 2.0 client can simply ignore it and use the uncompressed geometry.

Requirement 3. will technically break forwards compatibility, but asset creators may want to choose to explicitly opt out of compatibility and require a specific version. The draco mesh compression is a good example where someone could choose to require a minimum version. For a client-server type of scenario where a JSON file points to the bin files, you can have both the compressed mesh and uncompressed mesh and a client can just download the one it understands. However, for a self contained binary glTF file scenario, you may only want to keep the compressed version since the whole point was to reduce the file size. In this scenario an author could choose to explicitly require a minimum version of 2.1. The JSON for such a file must still contain the required elements so that it validates, but it could just point to an empty geometry which will never gets used.

Requirements 2.a and 2.b are satisfied by allowing additional properties in all nodes of the JSON.
Requirement 3. is satisfied by adding a minVersion property to the asset node.

Enums provide an interesting challenge and example below show how to update them in a forwards compatible manner :
Imagine SPLINE interpolation is added in glTF 2.1 (its actually part of 2.0 but just using it as an example). Say SPLINE is added such that you can specify a fallback to Linear interpolation.
To do this in a forwards compatible way a new additionalSamplers property will need to be added under the channels node.

"samplers" : [
    {
        "input": 2,
        "interpolation": "LINEAR",
        "output": 3
    },
    {
        "input": 4,
        "interpolation": "SPLINE",
        "output": 5
    }
], "channels" : [
    {
        "additionalSamplers": [ 1 ],
        "sampler": 0,
        "target": {
            "node": 0,
            "path": "rotation"
        }
    }
]

Only a client that understands glTF 2.1 will understand the additionalsamplers property and will read the sampler which uses spline interpolation. Older samplers should simply ignore the additionalSamplers property and read the 2.0 sampler property to use linear interpolation.

@lexaknyazev
Copy link
Member

@sbtron @bghgary @pjcozzi
What should asset.version string look like? There could be two approaches:

  1. Arbitrary string, order and values to be defined manually by each subsequent update ("2.0", "2.0a", "2.2.45").
  2. Fixed format string value ("2.0", "2.1", "2.2", etc). In this case, a simple regex could be used to retrieve major/minor integer.

Same question about asset.minVersion.

@pjcozzi
Copy link
Member

pjcozzi commented Apr 10, 2017

@lexaknyazev following Khronos versioning, the format for version and minVersion could be "major.minor.revision"

I don't think we will have other variations other than perhaps minor and revision being optional.

@@ -131,6 +132,14 @@ Version 2.0 of glTF does not define compression for geometry and other rich data

> The 3D Formats Working Group is developing partnerships to define the codec options for geometry compression. glTF defines the node hierarchy, materials, animations, and geometry, and will reference the external compression specs.

## Versioning

Any updates made to glTF in a minor version will be backwards and forwards compatible. Backwards compatibility will ensure that any client implementation that supports loading a glTF 2.x file will also be able to load a glTF 2.0 file. Forwards compatibility will allow a client implementation that only supports glTF 2.0 to load glTF 2.x files while gracefully ignoring any new features it does not understand.
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps "minor or revision version"

@@ -131,6 +132,14 @@ Version 2.0 of glTF does not define compression for geometry and other rich data

> The 3D Formats Working Group is developing partnerships to define the codec options for geometry compression. glTF defines the node hierarchy, materials, animations, and geometry, and will reference the external compression specs.

## Versioning

Any updates made to glTF in a minor version will be backwards and forwards compatible. Backwards compatibility will ensure that any client implementation that supports loading a glTF 2.x file will also be able to load a glTF 2.0 file. Forwards compatibility will allow a client implementation that only supports glTF 2.0 to load glTF 2.x files while gracefully ignoring any new features it does not understand.
Copy link
Member

Choose a reason for hiding this comment

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

Throughout this section, replace "glTF 2.0 file" with "glTF 2.0 asset", which is more consistent with the rest of the spec. (Looks like the spec itself could use a tweak or two here as well if you do a quick search).

@@ -176,6 +185,9 @@ Each glTF asset must have an `asset` property. In fact, it's the only required t
}
```

> **Implementation Note:** Client implementations should first check whether a `minVersion` property is specified and ensure both major and minor versions can be supported. If no `minVersion` is specified, then clients should check the `Version` property and ensure the major version is supported. Clients that load [GLB format](GLB_FORMAT.md) should also check for the `minVersion` and `Version` properties in the JSON chunk as the version specified in the GLB header only refers to the GLB container version.
Copy link
Member

Choose a reason for hiding this comment

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

Throughout, Version -> version. Property names should be camelCase.

@pjcozzi
Copy link
Member

pjcozzi commented Apr 10, 2017

+1 from me. Just trivial comments.

@lexaknyazev
Copy link
Member

@lexaknyazev following Khronos versioning, the format for version and minVersion could be "major.minor.revision"

@pjcozzi
I'd make minor part required and maybe drop revision, because I don't think that file format needs it.
We can continue refining language of 2.0 spec without changing version string.

@pjcozzi
Copy link
Member

pjcozzi commented Apr 10, 2017

OK with me, but let's confirm on the call today about dropping revision.

@lexaknyazev
Copy link
Member

@sbtron @bghgary
Textures and bufferView conflicts resolved, please merge if it's ready.

@sbtron sbtron merged commit b1574e9 into KhronosGroup:2.0 Apr 11, 2017
},
{
"enum": [ "STEP" ],
"description": "When interpolation is `\"STEP\"`, animated value remains constant to the value of the first point of the timeframe, until the next timeframe."
"enum": [ "STEP" ]
Copy link
Member

@emackey emackey Apr 11, 2017

Choose a reason for hiding this comment

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

We should make a note to restore these once wetzel is upgraded to handle them. The whole point of my lobbying for the change from non-standard to anyOf was specifically to get these descriptions per-enum-value.

For example, here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Agreed. Descriptions are handled, but long descriptions make the generated text hard to read. Since these didn't have descriptions initially, I just put them back to the original for now.

Copy link
Member

Choose a reason for hiding this comment

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

I opened #955 for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants