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

EXT_property_animation extension proposal #1301

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions extensions/2.0/Vendor/EXT_property_animation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# EXT\_property\_animation

## Contributors

* Bryce Hutchings, Microsoft [@brycehutchings](https://twitter.com/brycehutchings)
* Gary Hsu, Microsoft [@bghgary](https://twitter.com/bghgary)
* Jamie Marconi, Microsoft [@najadojo](https://twitter.com/najadojo)
* Lewis Weaver, Microsoft

## Status

Draft

## Dependencies

Written against the glTF 2.0 spec.

## Overview

This extension adds a specification for animation data targeting arbitrary
properties, such as material colors, texture transform matrices and
extension properties.

## Extending Animations

Property animations can be added to an animation by adding the
`EXT_property_animation` extension to any glTF animation. For example, the
following defines an animation with two channels that modify a material's
baseColorFactor and roughnessFactor.
```json
"animations" : [
{
"channels" : [],
Copy link
Member

@lexaknyazev lexaknyazev Mar 31, 2018

Choose a reason for hiding this comment

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

Empty lists are forbidden by the current schema. Why not just re-use the existing path property (since the schema allows arbitrary strings there)?

Copy link
Author

Choose a reason for hiding this comment

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

I updated the sample such that it doesn't fall into this problem. We can't use the path as it exists because its defined as an enum value with only the four existing supported values.

There may be assets that wish only to animate some property values but not TRS or weights. Suggestions welcome for schema change or a best practice note for an identity animation that would go in core spec channels.

Copy link
Member

Choose a reason for hiding this comment

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

The schema allows any string in addition to pre-defined four values.

Copy link
Author

Choose a reason for hiding this comment

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

It does but the validator and more than one engine makes this a strict enum value. Plus this schema requires a node reference which isn't required with the JSON Pointer.

Copy link
Member

Choose a reason for hiding this comment

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

Node reference is not required

The latest validator revision (wip) no longer treats unknown enum values as errors.

The documentation about extensions explicitly says that they can extend allowed enums.

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 how it may work although this distinction complicates promotion a bit (so schemas must be remade for minor version updates).

Looking again at the animation example above, it seems that target isn't referenced by any other property but inlined into channel, so it's neither case, right?

Copy link
Contributor

Choose a reason for hiding this comment

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

schemas must be remade for minor version updates

I'm not sure what you mean. What schema changes are you talking about?

Looking again at the animation example above, it seems that target isn't referenced by any other property but inlined into channel, so it's neither case, right?

target is being referenced through animations[n].channels[m].target. Basically, any enum that will be parsed and interpreted by an implementation loading the core spec falls into case 2.

Copy link
Member

Choose a reason for hiding this comment

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

What schema changes are you talking about?

Updated properties reside in the extension object for now. If/when the same functionality goes into 2.x core version, the schema will be different. That would complicate implementations willing to support all combinations of core versions / extensions.

target is being referenced through animations[n].channels[m].target.

I'd say that target is contained within channel object, not referenced by it. So an engine may transitively treat the whole channel object as "unknown" as well as animation. Given that there're no external (indexed) references to any of animation-related objects, I don't see much difference with top-level image with updated mimeType.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see much difference with top-level image with updated mimeType.

I suppose it depends on implementation. If an implementation is a top-down loader, then I see a difference. Images referenced only by an extension will never be loaded if the extension is never read and thus the types in the image can be extended without fear of existing implementations falling over.

Copy link
Member

Choose a reason for hiding this comment

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

I suppose it depends on implementation.

Exactly. Given that the spec allows an asset to have only, e.g., images collection, we can't assume that an arbitrary implementation won't try to load them in advance unless we want to incorporate "top-down" approach into spec's compatibility strategy (which may be a good idea after all).

The existing schema prevents us from extending animation.channel.target with an extension object because animation.channel.target.path is required. With versioning concerns in mind, this means that the safest way of designing the extension schema is to use a new top-level collection.

"extensions" : {
"EXT_property_animation" : {
"channels" : [
{
"sampler" : 0,
"target" : "/materials/1/pbrMetallicRoughness/roughnessFactor"
donmccurdy marked this conversation as resolved.
Show resolved Hide resolved
},
{
"sampler" : 1,
"target" : "/materials/1/pbrMetallicRoughness/baseColorFactor"
}
]
}
},
"samplers" : [
{
"input" : 6,
"interpolation" : "CUBICSPLINE",
"output" : 7
},
{
"input" : 8,
"interpolation" : "LINEAR",
"output" : 9
}
]
}
]
```
`EXT_property_animation` adds a channels list separate from the core
specification's such that a different set of target values can be described.

### sampler

`sampler` has the same meaning and interpretation as the core specification's
`sampler` property. The property animation keyframes are defined in the normal
samplers list and the `sampler` reference indexes into this list for the
enclosing animation.

The sampler's output accessor type must match the targeted property's type.
Copy link
Member

Choose a reason for hiding this comment

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

I'd propose to provide a full list of allowed accessor types for each animatable core spec property.

Copy link
Member

Choose a reason for hiding this comment

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

Must all keyframe values comply with limitations specific to the animated property (e.g. min/max for material factors)?


### target

`target` is a [JSON Pointer](https://tools.ietf.org/html/rfc6901) in the glTF
JSON specifying a leaf property value. The property need not be present in the
original JSON; default or implicit properties can be animated. `target` must
reference a leaf property on an object that fits the data types supported by
accessor elements. These types are `MAT4`, `MAT3`, `MAT2`, `VEC4`, `VEC3`,
`VEC2`, and `SCALAR`. Properties that don't fit these data types cannot be
Copy link
Member

Choose a reason for hiding this comment

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

Is there any use of matrix interpolation?

animated. Animation of boolean or enum values is prevented as well as any
indexed object reference within the glTF JSON (i.e. a property animation can't
Copy link
Member

Choose a reason for hiding this comment

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

At the current state of glTF 2.0 core spec, we could say that animation of all integer properties must be disallowed. This would cover the list above.

describe the value `"material": 0` or a new vertex buffer accessor such as
`"POSITION" : 4`).

Because the [JSON Pointer](https://tools.ietf.org/html/rfc6901) is able to
reference any JSON property `EXT_property_animation` allows animation of all
current and future glTF extensions. The path value would simply include
`/extensions/EXT_my_extension/my_property`.

## Extension compatibility and fallback behavior

When possible, authoring tools should define reasonable initial values
for properties intended to be animated and mark the `EXT_property_animation`
extension as optional. Models including the extension optionally will still
render in all clients that support the core glTF 2.0 specification. Clients
that do not support the extension will fallback to an un-animated initial
state.

## glTF Schema Updates

* **JSON schema**: [animation.EXT_property_animation.schema.json](schema/animation.EXT_property_animation.schema.json)

## Known Implementations

* [Blender glTF 2.0 Exporter](https://github.com/najadojo/glTF-Blender-Exporter/compare/master...najadojo:EXT_property_animation)
Experiment/Proof of concept to export material property animations.
* [three.js](https://github.com/mrdoob/three.js/compare/dev...najadojo:EXT_property_animation)
Experiment/Proof of concept to import material property animations.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Animation Channel",
"type": "object",
"description": "Targets an animation's sampler at a node's property.",
"allOf": [ { "$ref": "glTFProperty.schema.json" } ],
"properties": {
"sampler": {
"allOf": [ { "$ref": "glTFid.schema.json" } ],
"description": "The index of a sampler in this animation used to compute the value for the target.",
"gltf_detailedDescription": "The index of a sampler in this animation used to compute the value for the target."
},
"target": {
"description": "The JSON Pointer of the property to be animated.",
"gltf_detailedDescription": "Must reference a leaf property on an object that fits the data types supported by accessor elements; animation of boolean or enum values is prevented as well as any indexed object reference within the glTF JSON.",
"type": "string"
},
"extensions": { },
"extras": { }
},
"required": [ "sampler", "target" ]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"$schema": "http://json-schema.org/draft-04/schema",
"title": "EXT_property_animation glTF extension",
"type": "object",
"description": "glTF extension for arbitrary animated properties.",
"allOf": [ { "$ref": "glTFProperty.schema.json" } ],
"properties": {
"channels": {
"type": "array",
"description": "An array of channels, each of which targets an animation's sampler at a property. Different channels of the same animation can't have equal targets.",
"items": {
"$ref": "EXT_property_animation.channel.schema.json"
},
"minItems": 1
},
"extensions": { },
"extras": { }
}
}