GLTF Extensions

Posting this again as for some reason it has been unlisted.

Hi,

I’ve been testing the new glTF Mesh and Structural Metadata features, and they appear to be working well. However, I’ve noticed that the extensionsUsed and extensionsRequired arrays are not populated in the resulting glTF files. The glTF 2.0 specification states that all extensions used must be declared in the extensionsUsed array:

https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#specifying-extensions

It also states that the extensionsRequired array should list any extensions required to render the glTF.

If this functionality isn’t currently implemented and I haven’t missed anything, would it be possible for the extensionsUsed array to be automatically populated when required, and the extensionsRequired array could be populated by a new method?

Thanks,
Tom

@TPovey2

Hi Tom,

Currently, the Aspose.3D library does not support the automatic population of the extensionsUsed and extensionsRequired arrays in glTF files, which is a key feature outlined in the glTF 2.0 specification. I understand your concern regarding this limitation.

I recommend submitting a feature request to the Aspose team to consider adding this functionality in future updates. In the meantime, you can manually populate these arrays in your glTF files after they are generated. Additionally, it may be helpful to review the Aspose.3D documentation or community forums for any potential workarounds or updates.

If you have any further questions or need assistance with specific code examples, please feel free to ask!

Best regards.

Hi @lex.chou - I’m unsure how to submit a feature request - is it through the forum or via email?

Thanks,
Tom

Hi @TPovey2 ,

You don’t need to add any manual entry when saving to glTF with Aspose.3D. The library automatically detects the features you’re using and writes the correct extension information into the output file.

I’ll open a ticket to investigate why you’re seeing this behavior, and should be fixed in the next version.

You can submit a feature request in the Aspose.3D forum. We’ll add it to our roadmap and track its progress.

Best regards,
Lex Chou.

Great thanks - yes I can see that the extension EXT_structural_metadata has been added along with the relevant property tables, but the “extensionsUsed” array has not been created / populated. I’ll keep testing to make sure it’s not an error on my end.

Thanks,
Tom

Just an update on this - I’ve been testing it out and the EXT_mesh_features is populated in the extensionsUsed array, however EXT_structural_metadata is not added.

Here’s the resulting GLTF which is created from the example code found here Aspose.3D for .NET 25.5 Release Notes

I’m currently adding the EXT_structural_metadata extension to the array after the file has been saved. As can be seen below, the EXT_structural_metadata extension has been used and is correctly set out at the bottom of the file:

{
  "extensionsUsed": [
    "EXT_mesh_features"
  ],
  "accessors": [
    {
      "bufferView": 0,
      "byteOffset": 0,
      "componentType": 5123,
      "count": 12,
      "type": "SCALAR",
      "max": [
        7
      ],
      "min": [
        0
      ]
    },
    {
      "bufferView": 1,
      "byteOffset": 0,
      "componentType": 5126,
      "count": 8,
      "type": "VEC3",
      "max": [
        4,
        2,
        0
      ],
      "min": [
        0,
        0,
        0
      ],
      "name": "POSITION"
    },
    {
      "bufferView": 1,
      "byteOffset": 12,
      "componentType": 5126,
      "count": 8,
      "type": "SCALAR",
      "max": [
        1
      ],
      "min": [
        0
      ],
      "name": "_FEATURE_ID_0"
    }
  ],
  "asset": {
    "generator": "Aspose.3D 25.9.0",
    "version": "2.0"
  },
  "buffers": [
    {
      "uri": "test_1_data.bin",
      "byteLength": 176
    }
  ],
  "bufferViews": [
    {
      "buffer": 0,
      "byteOffset": 0,
      "byteLength": 24,
      "target": 34963
    },
    {
      "buffer": 0,
      "byteOffset": 24,
      "byteLength": 128,
      "byteStride": 16,
      "target": 34962
    },
    {
      "buffer": 0,
      "byteOffset": 152,
      "byteLength": 12
    },
    {
      "buffer": 0,
      "byteOffset": 164,
      "byteLength": 12
    }
  ],
  "meshes": [
    {
      "primitives": [
        {
          "attributes": {
            "POSITION": 1,
            "_FEATURE_ID_0": 2
          },
          "indices": 0,
          "mode": 4,
          "extensions": {
            "EXT_mesh_features": {
              "featureIds": [
                {
                  "featureCount": 2,
                  "attribute": 0,
                  "propertyTable": 0
                }
              ]
            }
          }
        }
      ],
      "name": ""
    }
  ],
  "nodes": [
    {
      "mesh": 0,
      "name": ""
    }
  ],
  "scene": 0,
  "scenes": [
    {
      "nodes": [
        0
      ]
    }
  ],
  "extensions": {
    "EXT_structural_metadata": {
      "schema": {
        "id": "metadata",
        "classes": {
          "test_class": {
            "properties": {
              "enum_value": {
                "name": "enum_value",
                "description": "enum_value",
                "array": true,
                "normalized": false,
                "type": "ENUM",
                "enumType": "test_enum"
              }
            },
            "name": "test_class"
          }
        },
        "enums": {
          "test_enum": {
            "name": "test_enum",
            "values": [
              {
                "value": 0,
                "name": "ENUM_A"
              },
              {
                "value": 1,
                "name": "ENUM_B"
              }
            ]
          }
        }
      },
      "propertyTables": [
        {
          "name": "example",
          "class": "test_class",
          "properties": {
            "enum_value": {
              "arrayOffsets": 2,
              "values": 3
            }
          },
          "count": 2
        }
      ]
    }
  }
}