Skip to content

fix(assets): preserve companion file paths and migrate existing flat textures - #64

Merged
JeanPhilippeKernel merged 4 commits into
developfrom
fix/asset-companion-paths
Aug 24, 2026
Merged

JeanPhilippeKernel merged 4 commits into
developfrom
fix/asset-companion-paths

Conversation

@JeanPhilippeKernel

Copy link
Copy Markdown
Owner

Problem

The Poly Haven API returns companion file relative paths as inc.Key (e.g. textures/foo_diff_4k.jpg, foo.bin). The previous code only stored the URL and derived the filename via Path.GetFileName, silently dropping the subdirectory prefix. All textures were placed flat next to the primary model file, breaking texture references in GLTF, FBX, Blend, and USD files.

Changes

Fix: new downloads use correct structure

  • AssetFormatOption: CompanionUrls List<string> → CompanionFiles List<(RelativePath, Url)>
  • LoadAssetFormatsAsync: store (inc.Key, url) instead of url only
  • LoadAndDownloadAssetAsync: use RelativePath verbatim relative to destDir, creating subdirectories (textures/) as needed

Fix: background migration for existing assets

  • MigrateAssetFoldersAsync runs once at startup in the background
  • Finds all flat image files (jpg/jpeg/png/webp/hdr/exr) under AppPaths.Assets
  • Moves them into textures/ alongside their primary model file
  • Shows a toast before migration begins and after completion
  • Idempotent — skips files that are already in the correct location
  • Non-fatal — any individual move failure leaves the file in place

Result

assets/{assetId}/{resolution}/
├── {model}.gltf / .fbx / .blend / .usd   ← texture refs now resolve
├── {model}.bin                            ← GLTF buffer stays flat
└── textures/
    ├── {model}_diff_{res}.jpg
    ├── {model}_nor_gl_{res}.jpg
    └── ...

Verified against GLTF (wine_barrel_01, chandelier_03), FBX, Blend — all formats use textures/ consistently per the Poly Haven API.

The Poly Haven API includes companion file relative paths as inc.Key
(e.g. 'textures/foo_diff_4k.jpg', 'foo.bin'). The previous code only
stored the URL and derived the filename via Path.GetFileName, dropping
the subdirectory prefix entirely. All textures were placed flat next to
the primary model, breaking GLTF/FBX/Blend/USD texture references.

- AssetFormatOption: replace CompanionUrls List<string> with
  CompanionFiles List<(string RelativePath, string Url)>
- LoadAssetFormatsAsync: store (inc.Key, url) instead of url only
- LoadAndDownloadAssetAsync: use RelativePath verbatim relative to
  destDir, creating subdirectories (e.g. textures/) as needed
…artup

Existing downloaded assets have textures sitting flat next to the primary
model file instead of in a textures/ subdirectory, breaking GLTF/FBX/Blend/USD
texture references. MigrateAssetFoldersAsync runs once at startup in the
background: it collects all flat image files (jpg/jpeg/png/webp/hdr/exr) under
AppPaths.Assets, moves them into the textures/ subdirectory alongside their
primary model, and notifies the user with toasts before and after. Dirs that
are already correctly structured are skipped. Non-fatal — any individual move
failure leaves the file in place.
…eption

Directory.EnumerateFiles with SearchOption.AllDirectories throws when it
walks into protected system paths (e.g. Photos Library.photoslibrary) if
the user sets the engine install location to a broad directory like their
home folder. Catch IOException and UnauthorizedAccessException at both
the top-level directory scan and per-version file search so the scan
completes gracefully instead of crashing the app.
@JeanPhilippeKernel
JeanPhilippeKernel merged commit ddf004c into develop Aug 24, 2026
10 checks passed
@JeanPhilippeKernel
JeanPhilippeKernel deleted the fix/asset-companion-paths branch August 24, 2026 04:23
@JeanPhilippeKernel JeanPhilippeKernel self-assigned this Aug 24, 2026
@github-actions github-actions Bot mentioned this pull request Aug 24, 2026
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