Skip to content

fix(asset): scene texture paths resolve against project root, not cwd (#887) - #916

Merged
drsnuggles8 merged 1 commit into
masterfrom
feature/decal-texture-roundtrip-887
Aug 23, 2026
Merged

fix(asset): scene texture paths resolve against project root, not cwd (#887)#916
drsnuggles8 merged 1 commit into
masterfrom
feature/decal-texture-roundtrip-887

Conversation

@drsnuggles8

Copy link
Copy Markdown
Owner

Summary

Root-caused and fixed #887. The decal texture arm was the reported symptom; the
underlying bug affected any scene-authored, project-relative texture path
("Assets/Textures/Foo.png"), not just decals.

Root cause, found by driving the live editor over its MCP diagnostics server and
reading OloEngine.log:

  1. EditorAssetManager::ImportAsset resolved a relative input path via
    std::filesystem::absolute(), which resolves against the process's current
    working directory
    (OloEditor/), not the project directory
    (OloEditor/SandboxProject/) the path is documented to be relative to. Because
    OloEditor/ also ships a copy of every generic texture under its own assets/
    tree, this wrong resolution frequently "succeeded" anyway — but registered the
    asset under a bogus ../assets/... relative key.
  2. TextureSerializer::TryLoadData then read straight from that bogus (still
    cwd-relative) key instead of prefixing Project::GetProjectDirectory(), the way
    every other AssetSerializer::TryLoadData in the file already does. The actual
    pixel load failed, and AssetManager::ResolveAssetOrPlaceholder silently
    substituted a placeholder texture — non-null, but with an empty GetPath().

SceneSerializer then wrote that empty path back into the scene YAML, and a
component that had already round-tripped an empty path once dropped the reference
entirely on the next save (the .scenebin symptom) — an empty path fails to
resolve back into a texture on reload, so nothing is written at all. This matches
the "double-silent, second-load" framing in the issue exactly.

Fix

  • EditorAssetManager::ImportAsset now tries the documented project-relative
    resolution first, falling back to the previous cwd-relative behaviour only when
    that fails — several existing scenes (PinkCubeWithTextures, the Sponza scenes,
    VehiclesTest, Drift) still carry the older working-directory-relative
    spelling and must keep resolving unchanged.
  • TextureSerializer::TryLoadData/TryLoadRawData now read from
    Project::GetProjectDirectory() / metadata.FilePath, matching every other
    serializer in the file, while keeping the reported identity (GetPath())
    project-relative — via a new optional identityPath parameter on
    Texture2D::Create, threaded through both the OpenGL and Vulkan backends
    (purely additive, default-valued, so no existing call site changes behaviour).

Verified live over the editor's MCP diagnostics server, before and after the fix,
across both the YAML and .scenebin load paths (see log excerpts in the linked
issue investigation).

Test plan

  • New AssetSceneLoad.DecalAndSpriteTexturePathsSurviveRoundTrip — loads
    DecalModeMatrixTest.olo and PinkCubeWithTextures.olo twice each (once via
    YAML, once via the resulting .scenebin sidecar) through a staged
    EditorAssetManager, asserting both texture paths survive non-empty and
    identical across both loads.
  • OloEngine-Tests.exe --gtest_filter="AssetSceneLoad.*" — 3/3 passed.
  • OloEngine-Tests.exe --gtest_filter="*Texture*:*Sprite*:*Decal*:ComponentRoundTrip.*:SceneBinarySidecar.*:*AssetContentValidity*" — 355/355 passed.
  • Live-verified in the running editor via MCP (olo_scene_open +
    olo://scene/current): both DecalModeMatrixTest.olo's
    EmissiveTexturePath and PinkCubeWithTextures.olo's TexturePath resolve
    correctly and round-trip through both load paths.

🤖 Generated with Claude Code

…project root, not cwd (#887)

EditorAssetManager::ImportAsset resolved a relative input path (the
"Assets/Textures/Foo.png" spelling scene YAML stores) via
std::filesystem::absolute(), which resolves against the process's
current working directory (OloEditor runs with cwd = OloEditor/, one
level above the project directory). Whenever a same-named file
happened to also exist under OloEditor's own generic assets/ tree —
true for every shipped texture — that wrong resolution silently
"succeeded", registering the asset under a bogus "../assets/..."
relative key. TextureSerializer::TryLoadData then loaded straight
from that bogus (still cwd-relative) key instead of prefixing
Project::GetProjectDirectory() like every other AssetSerializer in
the file already does, so the actual pixel load failed and a
placeholder texture was substituted — non-null, but with an empty
GetPath(). SceneSerializer wrote that empty path back into the scene
(YAML), and a component that had already round-tripped an empty path
once dropped the reference entirely on the next save (.scenebin),
since an empty path fails to resolve back into a texture on reload.

Fix: ImportAsset now tries the documented project-relative resolution
first, falling back to the previous cwd-relative behaviour only when
that fails (preserving several existing scenes that still carry the
older working-directory-relative spelling). TextureSerializer now
reads from Project::GetProjectDirectory() / metadata.FilePath while
keeping the reported identity (GetPath()) project-relative, via a new
optional identityPath parameter on Texture2D::Create threaded through
both the OpenGL and Vulkan backends.

Adds AssetSceneLoad.DecalAndSpriteTexturePathsSurviveRoundTrip, which
loads DecalModeMatrixTest.olo and PinkCubeWithTextures.olo twice each
(once via YAML, once via the resulting .scenebin sidecar) through a
staged EditorAssetManager and asserts both texture paths survive
non-empty and identical across both loads.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@drsnuggles8, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 32 minutes

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

Wait for the limit to reset, then comment @coderabbitai review or push new commits to the PR.

An organization admin can change what happens after included review limits in Billing.

How do review limits work?

CodeRabbit enforces per-developer PR review limits within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 5a64349a-484d-4df0-a782-4b483eb63979

📥 Commits

Reviewing files that changed from the base of the PR and between bc5af38 and f3d7a34.

📒 Files selected for processing (9)
  • OloEngine/src/OloEngine/Asset/AssetManager/EditorAssetManager.cpp
  • OloEngine/src/OloEngine/Asset/AssetSerializer.cpp
  • OloEngine/src/OloEngine/Renderer/Texture.cpp
  • OloEngine/src/OloEngine/Renderer/Texture.h
  • OloEngine/src/Platform/OpenGL/OpenGLTexture.cpp
  • OloEngine/src/Platform/OpenGL/OpenGLTexture.h
  • OloEngine/src/Platform/Vulkan/VulkanTexture.cpp
  • OloEngine/src/Platform/Vulkan/VulkanTexture.h
  • OloEngine/tests/AssetSceneLoadTest.cpp

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.

@sonarqubecloud

Copy link
Copy Markdown

@drsnuggles8
drsnuggles8 merged commit bbd8819 into master Aug 23, 2026
13 checks passed
@drsnuggles8
drsnuggles8 deleted the feature/decal-texture-roundtrip-887 branch August 23, 2026 06:41
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.

DecalComponent texture references are lost on a scene round-trip (empty path via YAML, dropped entirely via .scenebin)

1 participant