Improved avatar responsiveness.

avinationmerge
CasperW 2009-11-21 15:36:38 +01:00 committed by Melanie
parent 0844e5951c
commit 0149265ee8
6 changed files with 164 additions and 49 deletions

View File

@ -3121,7 +3121,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
objupdate.ObjectData[0] = CreateAvatarUpdateBlock(data); objupdate.ObjectData[0] = CreateAvatarUpdateBlock(data);
OutPacket(objupdate, ThrottleOutPacketType.Task); OutPacket(objupdate, ThrottleOutPacketType.Task);
} }
@ -3172,8 +3171,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue(); terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue();
} }
// HACK: Using the task category until the tiered reprioritization code is in OutPacket(terse, ThrottleOutPacketType.State);
OutPacket(terse, ThrottleOutPacketType.Task);
} }
public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)

View File

@ -571,23 +571,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
//Sorry, i know it's not optimal, but until the LL client //Sorry, i know it's not optimal, but until the LL client
//manages packets correctly and re-orders them as required, this is necessary. //manages packets correctly and re-orders them as required, this is necessary.
if (outgoingPacket.Type == PacketType.ImprovedTerseObjectUpdate
|| outgoingPacket.Type == PacketType.ChatFromSimulator
|| outgoingPacket.Type == PacketType.ObjectUpdate
|| outgoingPacket.Type == PacketType.LayerData)
{
sendSynchronous = true;
}
// Put the UDP payload on the wire // Put the UDP payload on the wire
if (sendSynchronous == true) if (outgoingPacket.Type == PacketType.ImprovedTerseObjectUpdate)
{ {
SyncBeginSend(buffer); SyncBeginPrioritySend(buffer, 2); // highest priority
}
else if (outgoingPacket.Type == PacketType.ObjectUpdate
|| outgoingPacket.Type == PacketType.ChatFromSimulator
|| outgoingPacket.Type == PacketType.LayerData)
{
SyncBeginPrioritySend(buffer, 1); // medium priority
} }
else else
{ {
AsyncBeginSend(buffer); SyncBeginPrioritySend(buffer, 0); // normal priority
} }
//AsyncBeginSend(buffer);
// Keep track of when this packet was sent out (right now) // Keep track of when this packet was sent out (right now)
outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue; outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue;
} }
@ -862,7 +864,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length); Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length);
AsyncBeginSend(buffer); SyncBeginPrioritySend(buffer, 1); //Setting this to a medium priority should help minimise resends
} }
private bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo) private bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo)

View File

@ -29,6 +29,7 @@ using System;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Threading; using System.Threading;
using System.Collections.Generic;
using log4net; using log4net;
namespace OpenMetaverse namespace OpenMetaverse
@ -52,12 +53,25 @@ namespace OpenMetaverse
/// <summary>Local IP address to bind to in server mode</summary> /// <summary>Local IP address to bind to in server mode</summary>
protected IPAddress m_localBindAddress; protected IPAddress m_localBindAddress;
/// <summary>
/// Standard queue for our outgoing SyncBeginPrioritySend
/// </summary>
private List<UDPPacketBuffer> m_standardQueue = new List<UDPPacketBuffer>();
/// <summary>
/// Prioritised queue for our outgoing SyncBeginPrioritySend
/// </summary>
private List<UDPPacketBuffer> m_priorityQueue = new List<UDPPacketBuffer>();
/// <summary>UDP socket, used in either client or server mode</summary> /// <summary>UDP socket, used in either client or server mode</summary>
private Socket m_udpSocket; private Socket m_udpSocket;
/// <summary>Flag to process packets asynchronously or synchronously</summary> /// <summary>Flag to process packets asynchronously or synchronously</summary>
private bool m_asyncPacketHandling; private bool m_asyncPacketHandling;
/// <summary>Are we currently sending data asynchronously?</summary>
private volatile bool m_sendingData = false;
/// <summary>The all important shutdown flag</summary> /// <summary>The all important shutdown flag</summary>
private volatile bool m_shutdownFlag = true; private volatile bool m_shutdownFlag = true;
@ -246,25 +260,48 @@ namespace OpenMetaverse
} }
} }
public void SyncBeginSend(UDPPacketBuffer buf) public void SyncBeginPrioritySend(UDPPacketBuffer buf, int Priority)
{ {
if (!m_shutdownFlag) if (!m_shutdownFlag)
{ {
if (!m_sendingData)
{
m_sendingData = true;
try try
{ {
m_udpSocket.SendTo( AsyncBeginSend(buf);
buf.Data,
0,
buf.DataLength,
SocketFlags.None,
buf.RemoteEndPoint);
} }
catch (SocketException) { } catch (SocketException) { }
catch (ObjectDisposedException) { } catch (ObjectDisposedException) { }
} }
else
{
if (Priority == 2)
{
lock (m_priorityQueue)
{
m_priorityQueue.Add(buf);
}
}
else
{
lock (m_standardQueue)
{
if (Priority != 0)
{
m_standardQueue.Insert(0, buf);
}
else
{
m_standardQueue.Add(buf);
}
}
}
}
}
} }
public void AsyncBeginSend(UDPPacketBuffer buf) private void AsyncBeginSend(UDPPacketBuffer buf)
{ {
if (!m_shutdownFlag) if (!m_shutdownFlag)
{ {
@ -288,8 +325,36 @@ namespace OpenMetaverse
{ {
try try
{ {
// UDPPacketBuffer buf = (UDPPacketBuffer)result.AsyncState;
m_udpSocket.EndSendTo(result); m_udpSocket.EndSendTo(result);
if (m_sendingData)
{
lock (m_priorityQueue)
{
if (m_priorityQueue.Count > 0)
{
UDPPacketBuffer buf = m_priorityQueue[0];
m_priorityQueue.RemoveAt(0);
AsyncBeginSend(buf);
}
else
{
lock (m_standardQueue)
{
if (m_standardQueue.Count > 0)
{
UDPPacketBuffer buf = m_standardQueue[0];
m_standardQueue.RemoveAt(0);
AsyncBeginSend(buf);
}
else
{
m_sendingData = false;
}
}
}
}
}
} }
catch (SocketException) { } catch (SocketException) { }
catch (ObjectDisposedException) { } catch (ObjectDisposedException) { }

View File

@ -156,8 +156,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation
Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix); Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix);
// Check control flags // Check control flags
bool heldForward = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS; bool heldForward = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS);
bool heldBack = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG; bool heldBack = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG);
bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS; bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS;
bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG; bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG;
//bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT; //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;

View File

@ -1164,16 +1164,16 @@ namespace OpenSim.Region.Framework.Scenes
// Check if any objects have reached their targets // Check if any objects have reached their targets
CheckAtTargets(); CheckAtTargets();
// Update SceneObjectGroups that have scheduled themselves for updates
// Objects queue their updates onto all scene presences
if (m_frame % m_update_objects == 0)
m_sceneGraph.UpdateObjectGroups();
// Run through all ScenePresences looking for updates // Run through all ScenePresences looking for updates
// Presence updates and queued object updates for each presence are sent to clients // Presence updates and queued object updates for each presence are sent to clients
if (m_frame % m_update_presences == 0) if (m_frame % m_update_presences == 0)
m_sceneGraph.UpdatePresences(); m_sceneGraph.UpdatePresences();
// Update SceneObjectGroups that have scheduled themselves for updates
// Objects queue their updates onto all scene presences
if (m_frame % m_update_objects == 0)
m_sceneGraph.UpdateObjectGroups();
int TempPhysicsMS2 = Environment.TickCount; int TempPhysicsMS2 = Environment.TickCount;
if ((m_frame % m_update_physics == 0) && m_physics_enabled) if ((m_frame % m_update_physics == 0) && m_physics_enabled)
m_sceneGraph.UpdatePreparePhysics(); m_sceneGraph.UpdatePreparePhysics();

View File

@ -144,7 +144,6 @@ namespace OpenSim.Region.Framework.Scenes
private int m_perfMonMS; private int m_perfMonMS;
private bool m_setAlwaysRun; private bool m_setAlwaysRun;
private bool m_forceFly; private bool m_forceFly;
private bool m_flyDisabled; private bool m_flyDisabled;
@ -166,7 +165,8 @@ namespace OpenSim.Region.Framework.Scenes
protected RegionInfo m_regionInfo; protected RegionInfo m_regionInfo;
protected ulong crossingFromRegion; protected ulong crossingFromRegion;
private readonly Vector3[] Dir_Vectors = new Vector3[6]; private readonly Vector3[] Dir_Vectors = new Vector3[9];
private bool m_isNudging = false;
// Position of agent's camera in world (region cordinates) // Position of agent's camera in world (region cordinates)
protected Vector3 m_CameraCenter; protected Vector3 m_CameraCenter;
@ -230,6 +230,8 @@ namespace OpenSim.Region.Framework.Scenes
DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG,
DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
} }
@ -714,22 +716,42 @@ namespace OpenSim.Region.Framework.Scenes
Dir_Vectors[3] = -Vector3.UnitY; //RIGHT Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
Dir_Vectors[4] = Vector3.UnitZ; //UP Dir_Vectors[4] = Vector3.UnitZ; //UP
Dir_Vectors[5] = -Vector3.UnitZ; //DOWN Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
Dir_Vectors[5] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
} }
private Vector3[] GetWalkDirectionVectors() private Vector3[] GetWalkDirectionVectors()
{ {
Vector3[] vector = new Vector3[6]; Vector3[] vector = new Vector3[9];
vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
vector[2] = Vector3.UnitY; //LEFT vector[2] = Vector3.UnitY; //LEFT
vector[3] = -Vector3.UnitY; //RIGHT vector[3] = -Vector3.UnitY; //RIGHT
vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge
return vector; return vector;
} }
private bool[] GetDirectionIsNudge()
{
bool[] isNudge = new bool[9];
isNudge[0] = false; //FORWARD
isNudge[1] = false; //BACK
isNudge[2] = false; //LEFT
isNudge[3] = false; //RIGHT
isNudge[4] = false; //UP
isNudge[5] = false; //DOWN
isNudge[6] = true; //FORWARD_NUDGE
isNudge[7] = true; //BACK_NUDGE
isNudge[8] = true; //DOWN_Nudge
return isNudge;
}
#endregion #endregion
/// <summary> /// <summary>
@ -1147,7 +1169,6 @@ namespace OpenSim.Region.Framework.Scenes
// // m_log.Debug("DEBUG: HandleAgentUpdate: child agent"); // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent");
// return; // return;
//} //}
m_perfMonMS = Environment.TickCount; m_perfMonMS = Environment.TickCount;
++m_movementUpdateCount; ++m_movementUpdateCount;
@ -1229,7 +1250,6 @@ namespace OpenSim.Region.Framework.Scenes
m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
} }
} }
lock (scriptedcontrols) lock (scriptedcontrols)
{ {
if (scriptedcontrols.Count > 0) if (scriptedcontrols.Count > 0)
@ -1261,7 +1281,6 @@ namespace OpenSim.Region.Framework.Scenes
{ {
return; return;
} }
if (m_allowMovement) if (m_allowMovement)
{ {
int i = 0; int i = 0;
@ -1289,6 +1308,11 @@ namespace OpenSim.Region.Framework.Scenes
update_rotation = true; update_rotation = true;
} }
//guilty until proven innocent..
bool Nudging = true;
//Basically, if there is at least one non-nudge control then we don't need
//to worry about stopping the avatar
if (m_parentID == 0) if (m_parentID == 0)
{ {
bool bAllowUpdateMoveToPosition = false; bool bAllowUpdateMoveToPosition = false;
@ -1303,6 +1327,12 @@ namespace OpenSim.Region.Framework.Scenes
else else
dirVectors = Dir_Vectors; dirVectors = Dir_Vectors;
bool[] isNudge = GetDirectionIsNudge();
foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
{ {
if (((uint)flags & (uint)DCF) != 0) if (((uint)flags & (uint)DCF) != 0)
@ -1312,6 +1342,10 @@ namespace OpenSim.Region.Framework.Scenes
try try
{ {
agent_control_v3 += dirVectors[i]; agent_control_v3 += dirVectors[i];
if (isNudge[i] == false)
{
Nudging = false;
}
} }
catch (IndexOutOfRangeException) catch (IndexOutOfRangeException)
{ {
@ -1373,6 +1407,9 @@ namespace OpenSim.Region.Framework.Scenes
// Ignore z component of vector // Ignore z component of vector
Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
LocalVectorToTarget2D.Normalize(); LocalVectorToTarget2D.Normalize();
//We're not nudging
Nudging = false;
agent_control_v3 += LocalVectorToTarget2D; agent_control_v3 += LocalVectorToTarget2D;
// update avatar movement flags. the avatar coordinate system is as follows: // update avatar movement flags. the avatar coordinate system is as follows:
@ -1450,7 +1487,7 @@ namespace OpenSim.Region.Framework.Scenes
// m_log.DebugFormat( // m_log.DebugFormat(
// "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
AddNewMovement(agent_control_v3, q); AddNewMovement(agent_control_v3, q, Nudging);
if (update_movementflag) if (update_movementflag)
Animator.UpdateMovementAnimations(); Animator.UpdateMovementAnimations();
@ -1886,7 +1923,7 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary> /// </summary>
/// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
/// <param name="rotation">The direction in which this avatar should now face. /// <param name="rotation">The direction in which this avatar should now face.
public void AddNewMovement(Vector3 vec, Quaternion rotation) public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
{ {
if (m_isChildAgent) if (m_isChildAgent)
{ {
@ -1960,7 +1997,7 @@ namespace OpenSim.Region.Framework.Scenes
// TODO: Add the force instead of only setting it to support multiple forces per frame? // TODO: Add the force instead of only setting it to support multiple forces per frame?
m_forceToApply = direc; m_forceToApply = direc;
m_isNudging = Nudging;
m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS);
} }
@ -1975,7 +2012,7 @@ namespace OpenSim.Region.Framework.Scenes
const float POSITION_TOLERANCE = 0.05f; const float POSITION_TOLERANCE = 0.05f;
//const int TIME_MS_TOLERANCE = 3000; //const int TIME_MS_TOLERANCE = 3000;
SendPrimUpdates();
if (m_newCoarseLocations) if (m_newCoarseLocations)
{ {
@ -2011,6 +2048,9 @@ namespace OpenSim.Region.Framework.Scenes
CheckForBorderCrossing(); CheckForBorderCrossing();
CheckForSignificantMovement(); // sends update to the modules. CheckForSignificantMovement(); // sends update to the modules.
} }
//Sending prim updates AFTER the avatar terse updates are sent
SendPrimUpdates();
} }
#endregion #endregion
@ -2864,14 +2904,24 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if (m_forceToApply.HasValue) if (m_forceToApply.HasValue)
{ {
Vector3 force = m_forceToApply.Value;
Vector3 force = m_forceToApply.Value;
m_updateflag = true; m_updateflag = true;
// movementvector = force;
Velocity = force; Velocity = force;
m_forceToApply = null; m_forceToApply = null;
} }
else
{
if (m_isNudging)
{
Vector3 force = Vector3.Zero;
m_updateflag = true;
Velocity = force;
m_isNudging = false;
}
}
} }
public override void SetText(string text, Vector3 color, double alpha) public override void SetText(string text, Vector3 color, double alpha)