-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add EXT_primitive_voxels #48
Changes from 7 commits
1cbfb0a
aea0fd2
2ed6724
237186f
d503e84
e51dd28
4c5f021
31fea78
458cc69
682e8ff
0d3670e
58c66f4
ed35109
e03c114
60a28d1
5220357
678c5ed
1387ba3
4484f25
0eefbe8
91fc2f8
dcc826e
0107640
b3a961d
40ebbdb
c805aaf
dc1029a
22e2c71
98f2868
be26d0f
74113f2
c9c6abf
60a4b4f
cd6749e
981c69b
9e8df19
1244f79
2b387c0
6dec236
fe44738
ea998cf
5048335
cfe3cc7
af8ea2d
92688a3
351ef49
519ff87
a877414
574bda2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,88 @@ | ||||||
# EXT_primitive_voxels | ||||||
|
||||||
<p align="center"> | ||||||
<img src="figures/voxel_cube.png"> | ||||||
</p> | ||||||
|
||||||
## Contributors | ||||||
- Daniel Krupka, Cesium | ||||||
- Ian Lilley, Cesium | ||||||
- Sean Lilley, Cesium | ||||||
|
||||||
## Status | ||||||
Draft | ||||||
|
||||||
## Dependencies | ||||||
Written against the glTF 2.0 specification. | ||||||
|
||||||
## Overview | ||||||
|
||||||
This extension allows primitives to use their attribute data to represent volumetric (voxel) data. | ||||||
|
||||||
``` | ||||||
{ | ||||||
"meshes": [ | ||||||
{ | ||||||
"primitives": [ | ||||||
{ | ||||||
"attributes": { | ||||||
"_TEMPERATURE": 1 | ||||||
}, | ||||||
"mode": 2147483648, | ||||||
"extensions": { | ||||||
"EXT_primitive_voxels": { | ||||||
"dimensions": [8, 8, 8], | ||||||
"bounds": { | ||||||
"minimum": [0.25, 0.5, 0.5], | ||||||
"maximum": [0.375, 0.625, 0.625] | ||||||
}, | ||||||
"neighboringEdges": { | ||||||
"beforeCount": [1, 1, 1], | ||||||
"afterCount": [1, 1, 1] | ||||||
} | ||||||
} | ||||||
} | ||||||
} | ||||||
] | ||||||
} | ||||||
] | ||||||
} | ||||||
``` | ||||||
|
||||||
The extension adds three new primitive modes, corresponding to voxel grid geometries: | ||||||
- `0x80000000` (`2147483648`) - A Cartesian box. The grid is a Cartesian grid of equally-sized boxes. | ||||||
- `0x80000001` (`2147483649`) - A cylinder. The grid is a stack of concentric rings, evenly divided around the circumference. | ||||||
- `0x80000002` (`2147483650`) - An ellipsoid. The grid is a set of concentric ellipsoids, divided evenly in latitude and longitude. | ||||||
|
||||||
|Box|Cylinder|Ellipsoid| | ||||||
| ------------- | ------------- | ------------- | | ||||||
|![Rectangular Voxel Grid](figures/box.png)|![Cylindrical Voxel Grid](figures/cylinder.png)|![Ellipsoid Voxel Grid](figures/sphere.png)| | ||||||
|
||||||
These grids all define "unit" objects centered at the origin, contained in the bounding box between `(-1, -1, -1)` and `(1, 1, 1)`. Node transforms | ||||||
should be used to position, orient, and scale the voxel grid as needed. The `POSITION` attribute is _not_ required or used by this extension - all positioning | ||||||
is through node transforms. | ||||||
|
||||||
The `dimensions` property of the extension specifies the voxel grid dimensions: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There should be a short explanation of how these coordinates map to the memory layout There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Totally agree, you've described this to me as a "reinterpret cast", but it would be good to describe this in more detail in the spec. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Diagrams and pictures could be helpful here, like showing how the same voxel grid maps to these different shapes. |
||||||
- x/y/z for boxes | ||||||
- r/z/theta for cylinders | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In glTF, y is up -- is the cylinder z coordinate pointing in the y direction or the z direction? this should be made clear (perhaps with a diagram) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I changed the cylinder coordinate names from 👍 to a diagram. |
||||||
- lon/lat/height for ellipsoids | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed |
||||||
|
||||||
Dimensions must be nonzero. Elements are laid out in memory first-axis-contiguous, e.g. for boxes, `x` data is contiguous (up to stride). | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "first-axis-contiguous" is a term I've never heard before. I find this confusing. I think you mean column major? (albeit that is a confusing term in 3D. here's an example of row major in 3D) basically "x-major" means it's the first index if you access it Also see how NumPy describes its arrays as either row- or column- major (the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps that sentence can be reworded. It's row-major access where x changes the fastest. If this were a C array (row major) it would be accessed like |
||||||
|
||||||
The `bounds` property describes how the voxel is clipped before rendering in voxel space. `bounds.minimum` and `bounds.maximum` specify a "rectangular" region of the voxel in the appropriate | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think there's a better word than |
||||||
coordinate systems: | ||||||
- Boxes: a rectangular region of the voxel, between `(-1, -1, -1)` and `(1, 1, 1)` | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if boxes should omit this property. If we want to keep it around for consistency, there could be a note saying that it's basically pointless and can be handled with node transforms instead. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Starting to change my mind on this. I think |
||||||
- Cylinders: a slice of the cylinder, between `(0, -1, 0)` and `(1, 1, 2*pi)` | ||||||
- Ellipsoids: a surface patch with height, between `(-pi, -pi/2, 0)` and `(pi, pi/2, 1)` | ||||||
|
||||||
The `neighboringEdges` 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. blurring, antialiasing. `neighboringEdges.beforeCount` and `neighboringEdges.afterCount` specify | ||||||
the count for neighbors before and after the grid in each dimension, e.g. a `beforeCount` of 1 and a `afterCount` 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. | ||||||
|
||||||
The neighbor data must be supplied with the rest of the voxel data - this means if `dimensions` is `[d1, d2, d3]`, `beforeCount` is `[b1, b2, b3]`, and `afterCount` is `[a1, a2, a3]`, | ||||||
the attribute must supply `(d1 + a1 + b1)*(d2 + a2 + b2)*(d3 + a3 + b3)` elements. | ||||||
|
||||||
## Optional vs. Required | ||||||
This extension is required, meaning it should be placed in both the `extensionsUsed` list and `extensionsRequired` list. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
{ | ||
"$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 specify voxel grid geomtetry for volumetric data", | ||
"allOf": [ | ||
{ | ||
"$ref": "glTFProperty.schema.json" | ||
} | ||
], | ||
"properties": { | ||
"dimensions": { | ||
"type": "array", | ||
"description": "Dimensions of the voxel grid. x/y/z for a box, r/theta/z for a cylinder, lat/lon/height for an ellipsoid.", | ||
"items": { | ||
"type": "integer", | ||
"minimum": 1 | ||
}, | ||
"minItems": 3, | ||
"maxItems": 3 | ||
}, | ||
"bounds": { | ||
"type": { | ||
"properties": { | ||
"minimum": { | ||
"type": "array", | ||
"items": { | ||
"type": "number" | ||
}, | ||
"minItems": 3, | ||
"maxItems": 3 | ||
}, | ||
"maximum": { | ||
"type": "array", | ||
"items": { | ||
"type": "number" | ||
}, | ||
"minItems": 3, | ||
"maxItems": 3 | ||
} | ||
} | ||
} | ||
}, | ||
"neighboringEdges": { | ||
"type": { | ||
"properties": { | ||
"beforeCount": { | ||
"type": "array", | ||
"description": "Number of neighboring data values before each dimension of the grid.", | ||
"items": { | ||
"type": "integer", | ||
"minimum": 0, | ||
"default": 0 | ||
}, | ||
"minItems": 3, | ||
"maxItems": 3 | ||
}, | ||
"afterCount": { | ||
"type": "array", | ||
"description": "Number of neighboring data values after each dimension of the grid.", | ||
"items": { | ||
"type": "integer", | ||
"minimum": 0, | ||
"default": 0 | ||
}, | ||
"minItems": 3, | ||
"maxItems": 3 | ||
} | ||
} | ||
}, | ||
"description": "The number of rows of neighboring tiles' voxel data." | ||
} | ||
}, | ||
"required": ["dimensions"] | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The spec doesn't say much about the attributes used here. Some questions:
POSITION
,NORMAL
,TEXCOORD_n
, etc.) have well-defined behavior in a voxel context? or are they treated the same as custom attributes like_TEMPERATURE
here?