diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 43e6e0193b..fe1eefebf2 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -23,7 +23,7 @@ jobs: steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 # Build spec targets - name: spec-generate @@ -32,7 +32,7 @@ jobs: make Specification.html Specification.pdf - name: Archive generated files - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: spec-outputs path: | diff --git a/extensions/2.0/Vendor/EXT_implicit_cylinder_region/README.md b/extensions/2.0/Vendor/EXT_implicit_cylinder_region/README.md new file mode 100644 index 0000000000..b7a9b39e43 --- /dev/null +++ b/extensions/2.0/Vendor/EXT_implicit_cylinder_region/README.md @@ -0,0 +1,110 @@ +# EXT_implicit_cylinder_region + +## Contributors + +- Janine Liu, Cesium +- Sean Lilley, Cesium + +## Status + +Draft + +## Dependencies + +Written against the glTF 2.0 specification. Depends on the [`KHR_implicit_shapes`](https://github.com/eoineoineoin/glTF/tree/refs/heads/collisionShapeMerge/extensions/2.0/Khronos/KHR_implicit_shapes) extension. + +## Overview + +This extension defines a cylinder-conforming region as an additional shape type for the `KHR_implicit_shapes` extension. These regions are useful for visualizing real-world data that has been captured by cylindrical sensors. + +`EXT_implicit_cylinder_region` extends the `shape` object in `KHR_implicit_shapes`. The `shape.type` should be set to `"cylinder region"`. The properties define a region following the surface of a cylinder between two different radius values. + +The cylinder does not need to be completely represented by the volume—for instance, the region may be hollow inside like a tube. However, an inner radius of `0` results in a completely solid cylinder. + +### Details + +The cylinder is centered at the origin, where the radius is measured along the `x` and `z` axes. The `height` of the cylinder is aligned with the `y` axis. + + + + + + + + + +
+ Example +
+ +```json +"extensions": [ + { + "KHR_implicit_shapes": { + "shapes": [ + { + "type": "cylinder region", + "extensions": { + "EXT_implicit_cylinder_region": { + "minRadius": 0.5, + "maxRadius": 1, + "height": 2 + } + } + } + ] + } + } +] +``` + + + +
+ +A cylinder region may also be confined to a certain angular range. The `minAngle` and `maxAngle` properties define the angles at which the region starts and stops on the cylinder. + +Angles are given in radians within the range `[-pi, pi]` and open clockwise around the cylinder (see figure below). + +![](figures/cylinder-angle.png) + + + + + + + + + +
+ Example +
+ +```json +"extensions": [ + { + "KHR_implicit_shapes": { + "shapes": [ + { + "type": "cylinder region", + "extensions": { + "EXT_implicit_cylinder_region": { + "minRadius": 0.5, + "maxRadius": 1, + "height": 2, + "minAngle": 0, + "maxAngle": 3.1415 + } + } + } + ] + } + } +] +``` + + +
+ +## Optional vs. Required +This extension is required, meaning it should be placed in both the `extensionsUsed` list and `extensionsRequired` list. diff --git a/extensions/2.0/Vendor/EXT_implicit_cylinder_region/figures/cylinder-angle.png b/extensions/2.0/Vendor/EXT_implicit_cylinder_region/figures/cylinder-angle.png new file mode 100644 index 0000000000..839db634dd Binary files /dev/null and b/extensions/2.0/Vendor/EXT_implicit_cylinder_region/figures/cylinder-angle.png differ diff --git a/extensions/2.0/Vendor/EXT_implicit_cylinder_region/figures/half-cylinder.png b/extensions/2.0/Vendor/EXT_implicit_cylinder_region/figures/half-cylinder.png new file mode 100644 index 0000000000..3d2b728701 Binary files /dev/null and b/extensions/2.0/Vendor/EXT_implicit_cylinder_region/figures/half-cylinder.png differ diff --git a/extensions/2.0/Vendor/EXT_implicit_cylinder_region/figures/hollow-cylinder.png b/extensions/2.0/Vendor/EXT_implicit_cylinder_region/figures/hollow-cylinder.png new file mode 100644 index 0000000000..b47ee174ee Binary files /dev/null and b/extensions/2.0/Vendor/EXT_implicit_cylinder_region/figures/hollow-cylinder.png differ diff --git a/extensions/2.0/Vendor/EXT_implicit_cylinder_region/schema/glTF.KHR_implicit_shapes.shape.EXT_implicit_cylinder_region.schema.json b/extensions/2.0/Vendor/EXT_implicit_cylinder_region/schema/glTF.KHR_implicit_shapes.shape.EXT_implicit_cylinder_region.schema.json new file mode 100644 index 0000000000..3dd6e0d3d3 --- /dev/null +++ b/extensions/2.0/Vendor/EXT_implicit_cylinder_region/schema/glTF.KHR_implicit_shapes.shape.EXT_implicit_cylinder_region.schema.json @@ -0,0 +1,48 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "glTF.KHR_implicit_shapes.shape.EXT_implicit_cylinder_region.schema.json", + "title": "EXT_implicit_cylinder_region extension on KHR_implicit_shapes.shape", + "type": "object", + "description": "Extension of `KHR_implicit_shapes.shape` to represent an implicit cylinder region in a glTF model.", + "allOf": [ + { + "$ref": "glTFProperty.schema.json" + } + ], + "properties": { + "minRadius": { + "type": "number", + "description": "The inner radius of the cylinder region along the X and Z axes, in meters.", + "minimum": 0 + }, + "maxRadius": { + "type": "number", + "description": "The outer radius of the cylinder region along the X and Z axes, in meters.", + "minimum": 0 + }, + "height": { + "type": "number", + "description": "The height of the cylinder in meters along the Y-axis, in meters.", + "minimum": 0 + }, + "minAngle": { + "type": "number", + "description": "The minimum angle of the cylinder region in radians. In other words, this is the angle where the cylinder region starts. Must be in the range [-pi, pi].", + "minimum": -3.14159265359, + "maximum": 3.14159265359, + "default": -3.14159265359 + }, + "maxAngle": { + "type": "number", + "description": "The maximum angle of the cylinder region in radians. In other words, this is the angle where the cylinder region ends. Must be in the range [-pi, pi].", + "minimum": -3.14159265359, + "maximum": 3.14159265359, + "default": 3.14159265359 + } + }, + "required": [ + "minRadius", + "maxRadius", + "height" + ] +} \ No newline at end of file diff --git a/extensions/2.0/Vendor/EXT_implicit_ellipsoid_region/README.md b/extensions/2.0/Vendor/EXT_implicit_ellipsoid_region/README.md new file mode 100644 index 0000000000..5024775f63 --- /dev/null +++ b/extensions/2.0/Vendor/EXT_implicit_ellipsoid_region/README.md @@ -0,0 +1,91 @@ +# EXT_implicit_ellipsoid_region + +## Contributors + +- Janine Liu, Cesium +- Sean Lilley, Cesium + +## Status + +Draft + +## Dependencies + +Written against the glTF 2.0 specification. Depends on the [`KHR_implicit_shapes`](https://github.com/eoineoineoin/glTF/tree/refs/heads/collisionShapeMerge/extensions/2.0/Khronos/KHR_implicit_shapes) extension. + +## Overview + +This extension defines an ellipsoid-conforming region as an additional shape type for the `KHR_implicit_shapes` extension. These regions are commonly used in geospatial applications to describe volumes that conform to the curvature of the Earth, or other bodies. + +`EXT_implicit_ellipsoid_region` extends the `shape` object in `KHR_implicit_shapes`. The `shape.type` should be set to `"ellipsoid region"`. The properties define the region following the surface of the ellipsoid between two different height values. + +The volume does not necessarily contain the full ellipsoid—and for many geospatial use cases, it will not. Rather, the ellipsoid is used as a reference from which the actual region is extruded. However, a region may be extend beneath the surface of the ellipsoid. Given the right height values, the region could contain the entire ellipsoid if desired. + +### Details + +The reference ellipsoid is centered at the origin. The `semiMajorAxisRadius` indicates the radius of the ellipsoid in meters along the `x` and `z` axes. The `semiMinorAxisRadius` indicates the radius of the ellipsoid in meters along the `y` axis. + +> The `x` and `z` radii are made equal to simplify the math required to render implicit regions along the ellipsoid. + +The `minHeight` and `maxHeight` properties indicate the heights of the region from the ellipsoid's surface in meters. A height of `0` sits right at the surface. Negative heights are also valid—they simply extend underneath the ellipsoid's surface. + +This example corresponds to the image below it: + +```json +"extensions": [ + { + "KHR_implicit_shapes": { + "shapes": [ + { + "type": "ellipsoid region", + "extensions": { + "EXT_implicit_ellipsoid_region": { + "semiMajorAxisRadius": 3.5, + "semiMinorAxisRadius": 2, + "minHeight": 0, + "maxHeight": 0.5 + } + } + } + ] + } + } +] +``` + +![](figures/hollow-ellipsoid.png) + +An ellipsoid region may also be confined to a specific latitude and/or longitude range. The `minLatitude` and `maxLatitude` properties represent the latitude values at which the region starts and stops, defined in the range `[-pi/2, pi/2]`. Similarly, the `minLongitude` and `maxLongitude` properties represent the longitude bounds within the range `[-pi, pi]`. + +```json +"extensions": [ + { + "KHR_implicit_shapes": { + "shapes": [ + { + "type": "ellipsoid region", + "extensions": { + "EXT_implicit_ellipsoid_region": { + "semiMajorAxisRadius": 3.5, + "semiMinorAxisRadius": 2, + "minHeight": 0, + "maxHeight": 0.5, + "minLongitude": 0, + "maxLongitude": 1.57079632679, + "minLatitude": -0.78539816339, + "maxLatitude": 0.78539816339, + } + } + } + ] + } + } +] +``` + +![](figures/half-ellipsoid.png) + +It is valid for the `maxLongitude` property to be less than `minLongitude`. This would define a region that crosses over the line at `-pi` or `pi`, equivalent to the International Date Line on Earth. + +## Optional vs. Required +This extension is required, meaning it should be placed in both the `extensionsUsed` list and `extensionsRequired` list. diff --git a/extensions/2.0/Vendor/EXT_implicit_ellipsoid_region/figures/half-ellipsoid.png b/extensions/2.0/Vendor/EXT_implicit_ellipsoid_region/figures/half-ellipsoid.png new file mode 100644 index 0000000000..11f97c60be Binary files /dev/null and b/extensions/2.0/Vendor/EXT_implicit_ellipsoid_region/figures/half-ellipsoid.png differ diff --git a/extensions/2.0/Vendor/EXT_implicit_ellipsoid_region/figures/hollow-ellipsoid.png b/extensions/2.0/Vendor/EXT_implicit_ellipsoid_region/figures/hollow-ellipsoid.png new file mode 100644 index 0000000000..84abb5d206 Binary files /dev/null and b/extensions/2.0/Vendor/EXT_implicit_ellipsoid_region/figures/hollow-ellipsoid.png differ diff --git a/extensions/2.0/Vendor/EXT_implicit_ellipsoid_region/schema/glTF.KHR_implicit_shapes.shape.EXT_implicit_ellipsoid_region.schema.json b/extensions/2.0/Vendor/EXT_implicit_ellipsoid_region/schema/glTF.KHR_implicit_shapes.shape.EXT_implicit_ellipsoid_region.schema.json new file mode 100644 index 0000000000..70f023ccd5 --- /dev/null +++ b/extensions/2.0/Vendor/EXT_implicit_ellipsoid_region/schema/glTF.KHR_implicit_shapes.shape.EXT_implicit_ellipsoid_region.schema.json @@ -0,0 +1,66 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "glTF.KHR_implicit_shapes.shape.EXT_implicit_ellipsoid_region.schema.json", + "title": "EXT_implicit_ellipsoid_region extension on KHR_implicit_shapes.shape", + "type": "object", + "description": "Extension of `KHR_implicit_shapes.shape` to represent an implicit ellipsoid region in a glTF model.", + "allOf": [ + { + "$ref": "glTFProperty.schema.json" + } + ], + "properties": { + "semiMajorAxisRadius": { + "type": "number", + "description": "The radius along the semi-major axis of the reference ellipsoid in meters. Corresponds to the radii along the X and Z axes.", + "minimum": 0 + }, + "semiMinorAxisRadius": { + "type": "number", + "description": "The radius along the semi-minor axis of the reference ellipsoid in meters. Corresponds to the radius along the Y-axis.", + "minimum": 0 + }, + "minHeight": { + "type": "number", + "description": "The minimum height of the region relative to the ellipsoid's surface, in meters. May be negative." + }, + "maxHeight": { + "type": "number", + "description": "The maximum height of the region relative to the ellipsoid's surface, in meters. May be negative." + }, + "minLatitude": { + "type": "number", + "description": "The minimum latitude (a.k.a. polar angle) of the region, in radians. Must be in the range [-pi/2, pi/2].", + "minimum": -1.57079632679, + "maximum": 1.57079632679, + "default": -1.57079632679 + }, + "maxLatitude": { + "type": "number", + "description": "The maximum latitude (a.k.a. polar angle) of the region, in radians. Must be in the range [-pi/2, pi/2].", + "minimum": -1.57079632679, + "maximum": 1.57079632679, + "default": 1.57079632679 + }, + "minLongitude": { + "type": "number", + "description": "The minimum longitude (a.k.a. azimuthal angle) of the region, in radians. Must be in the range [-pi, pi].", + "minimum": -3.14159265359, + "maximum": 3.14159265359, + "default": -3.14159265359 + }, + "maxLongitude": { + "type": "number", + "description": "The maximum longitude (a.k.a. azimuthal angle) of the region, in radians. Must be in the range [-pi, pi].", + "minimum": -3.14159265359, + "maximum": 3.14159265359, + "default": 3.14159265359 + } + }, + "required": [ + "semiMajorAxisRadius", + "semiMinorAxisRadius", + "minHeight", + "maxHeight" + ] +} \ No newline at end of file diff --git a/extensions/2.0/Vendor/EXT_primitive_voxels/README.md b/extensions/2.0/Vendor/EXT_primitive_voxels/README.md new file mode 100644 index 0000000000..a1636dd9c0 --- /dev/null +++ b/extensions/2.0/Vendor/EXT_primitive_voxels/README.md @@ -0,0 +1,257 @@ +# EXT_primitive_voxels + +

+ +

+ +## Contributors + +- Janine Liu, Cesium +- Daniel Krupka, Cesium +- Ian Lilley, Cesium +- Sean Lilley, Cesium +- Jeshurun Hembd, Cesium + +## Status + +Draft + +## Dependencies + +Written against the glTF 2.0 specification. Depends on the [`KHR_implicit_shapes`](https://github.com/eoineoineoin/glTF/tree/refs/heads/collisionShapeMerge/extensions/2.0/Khronos/KHR_implicit_shapes) extension. + +## Overview + +This extension allows mesh primitives to represent volumetric (voxel) data via custom attributes. Primitives that use this extension must set their `mode` to the constant `0x7FFFFFFF` (`2147483647`) used to indicate voxels. + +Typical mesh primitives make use of the `POSITION` attribute to store positional mesh data. However, `POSITION` is neither required nor used by `EXT_primitive_voxels`. Instead, this extension relies on the `KHR_implicit_shapes` extension to describe the shape of the voxel grid. + +```json +{ + "extensions": { + "KHR_implicit_shapes": { + "shapes": [ + { + "type": "box", + "box": { + "size": [2, 2, 2] + } + } + ] + } + }, + "meshes": [ + { + "primitives": [ + { + "attributes": { + "_TEMPERATURE": 0 + }, + "mode": 2147483647, + "extensions": { + "EXT_primitive_voxels": { + "shape": 0, + "dimensions": [8, 8, 8] + } + } + } + ] + } + ] +} +``` + +Though voxels are commonly associated with cubic geometry on a box-based grid, this extension also allows voxels to be based on other shapes, including cylinder-based regions specified by [`EXT_implicit_cylinder_region`](../EXT_implicit_cylinder_region/) and ellipsoid-based regions specified by [`EXT_implicit_ellipsoid_region`](../EXT_implicit_ellipsoid_region/). The supported shapes are visualized below. + +|Box|Cylinder|Ellipsoid| +| ------------- | ------------- | ------------- | +|![Box Voxel Grid](figures/box.png)|![Cylindrical Voxel Grid](figures/cylinder.png)|![Ellipsoid Voxel Grid](figures/sphere.png)| + +Voxels exist inside a bounding volume that conforms to the shape of the grid. The `dimensions` property refers to the number of subdivisions _within_ this bounding volume. Each value of `dimensions` must be a positive integer. + +The relationship between `dimensions` and the grid geometry is explained below. + +### Box Grid + +A **box** grid is a Cartesian grid defined by `x`, `y`, and `z` axes with equally-sized boxes. The `dimensions` correspond to the subdivisions of the box along the `x`, `y`, and `z` axes respectively. + +Elements are laid out in memory where the `x` data is contiguous in strides along the `y` axis, and each group of `y` strides represents a `z` slice. + +![Uniform box grid](figures/uniform-box.png) +

A uniform box grid that is subdivided into two cells along each axis.

+ +![Non-uniform box grid](figures/non-uniform-box.png) +

A box grid that is non-uniformly scaled and also non-uniformly subdivided.

+ +### Cylinder Region Grid + +A **cylinder** region grid is subdivided along the radius, height, and angle ranges of the region. The `dimensions` correspond to the subdivisions of those ranges, respectively. + +![Cylinder subdivisions](figures/cylinder-subdivisions.png) + +The cylinder is aligned with the `y`-axis in the primitive's local space. Its height is subdivided along that local `y`-axis from bottom to top. Subdivisions along the radius are concentric, centered around the `y`-axis and extending outwards. Finally, the angular bounds subdivided clockwise around the circumference of the cylinder. + +Elements are laid out in memory where the radial data is contiguous in strides along the cylinder's height, as if stacked in a column. Each group of height strides represents an angular slice on the cylinder. + +![Whole cylinder grid](figures/whole-cylinder.png) +

A cylinder that is subdivided into two cells along each axis.

+ +![Non-uniform cylinder grid](figures/non-uniform-cylinder.png) +

A smaller cylinder region with radial and angular bounds that is non-uniformly subdivided.

+ +### Ellipsoid Region Grid + +An **ellipsoid** region grid is subdivided along the longitude, latitude, and height ranges of the region. The `dimensions` correspond to the subdivisions of those ranges, respectively. + +Elements are laid out in memory where the longitude data is contiguous in strides along the region's latitude. Each group of latitude strides represents a height slice on the region. + +![Region grid](figures/part-ellipsoid.png) +

An ellipsoid region that is subdivided into two cells along each axis.

+ +![Non-uniform region grid](figures/non-uniform-part-ellipsoid.png) + +

An ellipsoid region that is non-uniformly subdivided.

+ +![Whole ellipsoid grid](figures/whole-ellipsoid.png) +

A hollow ellipsoid region that covers the entire ellipsoid, subdivided into two cells along each axis.

+ +### Padding + +The `padding` property specifies how many rows of attribute data in each dimension come from neighboring grids. This is useful in situations where the primitive represents a single tile in a larger grid, and data from neighboring tiles is needed for non-local effects e.g. trilinear interpolation, blurring, or antialiasing. + +`padding.before` and `padding.after` specify the number of rows before and after the grid in each dimension, e.g. a `padding.before` of 1 and a `padding.after` of 2 in the `y` dimension mean that each series of values in a given `y`-slice is preceded by one value and followed by two. + +Padding data must be included with the rest of the voxel data. In other words, given `dimensions` of `[d1, d2, d3]`, `padding.before` of `[b1, b2, b3]`, and `padding.after` of `[a1, a2, a3]`, the voxel primitive's attributes must contain `(d1 + a1 + b1)*(d2 + a2 + b2)*(d3 + a3 + b3)` elements. In the following example, the attributes on this voxel primitive must supply `(8 + 1 + 1)*(8 + 1 + 1)*(8 + 1 + 1) = 100` elements. + +```json +"extensions": { + "EXT_primitive_voxels": { + "shape": 0, + "dimensions": [8, 8, 8], + "padding": { + "before": [1, 1, 1], + "after": [1, 1, 1] + } + } +} +``` + +### No Data Values + +Voxel primitives may optionally specify a "No Data" value (or "sentinel value") for its attributes to indicate where property values do not exist. This "No Data" value may be provided for any type of attribute, but must be defined according to the type of its `accessor`. For `normalized` accessors, the `noData` value should be specified as the raw data value *before* normalization. + +The "No Data" values for attributes must be defined in the `noData` object. Any key in `noData` must match an existing key in the primitive's `attributes` object. However, not all `attributes` are required to provide a `noData` value. + +For instance, if a voxel primitive references the following accessors... + +```jsonc +"accessors": [ + { + "type": "SCALAR", + "componentType": 5122, // SHORT + "normalized": true + }, + { + "type": "VEC3", + "componentType": 5126, // FLOAT + }, + // .... +] +``` + +...then it may define `noData` values for its corresponding attributes like so: + +```json +"meshes": [ + { + "primitives": [ + { + "attributes": { + "_TEMPERATURE": 0, + "_DIRECTION": 1, + "_DATA_CONFIDENCE": 2 + }, + "mode": 2147483647, + "extensions": { + "EXT_primitive_voxels": { + "shape": 0, + "dimensions": [8, 8, 8], + "noData": { + "_TEMPERATURE": [-32768], + "_DIRECTION": [-999.99, -999.99, -999.99] + } + } + } + } + ] + } +] +``` + +Note that `_DATA_CONFIDENCE` intentionally does not specify a `noData` value. The attribute is expected to contain a valid value for every voxel cell. + +### Metadata + +This extension may be paired with the `EXT_structural_metadata` extension to convey more semantic information about the voxel attributes. + +```json +{ + "extensions": { + "EXT_structural_metadata": { + "schema": { + "classes": { + "voxels": { + "properties": { + "temperature": { + "type": "SCALAR", + "componentType": "UINT32", + "normalized": true, + "offset": 32.0, + "scale": 1.8 + } + } + } + } + }, + "propertyAttributes": [ + { + "class": "voxels", + "properties": { + "temperature":{ + "attribute": "_TEMPERATURE" + } + } + } + ] + } + }, + "meshes": [ + { + "primitives": [ + { + "attributes": { + "_TEMPERATURE": 0 + }, + "extensions": { + "EXT_primitive_voxels": { + "dimensions": [8, 8, 8], + "padding": { + "before": [1, 1, 1], + "after": [1, 1, 1] + } + }, + "EXT_structural_metadata": { + "propertyAttributes": [0] + } + } + } + ] + } + ] +} +``` + +`EXT_structural_metadata` may also specify a `noData` value for a property attribute property. If `EXT_primitive_voxels` contains an entry in `noData` for the same attribute, the values **SHOULD** match betwen the two extensions. + +## Optional vs. Required +This extension is required, meaning it should be placed in both the `extensionsUsed` list and `extensionsRequired` list. diff --git a/extensions/2.0/Vendor/EXT_primitive_voxels/figures/box.png b/extensions/2.0/Vendor/EXT_primitive_voxels/figures/box.png new file mode 100644 index 0000000000..3b642344f8 Binary files /dev/null and b/extensions/2.0/Vendor/EXT_primitive_voxels/figures/box.png differ diff --git a/extensions/2.0/Vendor/EXT_primitive_voxels/figures/cylinder-subdivisions.png b/extensions/2.0/Vendor/EXT_primitive_voxels/figures/cylinder-subdivisions.png new file mode 100644 index 0000000000..37ca35e6e7 Binary files /dev/null and b/extensions/2.0/Vendor/EXT_primitive_voxels/figures/cylinder-subdivisions.png differ diff --git a/extensions/2.0/Vendor/EXT_primitive_voxels/figures/cylinder.png b/extensions/2.0/Vendor/EXT_primitive_voxels/figures/cylinder.png new file mode 100644 index 0000000000..77ba71b29c Binary files /dev/null and b/extensions/2.0/Vendor/EXT_primitive_voxels/figures/cylinder.png differ diff --git a/extensions/2.0/Vendor/EXT_primitive_voxels/figures/non-uniform-box.png b/extensions/2.0/Vendor/EXT_primitive_voxels/figures/non-uniform-box.png new file mode 100644 index 0000000000..2cf8a6e153 Binary files /dev/null and b/extensions/2.0/Vendor/EXT_primitive_voxels/figures/non-uniform-box.png differ diff --git a/extensions/2.0/Vendor/EXT_primitive_voxels/figures/non-uniform-cylinder.png b/extensions/2.0/Vendor/EXT_primitive_voxels/figures/non-uniform-cylinder.png new file mode 100644 index 0000000000..2b54b372fe Binary files /dev/null and b/extensions/2.0/Vendor/EXT_primitive_voxels/figures/non-uniform-cylinder.png differ diff --git a/extensions/2.0/Vendor/EXT_primitive_voxels/figures/non-uniform-part-ellipsoid.png b/extensions/2.0/Vendor/EXT_primitive_voxels/figures/non-uniform-part-ellipsoid.png new file mode 100644 index 0000000000..7b24117e93 Binary files /dev/null and b/extensions/2.0/Vendor/EXT_primitive_voxels/figures/non-uniform-part-ellipsoid.png differ diff --git a/extensions/2.0/Vendor/EXT_primitive_voxels/figures/part-ellipsoid.png b/extensions/2.0/Vendor/EXT_primitive_voxels/figures/part-ellipsoid.png new file mode 100644 index 0000000000..3806e2325a Binary files /dev/null and b/extensions/2.0/Vendor/EXT_primitive_voxels/figures/part-ellipsoid.png differ diff --git a/extensions/2.0/Vendor/EXT_primitive_voxels/figures/sphere.png b/extensions/2.0/Vendor/EXT_primitive_voxels/figures/sphere.png new file mode 100644 index 0000000000..2d35269fb7 Binary files /dev/null and b/extensions/2.0/Vendor/EXT_primitive_voxels/figures/sphere.png differ diff --git a/extensions/2.0/Vendor/EXT_primitive_voxels/figures/uniform-box.png b/extensions/2.0/Vendor/EXT_primitive_voxels/figures/uniform-box.png new file mode 100644 index 0000000000..fa761d479d Binary files /dev/null and b/extensions/2.0/Vendor/EXT_primitive_voxels/figures/uniform-box.png differ diff --git a/extensions/2.0/Vendor/EXT_primitive_voxels/figures/voxel_cube.png b/extensions/2.0/Vendor/EXT_primitive_voxels/figures/voxel_cube.png new file mode 100644 index 0000000000..29be4db915 Binary files /dev/null and b/extensions/2.0/Vendor/EXT_primitive_voxels/figures/voxel_cube.png differ diff --git a/extensions/2.0/Vendor/EXT_primitive_voxels/figures/whole-cylinder.png b/extensions/2.0/Vendor/EXT_primitive_voxels/figures/whole-cylinder.png new file mode 100644 index 0000000000..887d20b992 Binary files /dev/null and b/extensions/2.0/Vendor/EXT_primitive_voxels/figures/whole-cylinder.png differ diff --git a/extensions/2.0/Vendor/EXT_primitive_voxels/figures/whole-ellipsoid.png b/extensions/2.0/Vendor/EXT_primitive_voxels/figures/whole-ellipsoid.png new file mode 100644 index 0000000000..cc70e38054 Binary files /dev/null and b/extensions/2.0/Vendor/EXT_primitive_voxels/figures/whole-ellipsoid.png differ diff --git a/extensions/2.0/Vendor/EXT_primitive_voxels/schema/mesh.primitive.EXT_primitive_voxels.schema.json b/extensions/2.0/Vendor/EXT_primitive_voxels/schema/mesh.primitive.EXT_primitive_voxels.schema.json new file mode 100644 index 0000000000..6198a5684c --- /dev/null +++ b/extensions/2.0/Vendor/EXT_primitive_voxels/schema/mesh.primitive.EXT_primitive_voxels.schema.json @@ -0,0 +1,54 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "mesh.primitive.EXT_primitive_voxels.schema.json", + "title": "EXT_primitive_voxels glTF Mesh Primitive extension", + "type": "object", + "description": "`EXT_primitive_voxels` extension for a primitive in a glTF model to indicate voxel-based volumetric data", + "allOf": [ + { + "$ref": "glTFProperty.schema.json" + } + ], + "properties": { + "shape": { + "allOf": [ + { + "$ref": "glTFid.schema.json" + } + ], + "description": "The index of the shape in `KHR_implicit_shapes` that the voxel grid adheres to." + }, + "dimensions": { + "type": "array", + "description": "Dimensions of the voxel grid. The values are interpreted with respect to the shape indicated by `KHR_implicit_shapes`.", + "items": { + "type": "integer", + "minimum": 1 + }, + "minItems": 3, + "maxItems": 3 + }, + "padding": { + "description": "The optional padding of the voxels.", + "$ref": "padding.schema.json" + }, + "noData": { + "description": "A plain JSON object, where each key corresponds to an existing semantic in the primitive's `attributes`, and each value is the attribute's `noData` value. A `noData` value represents missing data — also known as a sentinel value — wherever it appears.", + "type": "object", + "minProperties": 1, + "additionalProperties": { + "type": "array", + "description": "The `noData` value for the corresponding attribute. Array elements **MUST** follow the accessor's `componentType`, and its length must align with the accessor's `type`.", + "items": { + "type": "number" + }, + "minItems": 1, + "maxItems": 16 + } + } + }, + "required": [ + "shape", + "dimensions" + ] +} \ No newline at end of file diff --git a/extensions/2.0/Vendor/EXT_primitive_voxels/schema/padding.schema.json b/extensions/2.0/Vendor/EXT_primitive_voxels/schema/padding.schema.json new file mode 100644 index 0000000000..70b59e5d0b --- /dev/null +++ b/extensions/2.0/Vendor/EXT_primitive_voxels/schema/padding.schema.json @@ -0,0 +1,36 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "padding.schema.json", + "title": "Padding", + "type": "object", + "description": "The padding around a voxel grid. Specifies how many rows of attribute data come from neighboring grids in each dimension.", + "allOf": [ + { + "$ref": "glTFProperty.schema.json" + } + ], + "properties": { + "before": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "minItems": 3, + "maxItems": 3 + }, + "after": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "minItems": 3, + "maxItems": 3 + } + }, + "required": [ + "before", + "after" + ] +} \ No newline at end of file diff --git a/extensions/README.md b/extensions/README.md index 29e1c8e5b2..228c4b7eec 100644 --- a/extensions/README.md +++ b/extensions/README.md @@ -37,6 +37,7 @@ When an extension is implemented by more than one vendor, its name can use the r * [EXT_lights_image_based](2.0/Vendor/EXT_lights_image_based/README.md) * [EXT_mesh_gpu_instancing](2.0/Vendor/EXT_mesh_gpu_instancing/README.md) * [EXT_meshopt_compression](2.0/Vendor/EXT_meshopt_compression/README.md) +* [EXT_primitive_voxels](2.0/Vendor/EXT_primitive_voxels/README.md) * [EXT_texture_webp](2.0/Vendor/EXT_texture_webp/README.md) ### Vendor Extensions for glTF 2.0