KhronosGroup / glTF

glTF – Runtime 3D Asset Delivery
Other
7.14k stars 1.14k forks source link

[Clarification] Should I animate nodes that are NOT part of the scene? #1383

Closed Raveler closed 5 years ago

Raveler commented 6 years ago

Hey,

If one of the nodes that is being animated is not directly part of the scene (for example, it may be a node from a skeleton hierarchy that is not contained within the scene itself), should I animate it or not?

For an example, see the attached gltf file. If I load it with ThreeJs, it does not animate, because the skeleton nodes are not part of the scene. But this is not specified in the specs anywhere as far as I can see. What should I do? Animate them or not?

SimpleSkinNoChildren.txt

recp commented 6 years ago

I'm also confused about this. I think scene element could contains animation list which can help engines to ignore other animations which are not part of the active/default scene. For instance:

"scene": {
   "animations": [0, 1, 2, 3, 4, 5] /* ignore others; multiple scenes can use same animation */
}
donmccurdy commented 6 years ago

/cc @bghgary @lexaknyazev I think this is arguably a skinning question. If the transform of the skinned mesh is ignored and that of the skeleton hierarchy is used, then does it follow that the bones must be part of the scene, in order to have a meaningful transform? Are they implicitly attached to the scene root?

lexaknyazev commented 6 years ago

I think this question is a bit bigger than just skinning. One could argue that one animation cannot refer to targets belonging to different scenes.

No strong opinion on joint nodes being a part of a scene. We should probably check with engines on this.

bghgary commented 6 years ago

joint nodes being a part of a scene.

We have already encountered assets that does this in the wild. I think requiring this in the spec would result in a breaking change. This is a specific test case that we are adding to the asset generator: https://github.com/bghgary/glTF-Asset-Generator/issues/346

In fact, the simple skin in the tutorials from @javagl does this exact thing.

EDIT: I was wrong about the tutorial one. The joints are children of the skinned mesh.

donmccurdy commented 6 years ago

From the spec's discussion of skin.skeleton

The index of the node used as a skeleton root. When undefined, joints transforms resolve to scene root.

The spec is ambiguous on this — do just transforms resolve to the scene root if the joint isn't in the scene at all? What if skin.skeleton is a transformed node, but some of the joints are nowhere in the scene graph, do they resolve to that node or to the scene root? If we remove skin.skeleton, do all joint transforms resolve to scene root?

I can't think of any way to implement joints outside of the scene without appending them to the scene at runtime, so from the perspective of reducing the many edge cases in skinning, it would be nice to tighten this up in some (probably distant) future version...

Also consider:

For Version 2.0 conformance, the glTF node hierarchy is not a directed acyclic graph (DAG) or scene graph, but a disjoint union of strict trees. That is, no node may be a direct descendant of more than one node. This restriction is meant to simplify implementation and facilitate conformance.

If a joint is referenced only by a skin (it has no parent node), can it be reused in multiple scenes? Or does that imply that it is a child of two scenes, and therefore a descendant of multiple nodes?

bghgary commented 6 years ago

I can't think of any way to implement joints outside of the scene without appending them to the scene at runtime, so from the perspective of reducing the many edge cases in skinning

If we end up separating the skeleton from the node hierarchy completely in the future and suppose we did what I said here, then I think we explicitly should disallow the joint nodes to be referenced by the scene. If this works out, then I don't see any issue with multiple scenes referencing the same joint nodes.

donmccurdy commented 6 years ago

That makes sense, and if we think that's the right direction for the future then certainly it should remain valid now. But it does still leave some things to be defined about resolving joint transformations. Even if we remove skin.skeleton, I think this wording from its definition should remain:

When a joint has no parent, its transform resolves to the scene root.

bghgary commented 6 years ago

this wording from its definition should remain

+1

lexaknyazev commented 5 years ago

@bghgary @donmccurdy As discussed offline, all joints must belong to the same scene as a skinned mesh. This leaves out one more edge case when a skinned mesh itself doesn't belong to any scene. Should we disallow that as well?

recp commented 5 years ago

As discussed offline, all joints must belong to the same scene as a skinned mesh.

In this case, is it safe to ignore skin.skeleton property (in glTF 2.0)? Because since all joints will be in a scene (same scene), each one will have a parent or will be most parent?

lexaknyazev commented 5 years ago

The skeleton property should point to the closest common root (that must exist anyway) or to its parent (incl. transitive). skeleton property is not required for rendering or playing an existing animation of a skinned mesh.

bghgary commented 5 years ago

edge case when a skinned mesh itself doesn't belong to any scene

I'm not sure we should disallow this. I can imagine someone wanting to store skinned meshes in a glTF that is used to transmit that data by itself similar to materials or textures that are unreferenced.

lexaknyazev commented 5 years ago

OK, so the rule is:

When a skinned mesh belongs to a scene, all joints used by it must belong to the same scene.

right?

lexaknyazev commented 5 years ago

@bghgary @donmccurdy Can we move forward with the rule proposed above?

donmccurdy commented 5 years ago

Assuming I understand correctly, I think skinned mesh should say skin. A mesh may be stored with skinning-related attributes without being used by a skin. Conceivably that same mesh could be used by two different skins, each skin having different bones. The mesh is valid either way, so the rule should effectively be:

When a skin is referenced by a node within a scene, all joints used by the skin must belong to the same scene.