Skip to content

p6-f3: 3D render-to-thumbnail for imported prop assets #509

Description

@JArmandoAnaya

Split out of #322 (p6-s8), where it is listed under Out of scope ("3D-render-to-thumbnail for props (glyph or first-frame fallback acceptable)").

Problem

An imported prop asset has no thumbnail, so its Library row falls back to a
themed glyph (editor/src/panels/library_panel.cpp:78-86). Every bundled prop
has a real preview, so the user's own assets are visibly the second-class rows in
their own library.

Why there is no easy answer today

Bundled prop thumbnails are not rendered by the editor. They are produced
offline by scripts/gen_library_thumbnails.py — a pure-stdlib software
rasteriser that draws an orthographic three-quarter view, painter's-sorted, flat
Lambert per part colour, at 96×96 (:147 render_model(), SIZE = 96 at :53)
— and the PNGs are committed. Nothing in the C++ product generates a prop
thumbnail at all. The material half of p6-s8 sidesteps this because a texture's
thumbnail is the image, scaled.

So this issue is "give the editor a prop previewer", and there are two honest
routes:

  1. Port the rasteriser to C++. Deterministic, headless, no GL context, works
    in tests and on a build machine, and matches the bundled thumbnails exactly
    because it is the same algorithm. Around 150 lines, QImage-only.
  2. Render through the real renderer into an offscreen FBO. Matches what the
    scene actually draws (including any future prop texturing —
    see the prop-texture follow-up), but needs a GL context at import time, which
    the headless editor tests deliberately do not have.

Route 1 is the recommendation, precisely because it keeps thumbnail generation
testable headless — the same constraint that put signs::render_face in the
kernel rather than behind Qt.

Scope

  • A headless prop previewer producing a 96×96 RGBA PNG from a props::PropModel.
  • Called on prop import; written to
    <project>/assets/library/thumbnails/<slug>.png; the manifest entry's
    thumbnail field points at it.
  • Regenerating a bundled prop's thumbnail through the new code path produces a
    visually equivalent image to the committed PNG (this is the correctness check —
    not byte identity, which the Python rasteriser does not promise either).
  • Test asserts a non-blank image with more than one distinct colour, so a
    silently-black render cannot pass.

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