From b6651ce79017bc7c6d1df66757e26a74bacfc36f Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Mon, 26 Oct 2009 18:22:32 -0700 Subject: * Double the priority on avatar bake texture requests to get avatars rezzing in faster than the surrounding scene * Adds duplicate tracking for SceneObjectParts and ScenePresences to avoid sending out duplicate ImprovedTerseObjectUpdate packets --- .../Region/ClientStack/LindenUDP/LLClientView.cs | 18 ++++-- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 44 ++++++++++---- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 69 +++++++--------------- 3 files changed, 69 insertions(+), 62 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index edfb13c..31028b3 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -6756,11 +6756,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (OnRequestTexture != null) { TextureRequestArgs args = new TextureRequestArgs(); - args.RequestedAssetID = imageRequest.RequestImage[i].Image; - args.DiscardLevel = imageRequest.RequestImage[i].DiscardLevel; - args.PacketNumber = imageRequest.RequestImage[i].Packet; - args.Priority = imageRequest.RequestImage[i].DownloadPriority; + + RequestImagePacket.RequestImageBlock block = imageRequest.RequestImage[i]; + + args.RequestedAssetID = block.Image; + args.DiscardLevel = block.DiscardLevel; + args.PacketNumber = block.Packet; + args.Priority = block.DownloadPriority; args.requestSequence = imageRequest.Header.Sequence; + + // NOTE: This is not a built in part of the LLUDP protocol, but we double the + // priority of avatar textures to get avatars rezzing in faster than the + // surrounding scene + if ((ImageType)block.Type == ImageType.Baked) + args.Priority *= 2.0f; + //handlerTextureRequest = OnRequestTexture; //if (handlerTextureRequest != null) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index d84c35c..a87bde0 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -248,6 +248,12 @@ namespace OpenSim.Region.Framework.Scenes protected UUID m_uuid; protected Vector3 m_velocity; + protected Vector3 m_lastPosition; + protected Quaternion m_lastRotation; + protected Vector3 m_lastVelocity; + protected Vector3 m_lastAcceleration; + protected Vector3 m_lastAngularVelocity; + // TODO: Those have to be changed into persistent properties at some later point, // or sit-camera on vehicles will break on sim-crossing. private Vector3 m_cameraEyeOffset; @@ -2387,18 +2393,36 @@ if (m_shape != null) { /// public void SendScheduledUpdates() { - if (m_updateFlag == 1) //some change has been made so update the clients + const float VELOCITY_TOLERANCE = 0.01f; + const float POSITION_TOLERANCE = 10.0f; + + if (m_updateFlag == 1) { - AddTerseUpdateToAllAvatars(); - ClearUpdateSchedule(); + // Throw away duplicate or insignificant updates + if (RotationOffset != m_lastRotation || + Acceleration != m_lastAcceleration || + (Velocity - m_lastVelocity).Length() > VELOCITY_TOLERANCE || + (RotationalVelocity - m_lastAngularVelocity).Length() > VELOCITY_TOLERANCE || + (OffsetPosition - m_lastPosition).Length() > POSITION_TOLERANCE) + { + AddTerseUpdateToAllAvatars(); + ClearUpdateSchedule(); - // This causes the Scene to 'poll' physical objects every couple of frames - // bad, so it's been replaced by an event driven method. - //if ((ObjectFlags & (uint)PrimFlags.Physics) != 0) - //{ - // Only send the constant terse updates on physical objects! - //ScheduleTerseUpdate(); - //} + // This causes the Scene to 'poll' physical objects every couple of frames + // bad, so it's been replaced by an event driven method. + //if ((ObjectFlags & (uint)PrimFlags.Physics) != 0) + //{ + // Only send the constant terse updates on physical objects! + //ScheduleTerseUpdate(); + //} + + // Update the "last" values + m_lastPosition = OffsetPosition; + m_lastRotation = RotationOffset; + m_lastVelocity = Velocity; + m_lastAcceleration = Acceleration; + m_lastAngularVelocity = RotationalVelocity; + } } else { diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 67384fb..0ac5be0 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -93,12 +93,13 @@ namespace OpenSim.Region.Framework.Scenes public Vector3 lastKnownAllowedPosition; public bool sentMessageAboutRestrictedParcelFlyingDown; - + private Vector3 m_lastPosition; + private Quaternion m_lastRotation; + private Vector3 m_lastVelocity; private bool m_updateflag; private byte m_movementflag; private readonly List m_forcesList = new List(); - private short m_updateCount; private uint m_requestedSitTargetID; private UUID m_requestedSitTargetUUID = UUID.Zero; private SendCourseLocationsMethod m_sendCourseLocationsMethod; @@ -145,12 +146,9 @@ namespace OpenSim.Region.Framework.Scenes public string JID = string.Empty; // Agent moves with a PID controller causing a force to be exerted. - private bool m_newForce; private bool m_newCoarseLocations = true; private float m_health = 100f; - private Vector3 m_lastVelocity = Vector3.Zero; - // Default AV Height private float m_avHeight = 127.0f; @@ -158,16 +156,6 @@ namespace OpenSim.Region.Framework.Scenes protected ulong crossingFromRegion; private readonly Vector3[] Dir_Vectors = new Vector3[6]; - - /// - /// The avatar position last sent to clients - /// - private Vector3 lastPhysPos = Vector3.Zero; - - /// - /// The avatar body rotation last sent to clients - /// - private Quaternion lastPhysRot = Quaternion.Identity; // Position of agent's camera in world (region cordinates) protected Vector3 m_CameraCenter = Vector3.Zero; @@ -1123,18 +1111,18 @@ namespace OpenSim.Region.Framework.Scenes CameraConstraintActive = true; //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance); - Vector3 normal = Vector3.Normalize(new Vector3(0,0,collisionPoint.Z) - collisionPoint); + Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint); ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint))); } else { - if (((Util.GetDistanceTo(lastPhysPos, AbsolutePosition) > 0.02) - || (Util.GetDistanceTo(m_lastVelocity, m_velocity) > 0.02) - || lastPhysRot != m_bodyRot)) + if ((m_pos - m_lastPosition).Length() > 0.02f || + (m_velocity - m_lastVelocity).Length() > 0.02f || + m_bodyRot != m_lastRotation) { if (CameraConstraintActive) { - ControllingClient.SendCameraConstraint(new Vector4(0, 0.5f, 0.9f, -3000f)); + ControllingClient.SendCameraConstraint(new Vector4(0f, 0.5f, 0.9f, -3000f)); CameraConstraintActive = false; } } @@ -2373,6 +2361,9 @@ namespace OpenSim.Region.Framework.Scenes public override void Update() { + const float VELOCITY_TOLERANCE = 0.01f; + const float POSITION_TOLERANCE = 10.0f; + SendPrimUpdates(); if (m_newCoarseLocations) @@ -2383,28 +2374,17 @@ namespace OpenSim.Region.Framework.Scenes if (m_isChildAgent == false) { - if (m_newForce) // user movement 'forces' (ie commands to move) + // Throw away duplicate or insignificant updates + if (m_bodyRot != m_lastRotation || + (m_velocity - m_lastVelocity).Length() > VELOCITY_TOLERANCE || + (m_pos - m_lastPosition).Length() > POSITION_TOLERANCE) { SendTerseUpdateToAllClients(); - m_updateCount = 0; - } - else if (m_movementflag != 0) // scripted movement (?) - { - m_updateCount++; - if (m_updateCount > 3) - { - SendTerseUpdateToAllClients(); - m_updateCount = 0; - } - } - else if ((Util.GetDistanceTo(lastPhysPos, AbsolutePosition) > 0.02) - || (Util.GetDistanceTo(m_lastVelocity, m_velocity) > 0.02) - || lastPhysRot != m_bodyRot) - { - // Send Terse Update to all clients updates lastPhysPos and m_lastVelocity - // doing the above assures us that we know what we sent the clients last - SendTerseUpdateToAllClients(); - m_updateCount = 0; + + // Update the "last" values + m_lastPosition = m_pos; + m_lastRotation = m_bodyRot; + m_lastVelocity = m_velocity; } // followed suggestion from mic bowman. reversed the two lines below. @@ -2447,15 +2427,10 @@ namespace OpenSim.Region.Framework.Scenes public void SendTerseUpdateToAllClients() { m_perfMonMS = Environment.TickCount; - + m_scene.ForEachClient(SendTerseUpdateToClient); - m_lastVelocity = m_velocity; - lastPhysPos = AbsolutePosition; - lastPhysRot = m_bodyRot; - m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); - } public void SendCoarseLocations() @@ -3316,7 +3291,6 @@ namespace OpenSim.Region.Framework.Scenes /// public override void UpdateMovement() { - m_newForce = false; lock (m_forcesList) { if (m_forcesList.Count > 0) @@ -3338,7 +3312,6 @@ namespace OpenSim.Region.Framework.Scenes // Ignoring this causes no movement to be sent to the physics engine... // which when the scene is moving at 1 frame every 10 seconds, it doesn't really matter! } - m_newForce = true; m_forcesList.Clear(); } -- cgit v1.1