Implement native agent movement and teleportation (#60)
This commit is contained in:
65
docs/agent-movement.md
Normal file
65
docs/agent-movement.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# Agent movement, camera, teleport, and region crossing
|
||||
|
||||
`AgentManager::movement` is backed by native Rust state and emits the same
|
||||
LLUDP messages as LibreMetaverse's C# `AgentMovement`. The 32 control flags keep
|
||||
their protocol bit positions. `ResetControlFlags` preserves away, fly,
|
||||
mouselook, and crouch (`UP_NEG`), and automatic reset happens only after an
|
||||
`AgentUpdate` was actually sent. Duplicate idle updates are limited to the same
|
||||
ten transmissions as the reference implementation.
|
||||
|
||||
The camera retains the reference `CoordinateFrame` behavior, including the
|
||||
public wrapper's deliberate axis mapping: `AtAxis` exposes frame Y and
|
||||
`LeftAxis` exposes frame X, while `LookDirection` writes the requested forward
|
||||
vector to frame X. Roll, pitch, yaw, heading, look-at, and orthonormalization
|
||||
are native floating-point operations. Non-finite inputs return the mapped
|
||||
argument error instead of placing invalid values on the wire.
|
||||
|
||||
## Update lifecycle
|
||||
|
||||
The update worker starts after a successful login only when
|
||||
`SendUpdatesRegularly` is enabled. It uses the configured
|
||||
`AgentUpdateInterval`, wakes immediately when that interval changes, pauses on
|
||||
disconnect, and is joined by `Dispose` or normal destruction. A condition variable
|
||||
drives cadence and shutdown, so the implementation neither polls nor
|
||||
uses arbitrary sleeps. Manual updates remain available when periodic updates
|
||||
are disabled. Both paths refuse to send before simulator movement/handshake
|
||||
completion, as required by their respective C# methods.
|
||||
|
||||
Locomotion methods send real packets: flying, crouching, jumping, standing,
|
||||
ground sitting, object sitting, always-run, FOV, and autopilot use
|
||||
`AgentUpdate`, `AgentRequestSit`, `AgentSit`, `SetAlwaysRun`, `AgentFOV`, and
|
||||
`GenericMessage` with the reference field layout and reliability choices.
|
||||
|
||||
## Teleports and simulator crossings
|
||||
|
||||
Landmark, location, named-region, and lure requests share a generation-tagged
|
||||
teleport waiter. UDP `TeleportStart`, `TeleportProgress`, `TeleportFailed`,
|
||||
`TeleportCancel`, `TeleportLocal`, and `TeleportFinish` packets, together with
|
||||
their CAPS finish/failure equivalents, update status before raising
|
||||
`TeleportProgress`. Finish, failure, cancellation, timeout, disposal, and a
|
||||
superseding request all resolve the waiter exactly once. Cancellation and
|
||||
timeouts are executor-driven and do not leave a task or callback registered.
|
||||
|
||||
`CrossedRegion` starts a bounded native state machine with the C# states and
|
||||
failure reasons. It connects the destination simulator, retries failed
|
||||
connections up to three times, waits for that simulator's
|
||||
`AgentMovementComplete`, restores the old simulator after rejection, timeout,
|
||||
or manual cancellation, disconnects a partial destination, and raises
|
||||
`RegionCrossed` after state mutation. `GetCrossingState`,
|
||||
`GetCrossingFailureReason`, `GetCrossingDetails`, `IsCrossing`, and
|
||||
`CancelCrossing` expose the same diagnostic surface. Crossing and periodic
|
||||
update threads use weak ownership, cancellation wakeups, and joined handles.
|
||||
|
||||
When `MultipleSims` is enabled, movement completion also snapshots presence,
|
||||
position, rotation, and update time per simulator. Velocity near a region edge
|
||||
raises `RegionCrossingPredicted` with the matching cardinal direction, and the
|
||||
reference child-agent request bookkeeping is maintained with its 30-second
|
||||
deduplication and two-minute expiry windows. Border-object visibility is
|
||||
tracked through `TrackObjectInSimulator`, `UntrackObjectInSimulator`, and
|
||||
`GetSimulatorsForObject`; disconnected simulator entries are pruned without
|
||||
holding locks while callbacks run.
|
||||
|
||||
Tests use paused Tokio time for teleport timeout/cancellation and loopback UDP
|
||||
fake grids for packet-level movement. They decode the emitted control flags,
|
||||
camera/FOV values, always-run state, and invariant-culture autopilot parameters
|
||||
rather than accepting method invocation alone as evidence.
|
||||
Reference in New Issue
Block a user