Skip to content

feat(vat): --include-shaders flag + Inspector checkboxes - #649

Merged
fernandotonon merged 3 commits into
masterfrom
feat/vat-include-shaders
May 20, 2026
Merged

feat(vat): --include-shaders flag + Inspector checkboxes#649
fernandotonon merged 3 commits into
masterfrom
feat/vat-include-shaders

Conversation

@fernandotonon

@fernandotonon fernandotonon commented May 20, 2026

Copy link
Copy Markdown
Owner

Summary

Adds an opt-in step at the end of a VAT bake that drops the matching drop-in shader templates next to the bake — so a downstream consumer has the bake (PNG, sidecar, glTF, bind file) AND the engine glue code together in one folder, no chasing `tools/vat-shaders/` in the repo.

CLI

```bash
qtmesh vat character.fbx --anim "Dance" --include-shaders godot,unity
```

`` is a comma-separated subset of `{godot, unity, unreal}` (case-insensitive), or `all`. Unknown tokens are silently dropped with a warning.

Inspector

A new "Include shader" master checkbox in the VAT panel, followed by three per-engine sub-checkboxes (Godot / Unity / Unreal) that only appear when the master toggle is on. Godot defaults to on (the engine the website demo + most early users target); the others off. The state lives on the QML side and is passed to `VATBakerController.bake()` as a `QStringList`.

Mechanics

  • `tools/vat-shaders/vat_shaders.qrc` registers the three engine shaders and the bundled README as Qt resources under `:/vat-shaders/`. Linked into the executable so the templates ship inside the binary — no filesystem lookup needed when invoked from an installed `.deb` / `.app` / `.exe`.
  • `VATShaderEmitter` (pure-data helper): parses the CLI list string into a deduplicated lowercased subset, copies the requested resources to `outputDir`, and drops a small `OpenVAT_README.md` alongside when at least one engine was emitted. Idempotent overwrite.
  • Both the CLI (`CLIPipeline::cmdVat`) and GUI controller (`VATBakerController::bake`) route through the same emitter, so the JSON report's new `shaders` array, the text report's `shader:` lines, and the Inspector's bake output stay in sync.

Docs

  • `qtmesh vat` reference section gains `--include-shaders ` with two new example invocations.
  • Home-page CLI panel "VAT" tab demonstrates the flag.

Test plan

  • `--include-shaders all` drops 3 shaders + README into outputDir
  • `--include-shaders godot` drops just `openvat.gdshader` + README
  • `--include-shaders godot,unity` drops `openvat.gdshader` + `openvat.shader` + README
  • No flag → no shader files in outputDir, "re-run with --include-shaders all" hint in text output
  • Unknown token (e.g. `--include-shaders blender`) emits a warning and exits cleanly
  • App still builds + launches with the new `.qrc` linked in

Related

Follows the v3.3.0 VAT MVP release (PR #648).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added optional shader file generation during VAT baking—users can now select which game engines (Godot, Unity, Unreal) to generate shader templates for, or generate for all engines.
    • Updated UI with "Include shader" toggle and per-engine checkboxes in the Animation Mode panel.
    • New CLI flag --include-shaders {godot,unity,unreal,all} for command-line VAT export.
  • Documentation

    • Updated documentation with new shader generation options and examples.

Review Change Stack

Adds an opt-in step at the end of a VAT bake that drops the
matching drop-in shader templates next to the bake — so a
downstream consumer has the bake (PNG, sidecar, glTF, bind file)
AND the engine glue code together in one folder.

CLI surface:

  qtmesh vat <file> --anim <name> --include-shaders <list>

  where <list> is a comma-separated subset of {godot, unity, unreal},
  or "all". Unknown tokens are silently dropped with a warning.

Inspector surface:

  A new "Include shader" checkbox in the VAT panel, followed by
  three per-engine sub-checkboxes (Godot / Unity / Unreal) that
  only appear when the master toggle is on. Godot defaults to
  on; the others off. The state lives on the QML side and is
  passed to VATBakerController.bake() as a QStringList.

Mechanics:

  - `tools/vat-shaders/vat_shaders.qrc` registers the three
    engine shaders and the bundled README as Qt resources under
    `:/vat-shaders/`. Linked into the executable so the templates
    ship inside the binary — no filesystem lookup needed when
    invoked from an installed `.deb` / `.app` / `.exe`.
  - `VATShaderEmitter` (pure-data helper): parses the CLI list
    string, copies the requested resources to `outputDir`, and
    drops a small `OpenVAT_README.md` alongside when at least
    one engine was emitted. Idempotent overwrite.
  - Both the CLI (`CLIPipeline::cmdVat`) and GUI controller
    (`VATBakerController::bake`) route through the same emitter,
    so the JSON report's new `shaders` array, the text report's
    `shader:` lines, and the Inspector's bake output stay in
    sync.

Docs:

  - `qtmesh vat` reference section gains `--include-shaders <list>`
    with two new example invocations.
  - Home-page CLI panel "VAT" tab demonstrates the flag.
@coderabbitai

coderabbitai Bot commented May 20, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@fernandotonon has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 44 minutes and 1 second before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ec552f60-4ceb-4c65-b75f-f47e003e3ae4

📥 Commits

Reviewing files that changed from the base of the PR and between 190365f and 5e99f74.

📒 Files selected for processing (5)
  • src/CLIPipeline.cpp
  • src/VATBakerController.cpp
  • src/VATShaderEmitter.cpp
  • src/VATShaderEmitter.h
  • tests/CMakeLists.txt
📝 Walkthrough

Walkthrough

The PR extends the VAT (Vertex Animation Texture) exporter to optionally generate engine-specific shader template files during bake. A new VATShaderEmitter class reads embedded Qt resources and writes drop-in shader templates for Godot, Unity, and Unreal. The QML UI adds a master "Include shader" checkbox with per-engine toggles; the CLI gains a --include-shaders flag; and VATBakerController::bake() accepts an engine list and delegates shader writing. Output is reported in both JSON and human-readable formats.

Changes

Shader Emission for VAT Exporter

Layer / File(s) Summary
VATShaderEmitter: API contract and core implementation
src/VATShaderEmitter.h, src/VATShaderEmitter.cpp, tools/vat-shaders/vat_shaders.qrc
New VATShaderEmitter class with engine constants (Godot, Unity, Unreal) and two static functions: parseEngineList parses comma-separated engine tokens with "all" expansion and deduplication; writeShaders copies embedded Qt shader resources to disk and returns absolute paths of files written.
VATBakerController: extended bake signature and shader invocation
src/VATBakerController.h, src/VATBakerController.cpp
VATBakerController::bake() adds optional includeShadersFor parameter; implementation conditionally calls VATShaderEmitter::writeShaders() after successful bake when engine list is non-empty and logs breadcrumb if shaders were written.
QML UI: shader emission controls in PropertiesPanel
qml/PropertiesPanel.qml
VAT tools state extends with master includeShaders boolean and per-engine toggles (Godot/Unity/Unreal); UI conditionally shows per-engine checkboxes when master toggle is on; bake button constructs engines array from selected toggles and passes to updated VATBakerController.bake(...).
CLIPipeline: CLI --include-shaders argument parsing
src/CLIPipeline.cpp
vat command help text documents new --include-shaders {godot,unity,unreal,all} option; argument parsing accepts and stores the flag value; usage error messaging updated to include new option.
CLIPipeline: VAT bake shader emission and output reporting
src/CLIPipeline.cpp
During cmdVat bake, parses requested engines and conditionally writes shader files via VATShaderEmitter; JSON output includes shaders array with written file paths; text output lists generated paths or guidance about --include-shaders.
CMakeLists.txt: compile VATShaderEmitter and bundle shader resources
src/CMakeLists.txt
Adds VATShaderEmitter.cpp to source file list; uses qt_add_resources to create VAT_SHADER_RESOURCE_SRCS from tools/vat-shaders/vat_shaders.qrc; includes VAT shader resources in Windows, macOS, and generic executable targets.
Website documentation and CLI examples
website/src/DocsApp.jsx, website/src/data/content.js
Command documentation includes --include-shaders <list> option description; website examples updated with --include-shaders godot,unity and --include-shaders all usage patterns.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

  • fernandotonon/QtMeshEditor#371: This PR directly extends the VAT exporter feature to support per-engine shader emission control via CLI flag and QML UI, which relates to VAT capability expansion in the retrieved issue.

Possibly related PRs

  • fernandotonon/QtMeshEditor#568: Both PRs modify qml/PropertiesPanel.qml and VATBakerController::bake(...) for the VAT Inspector workflow; this PR extends the bake signature with an engine-selection list parameter.
  • fernandotonon/QtMeshEditor#620: Both PRs touch the VAT CLI/bake API surface; PR #620 simplified VAT to OpenVAT-only flow, while this PR reintroduces per-engine selection specifically for shader emission via --include-shaders and includeShadersFor.

Poem

🐰 From shader code born in resources deep,
A baker writes templates for engines to keep,
Godot, Unity, Unreal now share,
The drop-in shaders with pixelated flair,
One toggle, one CLI, all engines there!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main changes: adding a CLI flag and GUI checkboxes for shader inclusion in VAT baking.
Description check ✅ Passed The description is comprehensive and follows the template structure with Summary and Technical Details sections, including features, CLI examples, mechanics, docs, and test plan.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/vat-include-shaders

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 190365fa72

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/CLIPipeline.cpp
Comment on lines +5948 to +5951
if (engines.isEmpty()) {
err() << "Warning: --include-shaders=\"" << includeShadersArg
<< "\" did not match any known engine "
"(accepted: godot, unity, unreal, all)." << Qt::endl;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Warn on partially invalid --include-shaders lists

Only the engines.isEmpty() path emits a warning, so inputs like --include-shaders godot,blender silently drop blender and still succeed. In that case users can believe all requested templates were emitted, but one engine is missing and the problem is only discovered later during integration. Please detect and warn when any token is invalid, not just when all tokens are invalid.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/CLIPipeline.cpp`:
- Around line 5704-5710: The argument parsing currently skips
`--include-shaders` if no following token exists; update the parsing loop where
`arg`, `i`, and `argc` are used (the block that sets includeShadersArg) to
detect a missing value for `--include-shaders` and handle it as an error: when
`arg == "--include-shaders"` and `i + 1 >= argc`, emit a clear error message
(including the flag name) and abort/exit with non-zero status (or return an
error code) instead of silently continuing; otherwise keep the existing behavior
of assigning includeShadersArg = QString(argv[++i]).
- Around line 5943-5964: The current branch handling for includeShadersArg only
adds a Sentry breadcrumb on success; add breadcrumbs for the two failure
branches so invalid-engine and write-failure outcomes are tracked: when
VATShaderEmitter::parseEngineList(includeShadersArg) returns empty, call
SentryReporter::addBreadcrumb("file.export", QStringLiteral("VAT shaders:
invalid engine list: %1").arg(includeShadersArg)) alongside the existing err()
warning; when VATShaderEmitter::writeShaders(outDir, engines) returns an empty
list, add SentryReporter::addBreadcrumb("file.export", QStringLiteral("VAT
shaders: no files written for engines:
%1").arg(engines.join(QStringLiteral(",")))) alongside the existing err()
warning so both failure paths are recorded.

In `@src/VATBakerController.cpp`:
- Around line 179-187: When users requested shaders (includeShadersFor not
empty) we currently only breadcrumb the success case; update VATBakerController
so after calling VATShaderEmitter::writeShaders(outputDir, includeShadersFor)
you always emit a SentryReporter::addBreadcrumb: if shadersWritten.isEmpty() add
a "file.export" breadcrumb indicating shader write failed/no files written and
include the original includeShadersFor list; if shadersWritten.size() <
includeShadersFor.size() add a "file.export" breadcrumb indicating a partial
write that lists shadersWritten and the missing entries (requested minus
written); also ensure you add a breadcrumb when result.ok is false to record the
overall bake/export failure using SentryReporter::addBreadcrumb so all
failure/partial paths are tracked.

In `@src/VATShaderEmitter.cpp`:
- Around line 66-94: parseEngineList currently appends valid explicit tokens in
input order but must return a stable canonical order defined by kSpecs; change
the function to record valid engines into the seen set (use findSpec to validate
and still handle the "all" branch by inserting all kSpecs into seen) and defer
building out until the end by iterating kSpecs and calling pushIfFresh/append
for each spec whose engine is present in seen, so the final returned QStringList
follows the canonical kSpecs order while keeping uniqueness (references:
parseEngineList, kSpecs, findSpec, pushIfFresh, tokens).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b8858717-0b22-42cc-9e16-a119284fdaa9

📥 Commits

Reviewing files that changed from the base of the PR and between 4dc98da and 190365f.

📒 Files selected for processing (10)
  • qml/PropertiesPanel.qml
  • src/CLIPipeline.cpp
  • src/CMakeLists.txt
  • src/VATBakerController.cpp
  • src/VATBakerController.h
  • src/VATShaderEmitter.cpp
  • src/VATShaderEmitter.h
  • tools/vat-shaders/vat_shaders.qrc
  • website/src/DocsApp.jsx
  • website/src/data/content.js

Comment thread src/CLIPipeline.cpp
Comment thread src/CLIPipeline.cpp
Comment thread src/VATBakerController.cpp
Comment thread src/VATShaderEmitter.cpp Outdated
1) parseEngineList — surface rejected unknown tokens (Codex P2)

   parseEngineList now takes an optional `QStringList* rejectedOut`
   that the CLI fills and reports separately from the
   "no valid engines at all" branch. Previously
   `--include-shaders godot,blender` silently dropped "blender" and
   succeeded with just the Godot template, leaving the user to
   discover the missing engine during integration.

2) Missing value for --include-shaders is now an error
   (CodeRabbit Major)

   Bare `qtmesh vat ... --include-shaders` used to skip the flag
   silently if no value followed. Now it exits 2 with an error
   message naming the accepted values.

3) Breadcrumbs on every shader-emission outcome
   (CodeRabbit Major + Minor)

   Both the CLI (CLIPipeline::cmdVat) and the GUI controller
   (VATBakerController::bake) now emit a `file.export` breadcrumb on
   the no-valid-engines, write-failed-for-all-requested, AND
   success branches. The previous code only logged success, which
   left Sentry blind to "user asked for shaders, got nothing."

4) Canonical output order in parseEngineList
   (CodeRabbit Minor)

   The API contract said output order was stable as
   "godot, unity, unreal" but the implementation preserved input
   order (so `"unity,godot"` returned `["unity", "godot"]`). Fixed
   by collecting valid tokens into a set, then emitting them by
   walking the canonical engine spec list.

Verified end-to-end with the actual binary:
  --include-shaders                       → exit 2, error message
  --include-shaders godot,blender         → warning + writes godot only
  --include-shaders blender,maya,godot    → warning + writes godot only
  --include-shaders blender,maya          → 2 warnings, no shaders written
  --include-shaders unity,godot           → writes in canonical order
CI broke on the previous commit because test binaries link against
CLIPipeline.cpp and VATBakerController.cpp, both of which now
reference VATShaderEmitter::parseEngineList / writeShaders. The
src/CMakeLists.txt already added the new translation unit to
TEST_SRC_FILES's sibling list for the main executable, but the test
binaries pull from tests/CMakeLists.txt's TEST_SRC_FILES — that list
was missed.

Adding the .cpp there makes every test executable that links the
common test-source bundle find the symbols.
@sonarqubecloud

Copy link
Copy Markdown

@fernandotonon
fernandotonon merged commit 263e7fb into master May 20, 2026
20 checks passed
@fernandotonon
fernandotonon deleted the feat/vat-include-shaders branch May 20, 2026 21:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant