Closed kring closed 4 months ago
Merging now. Thanks @kring !
The combination of removeUnusedBufferViews
and compactBuffers
will break the alignment requirements in certain cases.
Here is an archive of a glTF and the resulting output:
The glTF has a single buffer, where
Accessor 0 is unused (but it might very well be used - this is just for demonstation). Buffer view 1 has an offset of 3 and a length of 3, and is unused.
So these are the ranges of the 44 bytes that are occupied by the respective buffer views 0, 1, and 2:
1 2 3 4 4
0 8 0 0 0 0 4
--------------------------------------------
000
111
222222222222222222222222222222222222
This is valid.
Running removeUnusedBufferViews/compactBuffers
on this will detect that the range 3...8 is unused, and remove it, resulting in
1 2 3 4 4
0 8 0 0 0 0 4
--------------------------------------------
000
1111111111111111111111111111111111111
where the buffer view 1 has an offset of 3, but the accessor that refers to it requires an alignment of 4.
Thanks @javagl. And I guess the problem is that we can't tell what alignment is required by only looking at the bufferView? We have to also look at the accessors (or whatever else uses the bufferView, e.g., metadata).
If I have that right, I think we can still deal with it relatively easily just be being conservative about it. If a bufferView is originally aligned to 2 or 4 bytes, whether it needs to be or not, we make sure we preserve that alignment by deleting slightly fewer bytes than we otherwise would. Are there any bufferViews that need to be aligned to 8 bytes?
Thanks @javagl. And I guess the problem is that we can't tell what alignment is required by only looking at the bufferView? We have to also look at the accessors (or whatever else uses the bufferView, e.g., metadata).
If I have that right, I think we can still deal with it relatively easily just be being conservative about it. If a bufferView is originally aligned to 2 or 4 bytes, whether it needs to be or not, we make sure we preserve that alignment by deleting slightly fewer bytes than we otherwise would. Are there any bufferViews that need to be aligned to 8 bytes?
You are safe if new buffer view offset = old buffer view offset mod 4. I think it's true that the alignment of a buffer view determines the maximum alignment of possible accessors; the accessor offset must be "a multiple of the size of the accessor’s component type," so the accessor's offset can't "realign" a misaligned buffer view.
The maximum component size in glTF 2.0 -- and therefore the maximum alignment -- is 4 bytes. I don't know if any extension specifies an 8 byte component type.
This builds on #853 so merge that first.
forEachRootNodeInScene
toModel
. This is useful to enumerate the root nodes associated with a scene (whether a particular one or the default), such as when you want to add a transformation to each.Model::merge
now returns anErrorList
, so it can report warnings and errors during the merge process.getNodeTransform
andsetNodeTransform
toGltfUtilities
. These make it easy to get/set the local transformation of theNode
as aglm::dmat4x4
.GltfUtilities
to remove unused elements from a glTF. Detecting unused elements in glTF requires complete knowledge of all extensions used, as well as a perfectly accurate accounting all the references. Ultimately this information should be expressed in the glTF schema itself, but it's hard coded here for the time being.compactBuffers
toGltfUtilities
. It removes any byte ranges from a Buffer that are not referenced by any BufferView, and updates all other BufferViews accordingly.postprocessGltf
toGltfReader
. This allows all of the post-processing that is optionally done after loading a glTF - such as decoding Draco or images - to be done later, after the main part of the load is complete.Model::merge
.ReferenceCounted.h
.