Skip to content

p6-f2: imported prop textures — UVs and base-colour images through PropPart, the batch path and both exporters #507

Description

@JArmandoAnaya

Split out of #322 (p6-s8) · governed by ADR-0013.

Problem

p6-s8 imports a glTF/GLB as a prop, but an imported model's textures are
discarded
. props::PropPart carries positions, normals, indices and a single
flat linear-RGB color — no UVs, no texture reference
(core/include/roadmaker/assets/prop_library.hpp:40-46). So the importer decodes
the primitive's baseColorTexture, averages it, multiplies by
baseColorFactor, and stores that one colour, warning per primitive as it goes.

A user importing a patterned chair gets a chair in roughly the right colour. That
is honest, and it is the decision ADR-0013 records — but it is not the feature.

Why it was not done in p6-s8

Because PropPart is not the only thing in the way. Every consumer of a prop
model assumes flat colour:

  • editor/src/viewport/viewport_widget.cpp:625all props draw with one
    shared material_for(SurfaceKind::Untextured, {}).
  • editor/src/render/scene_builder.cpp:245-249 — a batch converts each part to
    RenderMeshData once, colour only; RenderMeshData does have a uvs field
    (editor/src/render/renderer.hpp:115-120), so the renderer is not the blocker.
  • core/src/io/gltf_exporter.cpp — one glTF material per (model_id, part.name)
    via mesh_export_common.hpp:130, flat colour.
  • core/src/io/usd_exporter.cpp:63-71 — its own local MaterialDef{color3, roughness}.

Doing it properly is a change to the kernel representation, the instanced upload
path, and both exporters — which crosses the export byte-identity surface.
That is its own sprint, not a rider on an import sprint.

Scope

  • PropPart gains std::vector<double> uvs and an optional base-colour image
    (owned by the model, so props::model()'s pointer contract is unchanged).
  • The importer stops flattening: it keeps UVs and the decoded image, and the
    warning this issue is cited from disappears.
  • ScenePropBatch carries the material; the viewport uploads it once per batch
    (the sign-face path at viewport_widget.cpp:179-197 is the precedent for a
    runtime-generated texture) and stops sharing one untextured material.
  • The glTF exporter embeds the image; the USD exporter emits a UsdUVTexture.
  • Existing bundled props have no UVs and must keep exporting byte-identically
    — that is the regression gate, not a nice-to-have.

Acceptance

  • A textured GLB imports, renders with its texture, and exports with it to both
    .glb and .usda.
  • Every bundled prop's .glb and .usda output is byte-identical to before.
  • No import warning about flattening remains.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpillar:P6Road to Parity pillar P6

    Type

    No type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions