Checking a delivery
Four questions decide whether a delivery is good, they fail independently, and no single tool answers more than one of them. The profile’s Conformance testing section states them; this page says what to actually run.
Question |
How |
|
|---|---|---|
Valid |
Is it legal glTF? |
The Khronos glTF Validator. Zero errors required. |
Intended |
Does it look like what the modeler meant? |
The Khronos Sample Viewer, by a person. It runs the validator inline, so one drag and drop answers this and the row above together. It cannot answer orientation — see below. |
Compliant |
Does it satisfy the profile? |
|
Usable |
Does it render in Gazebo and load in RViz? |
Open it. For what the loader built rather than what it looks like, |
Passing in Gazebo is necessary and never sufficient: Gazebo ignores several things a file can get wrong, so a defect can be invisible there and fatal elsewhere. The clearest case is a material carrying a normal map and no base colour, which renders in Gazebo and terminates RViz.
Blender’s viewport answers none of these. It shows Blender’s materials, not the exported file, and the export is a translation in which metallic factor, image format, alpha mode and tangents can all change.
The reference viewer does answer orientation. The profile’s Axes section delivers files in glTF’s own convention, +Y up and +Z forward, which is what every third-party viewer assumes, so a conforming part stands upright and faces the camera in the Sample Viewer’s default view. A part on its side was exported with +Y Up off; a part facing sideways was built facing the wrong way in Blender. No tool can settle orientation from the file alone, since nothing in a glTF file records which way its author meant forward, so this view and the Gazebo check are where it is decided.
Running the checker
pip install git+https://github.com/HonuRobotics/gltf-robotics
gltf-check path/to/part_visual.glb
It parses the file rather than rendering it, so it needs no Gazebo, no GPU and no ROS. Point it at several files at once. The terminal output puts the verdict first, then each problem, then the checks that passed collapsed into one line — named rather than hidden, since a report of problems alone cannot tell you whether the thing you cared about was examined. Add -v to list every test with its full reason, -q to drop the PASS and SKIP lines, --report FILE.md to choose where the Markdown report goes, --json for machine-readable output, and --strict to treat SHOULD violations as failures.
gltf-summary answers a different question: not whether a file conforms, but what is in it. Structure, geometry, materials, and where the origin sits inside the bounding box — the last of which no viewer shows you. It reaches no verdicts, so it is the tool for an unfamiliar file or for confirming that a correct one really is correct. --explain appends a glossary of the output.
Reading the output
Each file opens with its name and verdict, then the tally. Below come the FAIL, WARN and OPEN findings in profile order: the mark, the test name (the profile section), a one-line finding, and the reason behind it — in full when it is short, otherwise its first sentence, with the rest under -v. The passes and skips close the file as one line each, naming their sections. With several files a last line counts how many are compliant. Marks are coloured when the output goes to a terminal, and plain in a pipe, a log or with NO_COLOR set. The marks, explained below, are also listed in gltf-check --help.
Every run also writes the full record as Markdown, for review and for walkthroughs, to gltf-check-output.md in the current directory; --report FILE.md writes it elsewhere. It opens with the legend. With several files it then has a matrix — tests as rows, files as columns, each cell the worst mark for that test, and a Verdict row — so a delivery’s parts read side by side. Each file then gets its verdict, a table of every test (mark, test name, what the rule tests, what it found), the reasons behind anything but a pass, and the file’s structure: the scene, node, mesh, primitive and material tree, with the scene the file opens starred and anything no scene reaches listed after it.
The marks are five words, used identically in every place they appear.
PASS is a rule satisfied. Listed rather than hidden, because the question “was that examined?” needs an answer as much as “did it fail?”.
FAIL is a MUST in the profile. The delivery is not compliant. Each one names the section that justifies it, so a disagreement is a disagreement with a specific rule and its stated reason, not with the tool.
WARN is a SHOULD, or a MUST the tool cannot fully settle. The second kind is worth understanding rather than skimming: reading a file cannot decide everything. A material that leaves metallicFactor unset but carries a metallic-roughness texture is the standing example — the texture’s blue channel multiplies against the factor, so a black channel would still give a non-metal, and only the decoded texels say which it is. Do not read that warning as “probably fine”. A solid white metallic channel is the usual export, and every map measured in this project’s own library had B = 255.
OPEN is a rule the profile has not decided, or one nothing in the file can answer. The profile’s Open issues section is explicit that a delivery cannot fail to conform on a point marked Open, so these never fail a run: they are something to discuss, not something to fix. Scale is here when the manifest cites no dimension: glTF says meters and nothing in the file confirms it. When the manifest does cite one, the Units rule compares it with the file’s extent and passes or fails. Forward axis is here too, since no glTF file records one. The protocol for answering those by eye is in probe/.
SKIP is a rule with nothing to examine — the texture rules on a file with no images, the datum rule on a file that declares no part role.
The verdict says compliant rather than conforms on purpose: compliant is the profile’s Conformance testing section’s third question, every MUST satisfied, and it is the only one of the four this tool answers. A file with only WARN findings is therefore compliant, with things to review before delivering; --strict counts them as failures instead. The exit code and the --json output follow the same rule as the text, so a script and a reader never disagree about a file.
What a clean run does not mean
A clean run is one of the four answers above, not the answer. It says the file satisfies the rules that can be decided by reading it. It says nothing about whether the part looks right, whether it is the correct size, which way it faces, or what Gazebo’s loader will build from it.