129 lines
7.6 KiB
Markdown
129 lines
7.6 KiB
Markdown
# Appearance, wearables, and the Current Outfit Folder
|
|
|
|
`AppearanceManager` owns the client-visible wearable and attachment snapshots.
|
|
Wearables retain their inventory item, asset, asset type, and wearable slot. A
|
|
clothing slot accepts at most 60 ordered layers; body parts are single-value
|
|
slots and replace an existing value of the same type. Sending the outfit emits
|
|
the native `AgentIsNowWearing` packet from a snapshot, then publishes the
|
|
appearance event after the send. Wearable reply and appearance subscribers are
|
|
also snapshotted before invocation, so no state or subscriber lock is held
|
|
during a callback.
|
|
|
|
Attachment calls preserve the inventory owner, name, description, permission
|
|
masks, flags, and requested attachment point in
|
|
`RezSingleAttachmentFromInv`. Add versus replace is encoded in the attachment
|
|
point field, and replace removes only objects at the selected non-default
|
|
point. `DetachAttachmentIntoInv` is keyed by inventory item ID. Queries expose
|
|
the same state by item, item ID, and attachment point.
|
|
|
|
## Current Outfit Folder ownership
|
|
|
|
`CurrentOutfitFolder` discovers the `CurrentOutfit` system folder from the
|
|
inventory store unless an explicit folder has been supplied. Its contents are
|
|
links: link UUIDs identify COF entries and link asset UUIDs identify the worn
|
|
inventory objects. Resolution first consults committed local link targets and
|
|
then the inventory store. This keeps successful mutations immediately
|
|
queryable while an asynchronous inventory reply is still being reconciled.
|
|
|
|
Clothing link descriptions encode the wearable type followed by a two-digit
|
|
layer number. Add chooses the first free layer, preserves existing layers, and
|
|
rejects a 61st layer. Replace removes the selected wearable type before
|
|
allocating its new layers. Body-part and attachment descriptions remain empty,
|
|
matching the reference link format. Folder ancestry and recursive outfit
|
|
discovery are cycle-safe and bounded to 256 nodes.
|
|
|
|
Mutations pass through a one-permit asynchronous operation gate. Waiting for
|
|
the gate is cancellation-aware, but the gate is not an inventory/state lock;
|
|
network awaits never retain a synchronous lock. Cancellation is checked while
|
|
planning and before committing. Once a commit begins, it completes or runs its
|
|
compensation before reporting the result, preventing a cancellation race from
|
|
leaving a half-written outfit.
|
|
|
|
Outfit changes create replacement links before removing old links. If removal
|
|
fails, new links are removed and old link descriptions are recreated. Attach
|
|
creates its COF link before executing the rez request; replacement removes the
|
|
displaced links only after the new attachment succeeds. A later failure
|
|
detaches the new item and restores displaced attachments. Detach similarly
|
|
restores the attachment if its COF link cannot be removed. The local shadow is
|
|
changed only after those network steps succeed.
|
|
|
|
`ICurrentOutfitPolicy` remains a pure decision/reporting boundary. Composite
|
|
policies use a stable subscriber snapshot, consult every policy for attach and
|
|
detach decisions, and invoke reports in registration order. Policy locks are
|
|
released before callbacks and committed changes are reported exactly once.
|
|
|
|
Focused compatibility coverage lives in `current_outfit_folder_semantics`,
|
|
`current_outfit_policy_semantics`, the COF link-description cases, and the
|
|
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 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.
|