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/Code Map/ScenePresence
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/Code Map/ScenePresence = == Overview == OpenSim/Region/Framework/Scenes/ScenePresence.cs One ScenePresence instance exists per agent per region. It represents the avatar -- whether root (avatar is here) or child (avatar is elsewhere, this is a listening post for interest management). ScenePresence implements IScenePresence and EntityBase. ---- == Lifecycle States == Governed by ScenePresenceStateMachine. The critical flag for most code paths is IsChildAgent (bool). {| class="wikitable" ! State !! IsChildAgent !! Description |- | Child || true || Pre-seeded in neighbouring region. Tracks position updates, no physics, no full scene state. |- | Root || false || Avatar is present in this region. Full physics, full scene state, heartbeat participation. |- | Deleted || -- || IsDeleted set. Dispose() called. |} Transition from child to root happens in MakeRootAgent(), called from CompleteMovement(). Transition from root to child happens in MakeChildAgent(), called by EntityTransferModule on departure. See [[OpenSimulator Internals/Walkthroughs/Avatar Rez In Region]] for the full transition sequence on login. ---- == Constructor == ScenePresence(IClientAPI client, Scene world, AvatarAppearance appearance, PresenceType type) # Sets IsChildAgent = true. # Sets draw distance from client.StartFar, clamped to region MaxDrawDistance / DefaultDrawDistance. # Sets RegionHandle, ControllingClient, name fields, UUID, LocalId. # Fetches UserAccount -- sets m_userFlags and GodController god level. If no account found, god level 0. # Initialises ScenePresenceAnimator and MovementAnimationOverrides. # Sets AbsolutePosition from ControllingClient.StartPos. # Disables child updates and reprioritization (m_childUpdatesBusy = true, m_reprioritizationBusy = true) -- re-enabled after CompleteMovement. # Calls AdjustKnownSeeds() -- initialises m_knownChildRegions from CapsModule. # Calls RegisterToClientEvents() -- see Event Wiring below. # Sets Appearance from passed AvatarAppearance. # Constructs ScenePresenceStateMachine. # Calls ControllingClient.RefreshGroupMembership(). ---- == Event Wiring == RegisterToClientEvents() hooks the following on ControllingClient: {| class="wikitable" ! Event !! Handler |- | OnCompleteMovementToRegion || CompleteMovement() |- | OnAgentUpdate || HandleAgentUpdate() |- | OnAgentCameraUpdate || HandleAgentCamerasUpdate() |- | OnAgentRequestSit || HandleAgentRequestSit() |- | OnAgentSit || HandleAgentSit() |- | OnSetAlwaysRun || HandleSetAlwaysRun() |- | OnStartAnim || HandleStartAnim() |- | OnStopAnim || HandleStopAnim() |- | OnChangeAnim || avnHandleChangeAnim() |- | OnForceReleaseControls || HandleForceReleaseControls() |- | OnAutoPilotGo || MoveToTargetHandle() |- | OnRegionHandShakeReply || RegionHandShakeReply() |} All removed in RemoveClientEvents() on disposal. ---- == MakeRootAgent() == private bool MakeRootAgent(Vector3 pos, bool isFlying, ref Vector3 lookat) Called only from CompleteMovement(). Returns false if already root. # Acquires m_completeMovementLock. # Handles pending sit (ParentUUID set): resolves prim, re-seats avatar. # Sets IsChildAgent = false. # Updates RegionHandle. # Fires EventManager.TriggerSetRootAgentScene(). # If not sitting: #* Calls CheckAndAdjustLandingPoint_OS() or _SL() -- adjusts position for telehubs, parcel landing points, ban lines. #* Clamps position to region bounds. #* Raises Z to ground height + avatar half-height. #* If ViaLogin or ViaLocation flags: raycasts downward from PhysSearchHeight (300f) using RayFilterFlags.PrimsNonPhantomAgents to find surface, avoids placing avatar inside objects. #* Sets AbsolutePosition. #* Calls AddToPhysicalScene(isFlying). # Calls m_scene.SwapRootAgentCount(false, IsNPC). # Resets MovementFlags = 0. # Updates circuit: AuthenticateHandler.UpdateAgentChildStatus(circuitCode, false). # Fires EventManager.TriggerOnMakeRootAgent(this). Physics position search constants: * PhysSearchHeight = 300f * PhysMinSkipGap = 20f * PhysSkipGapDelta = 30f * PhysNumberCollisions = 30 ---- == MakeChildAgent() == public void MakeChildAgent(ulong newRegionHandle) Called by EntityTransferModule when avatar departs. # Resets m_updateAgentReceivedAfterTransferEvent. # Clears group information and cross-update flags. # Unhooks RegionHeartbeatEnd. # Sets IsChildAgent = true. # Calls m_scene.SwapRootAgentCount(true, IsNPC). # Calls RemoveFromPhysicalScene(). # Clears parcel tracking. # Sends kill packets to root presences that don't know the new region (won't receive the avatar as child). # Updates circuit: AuthenticateHandler.UpdateAgentChildStatus(circuitCode, true). # Fires EventManager.TriggerOnMakeChildAgent(this). ---- == CompleteMovement() == public void CompleteMovement(IClientAPI client, bool openChildAgents) Triggered by OnCompleteMovementToRegion event from viewer. * For teleports/crossings: calls WaitForUpdateAgent() -- waits up to 10 seconds for source region's UpdateAgent to arrive (sets m_originRegionID via CopyFrom()). * For real login (IsRealLogin() true): skips WaitForUpdateAgent(). * Calls MakeRootAgent(). * Sends RegionHandshake if not a crossing. * Calls ControllingClient.MoveAgentIntoRegion(). * Validates baked texture cache (AvatarFactory.ValidateBakedTextureCache()); queues appearance save if invalid. * Sends initial avatar data to all presences. * Sends appearance and animations to self and others. * For real login: calls Scene.AttachmentsModule.RezAttachments(this). * For crossing with carried attachments: restarts scripts, sends attachment updates. * For login: calls IFriendsModule.SendFriendsOnlineIfNeeded(). * Hooks RegionHeartbeatEnd for per-frame processing. IsRealLogin() check: (teleportFlags & (ViaLogin | ViaHGLogin)) == ViaLogin ---- == RegionHandShakeReply() / SendInitialData() == public void RegionHandShakeReply(IClientAPI client) private void SendInitialData() RegionHandShakeReply() sets NeedInitialData = 2 on receipt of viewer handshake reply. SendInitialData() is called from Update() when NeedInitialData > 0. It waits for: * ViewerFlags.SentSeeds to be set (caps seeds sent to viewer). * NeedInitialData incremented to 6 (several heartbeat frames for viewer to process seeds). Then fires async (Util.FireAndForget): * Releases source region via SimulationService.ReleaseAgent() if callback URI present. * Calls IEntityTransferModule.CloseOldChildAgents(). * Sends terrain layer data if not a teleport. * Sends parcel info. * Sends full avatar updates for all other root presences (SendOtherAgentsAvatarFullToMe()). * Sends ObjectUpdate packets for all scene objects -- full updates or cache probes depending on ViewerFlags. * Calls IEntityTransferModule.EnableChildAgents() -- seeds neighbouring regions. * Sets m_childUpdatesBusy = false. ---- == Update() == Called each heartbeat frame from Scene.Update() for every ScenePresence. * If NeedInitialData > 0: calls SendInitialData() and returns. * If IsChildAgent or IsInTransit: returns. * Calls CheckForBorderCrossing(). * Handles MoveToTarget autopilot updates. * Handles delayed stop. * If avatar size changed: sends avatar data to all agents. * If position, velocity, rotation, or collision plane changed beyond tolerance: calls SendTerseUpdateToAllClients(). * Calls CheckForSignificantMovement(). ---- == Physical Scene == AddToPhysicalScene(bool isFlying): * Calls PhysicsScene.AddAvatar() -- creates PhysicsActor. * Wires pa.OnCollisionUpdate β PhysicsCollisionUpdate(). * Wires pa.OnOutOfBounds β OutOfBoundsCall(). * Sets PhysicsActor = pa. RemoveFromPhysicalScene(): * Interlocked.Exchange to null (thread-safe). * Unwires collision and OOB events. * Calls PhysicsScene.RemoveAvatar(). ---- == Neighbour Region Tracking == m_knownChildRegions: Dictionary<ulong, string> -- regionHandle β seed cap URL. m_knownChildRegionsSizeInfo: Dictionary<ulong, spRegionSizeInfo> -- regionHandle β (sizeX, sizeY). Key methods: * AddNeighbourRegion() / RemoveNeighbourRegion() * GetChildAgentsToClose() -- computes which neighbours to close on departure, based on IsOutsideView() distance check (currently hardcoded 255 rather than RegionViewDistance). * CloseChildAgents() -- sends CloseChildAgentConnections to computed list, drops cap seeds. ---- == Sitting == HandleAgentRequestSit() β SendSitResponse() β HandleAgentSit() / PhysicsSit(). PhysicsSit() delegates to PhysicsScene.SitAvatar() with callback PhysicsSitResponse(). Falls back to legacy sit if physics engine doesn't support it. On sit: * RemoveFromPhysicalScene(). * ParentID = part.LocalId, ParentPart = part. * part.AddSittingAvatar(this). * Animator.SetMovementAnimations("SIT"). StandUp(): * Computes world position from sit offset and prim rotation. * Clears ParentID, ParentPart. * Calls AddToPhysicalScene() if addPhys true. * part.RemoveSittingAvatar(this). * Animator.SetMovementAnimations("STAND"). SIT_TARGET_ADJUSTMENT = (0, 0, 0.4f) -- empirically derived fudge factor matching SL behaviour (Mantis 1716). ---- == Parcel Visibility == ParcelHideThisAvatar: true if current parcel has SeeAVs = false. On parcel crossing (currentParcelUUID setter β ParcelCrossCheck()): * Computes which presences need kill packets (now hidden from them or they from us). * Computes which presences need view packets (now visible). * Sends kills and views accordingly. ---- == Child Agent Data Transfer == CopyTo(AgentData, isCrossUpdate): serialises full avatar state for transfer to destination region -- position, velocity, camera, appearance, animations, attachments, script controls, group info, friends online cache. CopyFrom(AgentData): deserialises on destination side. Sets m_originRegionID, which signals WaitForUpdateAgent() to unblock CompleteMovement(). UpdateChildAgent(AgentData): called on destination when source fires UpdateAgent. Calls CopyFrom() then sets m_updateAgentReceivedAfterTransferEvent. UpdateChildAgent(AgentPosition): lightweight position-only update for child agent interest management. Adjusts position by region offset, updates throttles with distance-based scaling factor. ---- == Movement == HandleAgentUpdate(): main movement handler. Processes AgentUpdateArgs from viewer each packet. * Drops updates where IsChildAgent or IsInTransit. * Updates DrawDistance, HideTitle, MuteCollisions, mouse state, State byte. * Computes movement vector from control flags. * Calls AddNewMovement() β sets PhysicsActor.TargetVelocity. * Calls Animator.UpdateMovementAnimations(). * Calls SendControlsToScripts() -- fires EventManager.TriggerControlEvent for scripted control listeners. Autopilot: MoveToTarget() / HandleMoveToTargetUpdate() -- PID-style movement toward a target position, used by llMoveToTarget() and parcel enforcement. Border crossing detection: CheckForBorderCrossing() -- projects position by velocity * FrameTime, if outside region bounds calls CrossToNewRegion() β Scene.CrossAgentToNewRegion(). ---- == Attachment Management == m_attachments: List<SceneObjectGroup>, locked on AttachmentsSyncLock. AddAttachment() / RemoveAttachment() / GetAttachments() / ClearAttachments(). SendAttachmentsToAgentNF(): sends terse update then full updates for all attachments to a specific presence. SendAttachmentScheduleUpdate(): sends pending flagged updates to self and all visible presences. ---- == Animation == Animator: ScenePresenceAnimator -- manages animation state machine. Overrides: MovementAnimationOverrides -- server-side animation override pairs. HandleStartAnim() / HandleStopAnim() / avnHandleChangeAnim(): viewer-initiated animation control. RegionHeartbeatEnd hook: calls Animator.UpdateMovementAnimations() every 2 frames when root and not sitting. ---- == Significant Movement == CheckForSignificantMovement(): * MOVEMENT (0.25f sq) threshold: fires EventManager.TriggerOnClientMovement(). * SIGNIFICANT_MOVEMENT (16.0f sq) threshold: fires EventManager.TriggerSignificantClientMovement(). * CHILDAGENTSCHECK_MOVEMENT (1024f sq / 32m) threshold: calls IEntityTransferModule.EnableChildAgents() to update neighbour seeds. * CHILDUPDATES_MOVEMENT (100f sq): sends AgentPosition updates to known child regions. ---- == Key Constants == {| class="wikitable" ! Constant !! Value !! Purpose |- | MOVEMENT || 0.25f || Minimum movement to trigger client movement event (sq distance) |- | SIGNIFICANT_MOVEMENT || 16.0f || Minimum movement to trigger significant movement event (sq distance) |- | CHILDUPDATES_MOVEMENT || 100.0f || Minimum movement to send child agent position update (sq distance) |- | CHILDAGENTSCHECK_MOVEMENT || 1024.0f || Minimum movement to recheck neighbour child agents (sq distance, ~32m) |- | CHILDUPDATES_TIME || 2000f || Minimum ms between child agent updates |- | SIT_TARGET_ADJUSTMENT || (0,0,0.4f) || Sit target fudge factor matching SL (Mantis 1716) |- | PhysSearchHeight || 300f || Ray cast start height for spawn position search |- | PhysMinSkipGap || 20f || Minimum gap between surfaces in spawn position search |- | AgentControlNormalVel || 4.096f || Normal walk speed multiplier |- | AgentControlMidVel || 0.6 * 4.096f || Slow walk speed multiplier |} ---- == Known Issues == * IncomingAttechments() typo in Scene.cs line 2976 and AttachmentsModule.cs line 384 (Mantis pending). * GetChildAgentsToClose() uses hardcoded 255 for view distance rather than RegionViewDistance -- comment in source acknowledges this. ---- == See Also == * [[OpenSimulator Internals/Code Map/Scene]] * [[OpenSimulator Internals/Code Map/LLClientView]] * [[OpenSimulator Internals/Code Map/LLUDP]] * [[OpenSimulator Internals/Walkthroughs/Avatar Rez In Region]] * [[OpenSimulator Internals/Walkthroughs/Avatar Transfer Between Regions]] * [[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/Code Map/ScenePresence
Add topic