Jump to content
Main menu
Main menu
move to sidebar
hide
Navigation
Main page
Recent changes
Random page
Help about MediaWiki
Special pages
Open Simulator Technical Help
Search
Search
Appearance
Create account
Log in
Personal tools
Create account
Log in
Pages for logged out editors
learn more
Contributions
Talk
Editing
OpenSimulator Internals/Walkthroughs/Avatar Change Outfit
(section)
Page
Discussion
English
Read
Edit
View history
Tools
Tools
move to sidebar
hide
Actions
Read
Edit
View history
General
What links here
Related changes
Page information
Appearance
move to sidebar
hide
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
= OpenSimulator Internals/Walkthroughs/Avatar Change Outfit = == Overview == Traces what happens in code, connectors, and database when an avatar changes outfit -- replacing wearables and rebaking appearance textures. This covers the standard viewer-initiated outfit change. The sequence differs slightly between V1-style viewers (AvatarIsWearing only) and V2/3 viewers (AvatarIsWearing followed by AgentSetAppearance with baked textures). ---- == 1. Viewer Sends AvatarIsWearing == OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs -- Client_OnAvatarNowWearing() # Avatar selects new outfit or drags wearable items onto avatar in viewer. # Viewer sends AvatarIsWearing packet listing new wearable ItemIDs by WearableType slot. # AvatarFactoryModule.Client_OnAvatarNowWearing() fires. # Makes a copy of current AvatarAppearance (without textures). # Updates Wearables array on the copy: sets ItemID for each type, AssetID = UUID.Zero initially. # Calls avatAppearance.GetAssetsFrom(sp.Appearance) -- fills in known AssetIDs from current appearance where ItemID matches. # Under m_setAppearanceLock: writes sp.Appearance.Wearables only. Does NOT overwrite baked textures or visual params. # Calls QueueAppearanceSave() -- schedules async save after m_savetime (default 5s). Note: No appearance send at this step. The viewer will bake and send new textures next. ; No DB writes yet (save is queued, not executed). ---- == 2. Viewer Bakes New Textures Locally == This step happens entirely on the viewer side. No server involvement. * Viewer composites the new wearable assets (clothing layers, skin, etc.) into baked texture images for each BakeType (Head, UpperBody, LowerBody, Eyes, Skirt, Hair, and PBR variants). * Viewer uploads baked texture assets to the region's asset upload cap. * Assets arrive at AssetService and are stored (temporary=true, local=true initially). ; DB writes (via AssetService): * assets -- INSERT: each new baked texture asset (temporary, local) ---- == 3. Viewer Sends AgentSetAppearance == OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs -- Client_OnSetAppearance() β SetAppearance() # Viewer sends AgentSetAppearance packet containing: #* New TextureEntry -- baked texture UUIDs for each face index. #* New VisualParams -- slider values (height, body shape, etc.). #* WearableCacheItems -- CacheId/TextureID pairs for each bake index. #* AvatarSize vector. # AvatarFactoryModule.SetAppearance() called under m_setAppearanceLock. # Calls sp.Appearance.SetVisualParams() -- updates slider bytes, recalculates avatar height if changed. # Calls sp.Appearance.SetTextureEntries() -- updates baked texture UUIDs in appearance. # Calls UpdateBakedTextureCache(): #* Checks local IAssetCache for each baked texture asset. #* Updates WearableCacheItems with confirmed TextureID and CacheId. #* If any textures missing from cache: sends SendRebakeAvatarTextures() -- viewer must re-upload. Throttled to one request per texture per 30 seconds. #* If full set valid and changed: stores to IBakedTextureModule (bake server cache). # Calls QueueAppearanceSave() (appearance changed). # Calls QueueAppearanceSend(). ; No immediate DB writes -- both saves are queued. ---- == 4. Appearance Sent to Other Clients (Deferred) == AvatarFactoryModule.HandleAppearanceUpdateTimer() β SendAppearance() After m_sendtime (default 2s), timer drains m_sendqueue: # Calls sp.SendAppearanceToAllOtherAgents(): #* Iterates all root ScenePresences. #* Calls ControllingClient.SendAppearance() for each -- sends AvatarAppearance packet with new VisualParams and baked texture bytes. #* Respects parcel visibility (ParcelHideThisAvatar). # Calls Animator.SendAnimPack() -- sends current animation state. Other clients now render the avatar with the new appearance. ---- == 5. Appearance Saved to AvatarService (Deferred) == AvatarFactoryModule.HandleAppearanceUpdateTimer() β SaveAppearance() After m_savetime (default 5s), timer drains m_savequeue. Runs on thread pool. # Calls SetAppearanceAssets(): #* For each wearable slot: calls InventoryService.GetItem(userID, itemID) -- resolves ItemID to AssetID. #* If item not found: removes wearable from appearance, logs warning. #* Ignores Ruth default wearables. # Calls m_scene.AvatarService.SetAppearance(agentID, sp.Appearance): #* Connector: HTTP PUT to ROBUST AvatarService. #* ROBUST writes avatarappearance table (wearable list, texture entry, visual params) and avatarattachments table. ; DB writes: * inventoryitems -- SELECT: resolve each wearable ItemID to AssetID * avatarappearance -- UPDATE: new wearable list, texture entry, visual params * avatarattachments -- UPDATE: current attachment list ---- == 6. Attachments Changed (if outfit includes attachment changes) == OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs If the outfit change includes adding or removing attachments, the viewer sends separate RezSingleAttachmentFromInv / DetachAttachmentIntoInv packets independently of the appearance packets above. Adding an attachment: # Client_OnRezSingleAttachmentFromInv() fires. # RezSingleAttachmentFromInventory() checks not already worn. # RezSingleAttachmentFromInventoryInternal() calls IInventoryAccessModule.RezObject() -- fetches asset, deserialises SOG, adds to scene. # AttachObjectInternal() attaches to avatar, displaces any existing attachment at same point (if WearReplacesAll=true). # UpdateUserInventoryWithAttachment() updates inventory item to reflect attachment point. # ShowAttachInUserInventory() calls sp.Appearance.SetAttachment() and QueueAppearanceSave(). # Scripts created and started (CreateScriptInstances, ResumeScripts). # TriggerOnAttach() fires. Removing an attachment: # Client_OnDetachAttachmentIntoInv() fires. # DetachSingleAttachmentToInv() called -- see [[OpenSimulator Internals/Code Map/AttachmentsModule]]. # Script state snapshotted, object removed from scene, asset and inventory item updated. ; DB writes (per attachment change): * assets -- INSERT: updated attachment object asset (serialised XML) * inventoryitems -- UPDATE: new assetID, attach point ---- == Summary: DB Tables Touched == {| class="wikitable" ! Table !! Operation !! Step |- | assets || INSERT || Viewer uploads baked textures (step 2) |- | inventoryitems || SELECT || SetAppearanceAssets() resolves wearable AssetIDs (step 5) |- | avatarappearance || UPDATE || AvatarService.SetAppearance() (step 5) |- | avatarattachments || UPDATE || AvatarService.SetAppearance() (step 5) |- | assets || INSERT || Attachment object re-saved (step 6, if attachments changed) |- | inventoryitems || UPDATE || Attachment inventory item updated (step 6, if attachments changed) |} ---- == Timing Notes == * Appearance send is deferred 2s (m_sendtime) -- prevents flooding if multiple rapid changes. * Appearance save is deferred 5s (m_savetime) -- ensures all wearable asset uploads complete before inventory lookup. * Both delays are configurable in [Appearance] section of OpenSim.ini. * The AvatarIsWearing and AgentSetAppearance packets often arrive nearly simultaneously. m_setAppearanceLock ensures AvatarIsWearing does not overwrite SetAppearance texture changes. ---- == See Also == * [[OpenSimulator Internals/Walkthroughs]] * [[OpenSimulator Internals/Code Map/AvatarFactoryModule]] * [[OpenSimulator Internals/Code Map/AttachmentsModule]] * [[OpenSimulator Internals/Code Map/ScenePresence]] * [[OpenSimulator Internals/Code Map/ROBUST/AvatarService]] * [[OpenSimulator Internals/Walkthroughs/Avatar Rez In Region]] * [[OpenSimulator Internals/Walkthroughs/Avatar Logs Out]]
Summary:
Please note that all contributions to Open Simulator Technical Help may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
Open Simulator Technical Help:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Search
Search
Editing
OpenSimulator Internals/Walkthroughs/Avatar Change Outfit
(section)
Add topic