Skip to content

GLTF: Move accessor decoding functions to GLTFAccessor#109103

Merged
Repiteo merged 1 commit into
godotengine:masterfrom
aaronfranke:gltf-accessor-decode
Nov 14, 2025
Merged

GLTF: Move accessor decoding functions to GLTFAccessor#109103
Repiteo merged 1 commit into
godotengine:masterfrom
aaronfranke:gltf-accessor-decode

Conversation

@aaronfranke
Copy link
Copy Markdown
Member

@aaronfranke aaronfranke commented Jul 30, 2025

Draft because this depends on #108853.

This PR moves the logic of the accessor decoding functions currently found in GLTFDocument into the GLTFAccessor class. The goal here is to allow for these functions to be used outside of GLTFDocument, such as by extensions, so that extensions can read and write accessor data in a type-safe way.

This is a prerequisite PR to allow for MultiMeshInstance3D import via EXT_mesh_gpu_instancing as seen in PR #107866.

Now, I said "move", but this PR is far from a trivial move. This is a refactor where I combed over the code multiple times to ensure that we actually have a good API free from bugs. Of course, it's possible that I've missed something, so this should be ideally be tested with importing many models before merging.

Here's a list of changes:

  • Accessor decoding logic is now in GLTFAccessor instead of GLTFDocument. GLTFDocument has ~600 fewer lines of code in it, GLTFAccessor gains ~600 lines. Unlike the encode functions (see GLTF: Move accessor encoding functions to GLTFAccessor #108853), the existing decode logic wasn't so bad with code duplication, most of the logic was contained in just two functions.
  • GLTFDocument retains wrapper functions to check if the accessor index is valid, get the accessor, call the GLTFAccessor functions, since the GLTFAccessor functions are instance methods. These wrappers retain the ability to optionally read indexed data as non-indexed data (used by meshes).
  • GLTFDocument::_decode_buffer_view (really accessor logic) replaced with GLTFAccessor::_decode_raw_numbers
  • GLTFDocument::_decode_accessor replaced with GLTFAccessor::_decode_as_numbers
  • Both of those 2 functions are generic to allow for directly decoding numbers of the requested size, instead of always double. This fixes the ability to use 64-bit integer accessor types in extensions, and is potentially faster because it doesn't need to convert to a different size afterwards (probably the same speed though).
  • 16-bit half-precision floats are now supported.
  • Decoding sparse indices now has its own dedicated simpler function.
  • This line stride += 4 - (stride % 4); //according to spec must be multiple of 4 was bogus in the decoding logic, for the same reasons as it was in the encoding logic. Yes, the spec says it must be a multiple of 4... but if the files has the wrong stride, we can't just pretend it has a different one. Instead of "correcting", we need to error if this happens. With this PR, such invalid cases will print "glTF import: The declared buffer view byte stride " + itos(declared_byte_stride) + " was not a multiple of 4 as required by glTF.". Removing this also means we can drop the p_for_vertex parameter.

I tested this PR on real 3D models and they work correctly, and also stress-tested it on these test files which are specifically designed to contain all the edge cases of glTF and it works, but more testing is appreciated.

@fire
Copy link
Copy Markdown
Member

fire commented Nov 12, 2025

I think we should merge this for 4.6, but what is the correct order of operations?

@aaronfranke
Copy link
Copy Markdown
Member Author

@fire On every one of my draft PRs, the very top of the description has links to all the dependency PRs.

@fire
Copy link
Copy Markdown
Member

fire commented Nov 12, 2025

It's blocked on #108853

@aaronfranke aaronfranke marked this pull request as ready for review November 14, 2025 06:01
@aaronfranke aaronfranke requested a review from a team as a code owner November 14, 2025 06:01
@aaronfranke aaronfranke moved this to Ready for review in Asset Pipeline Issue Triage Nov 14, 2025
Comment thread modules/gltf/structures/gltf_accessor.cpp
@fire fire requested a review from a team November 14, 2025 08:37
Comment thread modules/gltf/structures/gltf_accessor.cpp Outdated
Comment thread modules/gltf/structures/gltf_accessor.cpp Outdated
Comment thread modules/gltf/structures/gltf_accessor.h Outdated
Comment thread modules/gltf/structures/gltf_accessor.h Outdated
Comment thread modules/gltf/gltf_document.cpp Outdated
Comment thread modules/gltf/gltf_document.cpp Outdated
Comment thread modules/gltf/gltf_document.cpp Outdated
Comment thread modules/gltf/gltf_document.cpp Outdated
Comment thread modules/gltf/gltf_document.cpp Outdated
Comment thread modules/gltf/gltf_document.cpp Outdated
@Repiteo Repiteo merged commit 0d66b2a into godotengine:master Nov 14, 2025
20 checks passed
@github-project-automation github-project-automation Bot moved this from Ready for review to Done in Asset Pipeline Issue Triage Nov 14, 2025
@Repiteo
Copy link
Copy Markdown
Contributor

Repiteo commented Nov 14, 2025

Thanks!

@aaronfranke aaronfranke deleted the gltf-accessor-decode branch November 15, 2025 02:26
@fire
Copy link
Copy Markdown
Member

fire commented Nov 25, 2025

@akien-mga bisected a [gltf import] 1x to 2x slowdown because of this pull request on master. I'll post the most current master commit 4601c07 but the git bisect was done earlier.

aaronfranke is checking now.

@aaronfranke
Copy link
Copy Markdown
Member Author

For the record: The specific part of the code that regressed in performance was about 50 times slower. So it was catastrophically bad, apologies for my mistake. Anyway, it is now fixed as of PR #113172.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Development

Successfully merging this pull request may close these issues.

4 participants