Implement appearance baking pipeline (#66)
Some checks failed
Native code generation / deterministic (push) Failing after 2m18s
Imaging and meshing gate / native (push) Failing after 1m28s
Native Rust workspace compile / compile (push) Failing after 58s

This commit is contained in:
2026-08-10 10:33:29 +00:00
parent a9927fcfcb
commit b1f60db3d6
17 changed files with 3487 additions and 249 deletions

View File

@@ -57,5 +57,72 @@ Focused compatibility coverage lives in `current_outfit_folder_semantics`,
issue-relevant appearance cases. Native recording fakes additionally prove
create/remove compensation, create-before-attach ordering, replacement state,
layer preservation, and cancellation before backend interaction. Texture
baking, visual-parameter synthesis, and texture upload are a separate
appearance pipeline and are not owned by this service slice.
baking, visual-parameter synthesis, and texture upload are the next appearance
pipeline described below.
## Baking and texture transport
The baking pipeline retains all 45 avatar texture slots, all 11 classic and
extended baked outputs, the reference cache salts and sentinel UUIDs, and the
generated visual-parameter ordering from the pinned character definition.
Wearable assets are parsed as bounded LLWearable text, including parameter
values and texture indices. Texture retrieval is provided through
`IBakingTextureProvider`; the grid implementation downloads the asset and
decodes it through the existing JPEG2000 abstraction. At most five texture
downloads and six baked-texture uploads are in flight at once.
`Baker` composites owned image copies into 1024-by-1024 bakes (128-by-128 for
eyes). It applies the canonical head, skin-grain, hair, wearable alpha, tint,
and morph-bump layers, preserves color/alpha/bump channels, and caps a bake at
60 input layers. Character resources are resolved cross-platform from
`LIBREMETAVERSE_RESOURCE_DIR`, the configured resource directory, or the
project resource bundle. Cached images are cloned on both insertion and read,
so a caller cannot corrupt a later bake. Minimal installations have neutral
built-in base masks; JPEG2000 encoding remains behind the project codec
feature rather than a platform API.
Appearance setting first uses server-side baking when the simulator advertises
the appearance service and actually exposes `UpdateAvatarAppearance`; a region
with only the protocol flag falls back to local baking. The capability call
validates the COF version, success response, visual parameters, and required
baked texture IDs, with five cancellation-aware attempts and bounded
exponential delay. A classic region
requests cached bake hashes, incorporates the reply, downloads only necessary
inputs, bakes missing layers locally, uploads them, and sends the complete
`AgentSetAppearance` packet. Its texture entry uses the protocol's big-endian
seven-bit face masks and complete default-face attributes, while visual
parameters retain the reference's 218 normal or 251 physics-wearable fields
and drive the reported avatar height. Rebake packets cancel superseded work,
clear stale bake IDs, and force a fresh local bake. A region change before the
final send aborts and rolls back the old-region result. No synchronous state
lock crosses a network await or event callback. On cancellation or failure the
texture, wearable-asset, visual-parameter, and COF-version snapshots are
restored before the failure event is published.
Wearable discovery rebuilds both wearables and attachments from resolved COF
links with a 512-entry bound. On classic/OpenSim regions, an empty or unusable
COF result falls back to `AgentWearablesRequest` and waits up to 30 seconds for
`AgentWearablesUpdate`. The packet handler ignores server-baking dummy payloads,
preserves every valid item/asset/type tuple, wakes the pending request, and can
start a bake for a spontaneous legacy update. Missing wearable assets or
required texture downloads fail the pipeline instead of publishing a false
success with incomplete bakes.
## Initial outfit setup
First-login outfit setup searches the library iteratively with a 256-node
bound, creates missing Clothing and Trash system folders, counts the selected
tree, and copies its folder and item hierarchy into Clothing. Progress follows
`Counting`, `Copying`, `Applying`, then `Complete`; completion is reported only
after transactional COF replacement succeeds. Cancellation is checked during
planning, creation, copying, and application. A failed or cancelled copy
removes its partially created root, and a failed application removes the fully
copied root while the Current Outfit Folder restores its prior links. The
login handler starts this work once, owns its cancellation source and event
subscription, and disposes idempotently.
Focused verification covers the translated Baker cases, exact bake mappings
and cache hashes, generated visual metadata, wearable parsing, output pixels
and channels, packet/event payloads, cancellation before mutation, progress
state, and handler disposal. Live appearance tests remain opt-in because they
require grid credentials.