castle-engine/castle-model-viewer

Honor Metadata containerField="value" in X3D 4

Closed this issue · 3 comments

As of now, CGE and view3dscene follow X3D 3 behavior (regardless if the input file declares X3D 3 or 4 in the header): MetadataXxx nodes by default use containerField = metadata.

This has changed in X3D 4, MetadataXxx nodes by default have now containerField = value. This means that in X3D 4, you don't need to explicitly spell out containerField in some cases, but OTOH you now have to specify containerField in some other cases.

See "[x3d-public] "deep dive" on containerField and value fields for Metadata* node examples" thread on x3d-public around 2023-07-03.

The minimal testcases (following Don Brutzman):

How to implement? Various options:

  • Minimal read implementation just looks at X3D version declared in the header, and behaves as if default containerField is value or metadata, depending on X3D version 3 or 4. This will be correct... but the strictness may be a bit uncomfortable for people switching between X3D 3 / 4? Esp. if users copy-paste X3D content between files, not paying attention to versions.
  • Minimal write implementation follows same logic. So we will omit containerField when it equals default to given X3D version.
  • More tolerant read implementation would be to just forgive user, regardless of the X3D version. This means being "smart" and "guessing" correct containerField, if not given explicitly. When we're inside MetadataSet, containerField can be guesses as value. Otherwise, containerField can be guesses as metadata. Is this "auto detection" not causing any surprising things? We should test.
  • More safe write implementation would just always output containerField of MetadataXxx nodes. So the output will work in any X3D version, and users who copy-paste between X3D files will have more verbose, but also safer content that "always works".

See more:

https://www.web3d.org/specifications/x3d-4.0.xsd

https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter15Metadata/

https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MetadataBoolean
https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MetadataDouble
https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MetadataFloat
https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MetadataInteger
https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MetadataSet
https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MetadataString

Related: #69

@coderextreme @brutzman You both expressed interest in this. Done :)

view3dscene, tovrmlx3d and all other Castle Game Engine tools now handle properly the fact that containerField of metadata nodes changed between X3D 3 and 4.

Both testcases

pass now. Both reading and writing.

Note that our implementation is strict. Trying to guess stuff was leading to potential weird problems -- e.g. MetadataXxx nodes also have metadata fields, but you probably don't indent to have metadata of metadata. Trying to make specialized warnings was also problematic, since this case (X3D versions changed containerField) is so exceptionally special, and trying to be smart about it would really complicate the overall X3D code.

So we follow exactly the spec, both when reading and writing:

  • containerField is value in X3D 4
  • containerField is metadata in X3D 3

We follow this logic, and if the resulting containerField points to non-existing field of parent -> we just make parsing error.

When writing, we omit the containerField if it matches the default, and "the default" depends on X3D version, per logic above.

( As usual, view3dscene snapshots with this fix will be build by Jenkins automatically. You can monitor it by looking at castle-engine/castle-engine@snapshot...master , when it will no longer contain the commit titled "Cannot warn about metadata container field here..." then it should be all deployed, and snapshot download on https://castle-engine.io/view3dscene.php will contain the fix. )