glTF import mode is ignored so TRIANGLE_STRIP/TRIANGLE_FAN primitives remain mis-imported #841
Labels
No labels
Context: Bug
Context: Enhancements
Platform: Android
Platform: Linux
Platform: Web
Platform: Windows
Platform: iOS
Platform: macOS
Target: CI
Target: CLI
Target: Dependency
Target: Engine
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
SakulFlee/Orbital#841
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
parse_modelsnever readsPrimitive::mode(). Every primitive is imported asif it were a glTF
TRIANGLESprimitive, soTRIANGLE_STRIP(5) andTRIANGLE_FAN(6) assets import as garbage geometry instead of failing loudly.Where the assumption lives
Crates/orbital_importer_gltf/src/gltf/mod.rs, inparse_models(line numbers as of
main@5bf04032):mod.rs:902,mod.rs:921— the index accessor is read, butmodeisnever queried. Neither
Primitive::mode()norgltf::mesh::Modeisreferenced anywhere in the crate.
mod.rs:1072-1081— the winding flip assumes a triangle listunconditionally:
For a strip or a fan,
i/i+1/i+2are not the vertices of a triangle.mod.rs:926onward — the samestep_by(3)assumption appears in thenormal calculation, so computed normals are already wrong for strip/fan
before the flip even runs.
The flip also silently discards a trailing partial triangle
(
i + 2 < indices_vec.len()), with no warning.This is not just "read one more field"
orbital_mesh::MeshDescriptoris{ vertices, indices }with no topology, andorbital_material_shader::MaterialShaderDescriptor::primitive_topologyis aper-material field defaulting to
PrimitiveTopology::TriangleList. The pipelineis triangle-list only, so the work splits into two groups:
Expandable into a triangle list, no pipeline change:
TRIANGLESTRIANGLE_STRIPTRIANGLE_FANNot representable without plumbing a topology through
MeshDescriptorandthe render pipeline:
POINTS(0),LINES(1),LINE_LOOP(2),LINE_STRIP(3).Those two groups are worth separating: the first is a contained importer fix,
the second is a cross-crate change.
⚠️ Numbering trap: the glTF spec numbers are 0–6, but
gltf_json's RustModeenum starts atPoints = 1. Its discriminants are shifted by one fromthe spec values that appear in JSON files. Don't compare raw integers, and
don't trust
as u32on aMode.Notes for whoever picks this up
it. The flip's parity interacts with the strip winding rule, so doing it as
two independent passes is an easy way to produce subtly inside-out geometry
on every other triangle.
defines an unindexed primitive as implicitly indexed
0..N, which is exactlythe vertex order a strip and a fan are defined over. The synthesized
0..Nlist is the right starting point — what's missing is only the expansion.
Suggested test
Follow the inline-
.gltfpattern inCrates/orbital_importer_gltf/tests/import_assets.rs, which builds documentsfrom
serde_json::json!against a tempFileManager. A 4-vertex"mode": 5strip should yield 6 indices; a 5-vertex"mode": 6fan shouldyield 9.
Two shapes worth covering:
than just the vertex count;
NORMALattribute, so the asserted normals can onlycome from the expanded indices reaching the triangle-geometry path.
Open questions
TRIANGLES, so this may be a long tail — and some pipelines run assetsthrough meshopt, which normalizes to triangles anyway. Worth measuring
against real assets before investing. If the answer is "rare and handled
upstream", documenting the limitation may be the better outcome than a fix.
topology actually be plumbed through?
own issue? It is orthogonal to
modeand affects indexedTRIANGLEStoo.