Puppetry Network Control
This document is intended for developers and people that want to understand some of the technology used in Second Life so the viewers and region simulator can share Puppetry animation. It assumes the reader has some knowledge of C++ programming, http and what's happening inside Second Life. See How Puppetry Works for more information.
Puppetry Viewer and Server
The Second Life viewer communicates with region servers through two mechanisms. The first is the "Puppetry" capability (also referenced as a cap) to exchange information with the server about the feature. This is the same mechanism used by many other systems, and allows the viewer to detect, start, stop and control Puppetry functionality. The actual information to animate your and other avatars is sent in the AgentAnimation and the AvatarAnimation messages. These messages will have bone position and rotation data to pose the avatar.
The Puppetry Capability
The Puppetry capability may be requested from a viewer. Requesting this cap upon connection to a region enables puppetry messages and services between the viewer and the simulator. The name for the cap is `Puppetry` and should be requested when connecting to a region along with all other capabilities. If the simulator supports puppetry it will respond with a URL that can be used to access the services. If there is no response for "Puppetry", the server does not support it.
Getting the Current State of Puppetry
Issuing an HTTP GET to the puppetry cap queries the current state of puppetry. The response is an LLSD map with the following fields.
|Boolean||When this value is **true**the viewer has indicated to the simulator that it will be transmitting real-time puppetry data to the simulator. If this value is **false**, the simulator will discard any puppetry data received from a viewer.Default: True|
|Boolean||This controls whether the viewer will receive puppetry events from other transmitting viewers. When the value is true the simulator will append puppetry events to the AvatarAnimation messages sent as part of the interest list updates every frame.Default: True|
|Integer||Puppetry events are collected and send in blocks. This is the size of the largest collection of events that may be transmitted.Default: 255|
|Real||The simulator only transmits puppetry events to avatars within a certain range of the viewer. By default, this range is 25 meters.Default: 25|
|Array of UUIDs||List of agents that have been explicitly
subscribed to. Subscribed agents ignore the range limit.Default: empty
|Array of UUIDs||List of agents that have been explicitly muted. Muted agents will never send puppetry information.Default: empty|
Setting Parameters and Puppetry Behavior
Puppetry behavior is modified by POSTing to the puppetry cap. If the parameters are successfully changed the simulator will respond with a body identical to the HTTP get with the new parameters. When changing parameters, only those you wish to change are included in the posted LLSD body. Omitted parameters are left unchanged.
Transmitting, Receiving, and Local vs. Remote Echo
In order to transmit or receive puppetry data to the simulator the viewer must turn it on by posting a message to the puppetry cap. Setting transmit to true will allow the viewer to send realtime puppetry events to the simulator. Setting receive to true will allow the simulator to send puppetry events produced by other avatars to the viewer.
Normally, the simulator relays puppetry events to other agents within range and does not echo them back to the sender. Setting `echo_back` to true changes this behavior and the simulator will send the events back to the agent that produced them.
|Boolean||Controls whether the agent may transmit Puppetry data to the simulator. **true**: The simulator will accept and forward Puppetry events from this agent. **false**: The simulator will discard any Puppetry events sent from this agent.|
|Boolean||Controls whether this agent will receive Puppetry events from other avatars. **true**: The agent will receive Puppetry events as part of the AvatarAnimation message from the simulator during an interest list update. **false**: The agent will not receive Puppetry events from other avatars.|
|Boolean||Controls whether the agent will receive an echo of their own Puppetry events from the simulator. **true**: This agent's Puppetry events are echoed back as part of the interest list update. **false**: This agent does not receive their own Puppetry events.|
By default an agent will only receive events from agents that are within 25 meters of their avatar position. To change the default range include a `range` value in the posted body with the new value.
|Range||Real||Maximum range for puppetry data. Agents outside of this range will not exchange puppetry information.|
Subscriptions and Muting
A viewer may also request that puppetry data be sent from certain agents that may be out of range. To do this include an array of the Agent IDs that the viewer would like to subscribe to in the post body under the `subscribe` key. To cancel a subscription, post the agent IDs in an array called `unsubscribe`. A viewer may subscribe to at most 10 other agents at a time.
Muted agents will never send puppetry information to the viewer. Muting and unmuting is done by posting arrays of agent IDs to the simulator using the `mute` and `unmute` keys. A viewer may mute up to 100 other agents at a time.
|subscribe||Array of UUIDs||Explicitly subscribes to agents in the list. Subscribed agents will transmit puppetry data even when out of range.|
|unsubscribe||Array of UUIDs||Removes agents from the explicitly subscribed list.|
|mute||Array of UUIDs||Explicitly mute puppetry information from the listed avatars.|
|unmute||Array of UUIDs||Remove avatars from the mute list.|
Realtime Avatar Puppetry
The simulator receives and forwards puppetry events through the optional PhysicalAvatarEventList block in the AgentAnimation and the AvatarAnimation messages. The simulator will forward any received puppetry events to eligible agents on the next frame as part of the interest list update. The simulator will only process the most recent 5 puppetry event blocks, discarding older blocks in favor of newer ones.
Sending Puppetry Events to the Simulator
Puppetry events are sent to the server by packing them together into PhysicalAvatarEventList blocks and sending those blocks to the simulator as part of an AgentAnimation message. An event block may never be larger than the `event_size` value returned from the puppetry cap. Data sent beyond this threshold will be truncated. The viewer may send multiple blocks and multiple AgentAnimation message as frequently as they like. However the stream is lossy when overloaded; the simulator will discard older event blocks in favor of new ones.
Receiving Puppetry Events from the Simulator
The simulator sends puppetry events to receiving simulators in one or more optional PhysicalAvatarEventList in an AvatarAnimation message. These blocks should be decoded by the receiving viewer and fed into the inverse kinematics (IK) system to animate the avatar. The simulator will never send more than one AvatarAnimation message per frame. If there is insufficient space in the the message the oldest event blocks will be dropped.
PhysicalAvatarEventList Packing Format
The puppetry event block consists of a series of events that are to be replayed by viewers through the IK system.
- 32 bit: timestamp for the event
- 16 bit: number of joint events to follow
- 32 bit: size of event block.
- repeating blocks:
- 16 bit: Joint ID
- 8 bit: Event mask flag
- 0x01 = position is packed (three floats: xyz)
- 0x02 = reserved for: position is in parent frame when set (currently always in root-frame)
- 0x04 = orientation is packed (three floats: imaginary xyz part of quaternion xyzw, where w is always positive)
- 0x08 = orientation is in parent frame when set (else in root-frame)
- 0x10 = reserved for: scale is packed (three floats: xyz), but not yet supported
- 0x20 = reserved, unused
- 0x40 = reserved, unused
- 0x80 = "disable constraint"
- variable data as per mask: [12 bytes position] | [12 bytes orientation]
- future update will change this to be 6 bytes, F32 values packed to 16 bits