KhronosGroup / glTF

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

Handling multiple scenes without a default scene #815

Closed javagl closed 7 years ago

javagl commented 7 years ago

The 1.0 specification says about scenes :

The glTF asset contains one or more scenes, the set of visual objects to render. Scenes are defined in a dictionary object scenes. An additional property, scene (note singular), identifies which of the scenes in the dictionary is to be displayed at load time.

Hereby, the glTF.scene property is not required

Several loaders and viewers are assuming that the glTF.scene property is present. Moreover, it is not clear what should happen when there are multiple scenes, but no default scene.

Should viewers then load and display all scenes? Or only the first scene? Or an arbitrary one?

(This question has some analogies to the cameras: There is no default camera, and viewers seem to be free to pick any camera for the initial rendering).


Pull request where this issue originated from: https://github.com/KhronosGroup/glTF-Sample-Models/pull/18#issuecomment-271922646 Related issues: https://github.com/KhronosGroup/glTF/issues/39 , https://github.com/KhronosGroup/glTF/issues/150 , and maybe others...

RemiArnaud commented 7 years ago

Most basic application can visualize first scene. A more advance application can show user available scenes, and cameras and let user decide. Try to double click on a collada (.dae) with multiple cameras on a mac and see preview let you chose camera. A game or embedded application is expecting some specific scenes and specific cameras and would know what to do with.

pjcozzi commented 7 years ago

@lexaknyazev what do you think?

Since scenes will be an array, not an object property, I think it is reasonable to just render the scene at index 0 by default. Rendering all scenes by default could create artifacts if the scenes are on top of each, for example.

javagl commented 7 years ago

Off-topic but somehow related: A similar recommendation could be included for the cameras. One could even consider to introduce an optional camera property, to indicate the camera to use when the asset is loaded. A caveat here may be: When there are multiple scenes and multiple cameras, then I'm not sure whether it would make sense (or whether it should even be allowed) to use a camera that is attached to a node that is not part of the current scene...

lexaknyazev commented 7 years ago

@javagl There's no limitation on having the same node in different scenes.

@pjcozzi Are you proposing following behavior?

javagl commented 7 years ago

My point was a different one: I think that scenes and cameras are implicitly "connected", via the nodes that they contain or attached to.

(EDIT: But I might have been wrong. One could simply say that the list of cameras that can be selected by the user are only the ones that are attached to nodes of the currently active scene. So even though it might be based on a misunderstanding, I'll leave the remaining part of this comment here)

Assume that you have two scenes

And there are two cameras:

When only sceneA is rendered - what should happen if someone selects cameraB? Depending on the scene management, the nodeB might not be considered as "valid", because it is not part of the "active" scene. But maybe this is yet another nitpick that can be solved by the application.

I think that Patricks comment did not refer to the nodes or an empty scenes array, but only to the original question: What should happen when there are multiple elements in the scenes, but none selected as the default via the top-level glTF.scene property. (It's not yet entirely clear to me what happens with this. If all top-level elements are replaced by arrays, then this property would either be removed, or become a number (integer) that indicates the index of the default scene)

pjcozzi commented 7 years ago

@javagl I don't think we can make any default camera requirements. For example, in Cesium, if a glTF model includes cameras, the user most likely does not want to use it by default since they already set up their camera in the engine.

@pjcozzi Are you proposing following behavior?

  • If there's no scenes or it's empty, all nodes belong to an implicit scene 0;
  • if there's no scene, then scenes[0] is selected.

Not exactly, I am proposing:

javagl commented 7 years ago

@javagl I don't think we can make any default camera requirements.

I did not propose that, but see that if there was an explicit camera field, some viewers would still like to ignore this and use their own camera. So what I said about the cameras can be considered as obsolete, and the actual question about the scenes seems to approach a consensus.

recp commented 7 years ago

I'm working on library (C99) based on COLLADA specs and working on viewer (currently Cocoa), after finished implement full COLLADA specs I'll work on glTF as well (will be open source soon)

Here how to I select camera for my scene: When parsing camera nodes in COLLADA scene, I select first/top camera and attach it to scene as default camera (maybe I must use breadh-first to pick), if there is no camera then I create default view and projection matrix.

In viewer, currently I'm rendering with default camera but I'll list all cameras, user may pick any camera in scene. @javagl I think you are right, cameras which are only referenced in visual scene must be selectable... Also I it seems it is a viewer/engine issue

Sorry when started working on glTF I'll speak more specific to glTF :/

pjcozzi commented 7 years ago

@recp slightly tangential, but when your glTF engine is ready, please open a pull request to add it to https://github.com/KhronosGroup/glTF#gltf-tools

recp commented 7 years ago

PS: I'll also mix glTF with COLLADA through technique/profiles (sorry this is out of topic :), I'm a little excited):

<mesh>
  <source id="mesh-data">
     <technique profile="gltf">
    <gltf type="binary" url="gtlf-mesh.bin" />
     </technique>
  </source>
  <vertices id="mesh-vertices">
    <input semantic="POSITION" source="#mesh-data"/>
  </vertices>
  <triangles count="...">
    <input semantic="VERTEX" source="#mesh-vertices" offset="0"/>
    <input semantic="NORMAL" source="#mesh-data"     offset="0"/>
    <p>...</p>
  </triangles>
<mesh>

I'm really working hard to finish this importer/exporter/runtime lib and rendrer lib both are written in C99 I'd be happy to create a PR when finished, thanks!

lexaknyazev commented 7 years ago

@pjcozzi

Not exactly, I am proposing:

  • scenes.length must be >= 1

Just to be clear: are scenes required now? Also, what about nodes not included in any scene?

pjcozzi commented 7 years ago

Not exactly, I am proposing:

  • scenes.length must be >= 1

Just to be clear: are scenes required now? Also, what about nodes not included in any scene?

Ah, I remember now. We wanted to be very loose with what was required so that users could use bits and pieces of glTF, e.g., a user might not want a scene hierarchy, they just want to access the nodes directly and put them in their own structure or even just access the meshes directly. I think this is still a good idea so that would make it hard to require scenes.

Do you think it is reasonable to require scenes only when scene is defined?

lexaknyazev commented 7 years ago

Let's look at all combinations:

The question about nodes not participating in any scene remains.

pjcozzi commented 7 years ago

The question about nodes not participating in any scene remains.

I would ignore them like glTF does for other extra properties like accessors.

But this

Nor scene, neither scenes defined. We can safely imply single default scene of all nodes.

makes it sound like they should be one node scenea that are rendered by default.

Perhaps if scenes is not defined, nothing is rendered; this is only used when glTF is packaged with another format, e.g., a game engine format might reference glTF nodes directly.

lexaknyazev commented 7 years ago

Perhaps if scenes is not defined, nothing is rendered

Makes sense. This should clear remaining ambiguity, given that scenes[s].nodes should contain only top-level nodes.

pjcozzi commented 7 years ago

Cool, let's do it!

lexaknyazev commented 7 years ago

@pjcozzi There's a small JSON-related issue with

scenes.length must be >= 1

Currently, each top-level array is empty by default. "default" value in JSON-Schema must obey reqs for "provided" value, so this is INVALID:

{
    "scene" : {
        "allOf" : [ { "$ref" : "glTFid.schema.json" } ],
        "description" : "The index of the default scene."
    },
    "scenes" : {
        "type" : "array",
        "description" : "An array of scenes.",
        "items" : {
            "$ref" : "scene.schema.json"
        },
        "minItems" : 1,
        "default" : []
    }
}

What do you prefer:

I think that we should disallow empty arrays throughout the whole spec: when an asset doesn't need some kind of objects, it mustn't define corresponding top-level array at all.

pjcozzi commented 7 years ago

I think that we should disallow empty arrays throughout the whole spec: when an asset doesn't need some kind of objects, it mustn't define corresponding top-level array at all.

+1

pjcozzi commented 7 years ago

Updated in #826