diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs')
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 231 |
1 files changed, 141 insertions, 90 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 2d337f1..2650be4 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -909,7 +909,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
909 | public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look) | 909 | public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look) |
910 | { | 910 | { |
911 | m_thisAgentUpdateArgs.CameraAtAxis.X = float.MinValue; | 911 | m_thisAgentUpdateArgs.CameraAtAxis.X = float.MinValue; |
912 | m_thisAgentUpdateArgs.ControlFlags = uint.MaxValue; | 912 | // m_thisAgentUpdateArgs.ControlFlags = uint.MaxValue; |
913 | m_thisAgentUpdateArgs.ControlFlags = 0; | ||
913 | 914 | ||
914 | AgentMovementCompletePacket mov = (AgentMovementCompletePacket)PacketPool.Instance.GetPacket(PacketType.AgentMovementComplete); | 915 | AgentMovementCompletePacket mov = (AgentMovementCompletePacket)PacketPool.Instance.GetPacket(PacketType.AgentMovementComplete); |
915 | mov.SimData.ChannelVersion = m_channelVersion; | 916 | mov.SimData.ChannelVersion = m_channelVersion; |
@@ -1375,73 +1376,125 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1375 | } | 1376 | } |
1376 | } | 1377 | } |
1377 | 1378 | ||
1379 | |||
1380 | // wind caching | ||
1381 | private static Dictionary<ulong,int> lastWindVersion = new Dictionary<ulong,int>(); | ||
1382 | private static Dictionary<ulong,List<LayerDataPacket>> lastWindPackets = | ||
1383 | new Dictionary<ulong,List<LayerDataPacket>>(); | ||
1384 | |||
1385 | |||
1378 | /// <summary> | 1386 | /// <summary> |
1379 | /// Send the wind matrix to the client | 1387 | /// Send the wind matrix to the client |
1380 | /// </summary> | 1388 | /// </summary> |
1381 | /// <param name="windSpeeds">16x16 array of wind speeds</param> | 1389 | /// <param name="windSpeeds">16x16 array of wind speeds</param> |
1382 | public virtual void SendWindData(Vector2[] windSpeeds) | 1390 | public virtual void SendWindData(int version, Vector2[] windSpeeds) |
1383 | { | 1391 | { |
1384 | Util.FireAndForget(DoSendWindData, windSpeeds, "LLClientView.SendWindData"); | 1392 | // Vector2[] windSpeeds = (Vector2[])o; |
1385 | } | 1393 | |
1394 | ulong handle = this.Scene.RegionInfo.RegionHandle; | ||
1395 | bool isNewData; | ||
1396 | lock(lastWindPackets) | ||
1397 | { | ||
1398 | if(!lastWindVersion.ContainsKey(handle) || | ||
1399 | !lastWindPackets.ContainsKey(handle)) | ||
1400 | { | ||
1401 | lastWindVersion[handle] = 0; | ||
1402 | lastWindPackets[handle] = new List<LayerDataPacket>(); | ||
1403 | isNewData = true; | ||
1404 | } | ||
1405 | else | ||
1406 | isNewData = lastWindVersion[handle] != version; | ||
1407 | } | ||
1386 | 1408 | ||
1387 | /// <summary> | 1409 | if(isNewData) |
1388 | /// Send the cloud matrix to the client | 1410 | { |
1389 | /// </summary> | 1411 | TerrainPatch[] patches = new TerrainPatch[2]; |
1390 | /// <param name="windSpeeds">16x16 array of cloud densities</param> | 1412 | patches[0] = new TerrainPatch { Data = new float[16 * 16] }; |
1391 | public virtual void SendCloudData(float[] cloudDensity) | 1413 | patches[1] = new TerrainPatch { Data = new float[16 * 16] }; |
1392 | { | ||
1393 | Util.FireAndForget(DoSendCloudData, cloudDensity, "LLClientView.SendCloudData"); | ||
1394 | } | ||
1395 | 1414 | ||
1396 | /// <summary> | 1415 | for (int x = 0; x < 16 * 16; x++) |
1397 | /// Send wind layer information to the client. | 1416 | { |
1398 | /// </summary> | 1417 | patches[0].Data[x] = windSpeeds[x].X; |
1399 | /// <param name="o"></param> | 1418 | patches[1].Data[x] = windSpeeds[x].Y; |
1400 | private void DoSendWindData(object o) | 1419 | } |
1401 | { | ||
1402 | Vector2[] windSpeeds = (Vector2[])o; | ||
1403 | TerrainPatch[] patches = new TerrainPatch[2]; | ||
1404 | patches[0] = new TerrainPatch { Data = new float[16 * 16] }; | ||
1405 | patches[1] = new TerrainPatch { Data = new float[16 * 16] }; | ||
1406 | 1420 | ||
1407 | for (int x = 0; x < 16 * 16; x++) | 1421 | // neither we or viewers have extended wind |
1408 | { | 1422 | byte layerType = (byte)TerrainPatch.LayerType.Wind; |
1409 | patches[0].Data[x] = windSpeeds[x].X; | ||
1410 | patches[1].Data[x] = windSpeeds[x].Y; | ||
1411 | } | ||
1412 | 1423 | ||
1413 | // neither we or viewers have extended wind | 1424 | LayerDataPacket layerpack = |
1414 | byte layerType = (byte)TerrainPatch.LayerType.Wind; | 1425 | OpenSimTerrainCompressor.CreateLayerDataPacketStandardSize( |
1426 | patches, layerType); | ||
1427 | layerpack.Header.Zerocoded = true; | ||
1428 | lock(lastWindPackets) | ||
1429 | { | ||
1430 | lastWindPackets[handle].Clear(); | ||
1431 | lastWindPackets[handle].Add(layerpack); | ||
1432 | lastWindVersion[handle] = version; | ||
1433 | } | ||
1434 | } | ||
1415 | 1435 | ||
1416 | LayerDataPacket layerpack = OpenSimTerrainCompressor.CreateLayerDataPacketStandardSize(patches, layerType); | 1436 | lock(lastWindPackets) |
1417 | layerpack.Header.Zerocoded = true; | 1437 | foreach(LayerDataPacket pkt in lastWindPackets[handle]) |
1418 | OutPacket(layerpack, ThrottleOutPacketType.Wind); | 1438 | OutPacket(pkt, ThrottleOutPacketType.Wind); |
1419 | } | 1439 | } |
1420 | 1440 | ||
1441 | // cloud caching | ||
1442 | private static Dictionary<ulong,int> lastCloudVersion = new Dictionary<ulong,int>(); | ||
1443 | private static Dictionary<ulong,List<LayerDataPacket>> lastCloudPackets = | ||
1444 | new Dictionary<ulong,List<LayerDataPacket>>(); | ||
1445 | |||
1421 | /// <summary> | 1446 | /// <summary> |
1422 | /// Send cloud layer information to the client. | 1447 | /// Send the cloud matrix to the client |
1423 | /// </summary> | 1448 | /// </summary> |
1424 | /// <param name="o"></param> | 1449 | /// <param name="windSpeeds">16x16 array of cloud densities</param> |
1425 | private void DoSendCloudData(object o) | 1450 | public virtual void SendCloudData(int version, float[] cloudDensity) |
1426 | { | 1451 | { |
1427 | float[] cloudCover = (float[])o; | 1452 | ulong handle = this.Scene.RegionInfo.RegionHandle; |
1428 | TerrainPatch[] patches = new TerrainPatch[1]; | 1453 | bool isNewData; |
1429 | patches[0] = new TerrainPatch(); | 1454 | lock(lastWindPackets) |
1430 | patches[0].Data = new float[16 * 16]; | 1455 | { |
1456 | if(!lastCloudVersion.ContainsKey(handle) || | ||
1457 | !lastCloudPackets.ContainsKey(handle)) | ||
1458 | { | ||
1459 | lastCloudVersion[handle] = 0; | ||
1460 | lastCloudPackets[handle] = new List<LayerDataPacket>(); | ||
1461 | isNewData = true; | ||
1462 | } | ||
1463 | else | ||
1464 | isNewData = lastCloudVersion[handle] != version; | ||
1465 | } | ||
1431 | 1466 | ||
1432 | for (int y = 0; y < 16; y++) | 1467 | if(isNewData) |
1433 | { | 1468 | { |
1434 | for (int x = 0; x < 16; x++) | 1469 | TerrainPatch[] patches = new TerrainPatch[1]; |
1470 | patches[0] = new TerrainPatch(); | ||
1471 | patches[0].Data = new float[16 * 16]; | ||
1472 | |||
1473 | for (int y = 0; y < 16; y++) | ||
1474 | { | ||
1475 | for (int x = 0; x < 16; x++) | ||
1476 | { | ||
1477 | patches[0].Data[y * 16 + x] = cloudDensity[y * 16 + x]; | ||
1478 | } | ||
1479 | } | ||
1480 | // neither we or viewers have extended clouds | ||
1481 | byte layerType = (byte)TerrainPatch.LayerType.Cloud; | ||
1482 | |||
1483 | LayerDataPacket layerpack = | ||
1484 | OpenSimTerrainCompressor.CreateLayerDataPacketStandardSize( | ||
1485 | patches, layerType); | ||
1486 | layerpack.Header.Zerocoded = true; | ||
1487 | lock(lastCloudPackets) | ||
1435 | { | 1488 | { |
1436 | patches[0].Data[y * 16 + x] = cloudCover[y * 16 + x]; | 1489 | lastCloudPackets[handle].Clear(); |
1490 | lastCloudPackets[handle].Add(layerpack); | ||
1491 | lastCloudVersion[handle] = version; | ||
1437 | } | 1492 | } |
1438 | } | 1493 | } |
1439 | // neither we or viewers have extended clouds | ||
1440 | byte layerType = (byte)TerrainPatch.LayerType.Cloud; | ||
1441 | 1494 | ||
1442 | LayerDataPacket layerpack = OpenSimTerrainCompressor.CreateLayerDataPacketStandardSize(patches, layerType); | 1495 | lock(lastCloudPackets) |
1443 | layerpack.Header.Zerocoded = true; | 1496 | foreach(LayerDataPacket pkt in lastCloudPackets[handle]) |
1444 | OutPacket(layerpack, ThrottleOutPacketType.Cloud); | 1497 | OutPacket(pkt, ThrottleOutPacketType.Cloud); |
1445 | } | 1498 | } |
1446 | 1499 | ||
1447 | /// <summary> | 1500 | /// <summary> |
@@ -6144,27 +6197,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6144 | /// <param name='x'></param> | 6197 | /// <param name='x'></param> |
6145 | private bool CheckAgentMovementUpdateSignificance(AgentUpdatePacket.AgentDataBlock x) | 6198 | private bool CheckAgentMovementUpdateSignificance(AgentUpdatePacket.AgentDataBlock x) |
6146 | { | 6199 | { |
6147 | float qdelta1 = Math.Abs(Quaternion.Dot(x.BodyRotation, m_thisAgentUpdateArgs.BodyRotation)); | 6200 | if( |
6148 | //qdelta2 = Math.Abs(Quaternion.Dot(x.HeadRotation, m_thisAgentUpdateArgs.HeadRotation)); | ||
6149 | |||
6150 | bool movementSignificant = | ||
6151 | (x.ControlFlags != m_thisAgentUpdateArgs.ControlFlags) // significant if control flags changed | 6201 | (x.ControlFlags != m_thisAgentUpdateArgs.ControlFlags) // significant if control flags changed |
6152 | || (x.ControlFlags != (byte)AgentManager.ControlFlags.NONE) // significant if user supplying any movement update commands | 6202 | || ((x.ControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0 && |
6203 | (x.ControlFlags & 0x3f8dfff) != 0) // we need to rotate the av on fly | ||
6153 | || (x.Flags != m_thisAgentUpdateArgs.Flags) // significant if Flags changed | 6204 | || (x.Flags != m_thisAgentUpdateArgs.Flags) // significant if Flags changed |
6154 | || (x.State != m_thisAgentUpdateArgs.State) // significant if Stats changed | 6205 | || (x.State != m_thisAgentUpdateArgs.State) // significant if Stats changed |
6155 | || (qdelta1 < QDELTABody) // significant if body rotation above(below cos) threshold | ||
6156 | // Ignoring head rotation altogether, because it's not being used for anything interesting up the stack | ||
6157 | // || (qdelta2 < QDELTAHead) // significant if head rotation above(below cos) threshold | ||
6158 | || (Math.Abs(x.Far - m_thisAgentUpdateArgs.Far) >= 32) // significant if far distance changed | 6206 | || (Math.Abs(x.Far - m_thisAgentUpdateArgs.Far) >= 32) // significant if far distance changed |
6159 | ; | 6207 | ) |
6160 | //if (movementSignificant) | 6208 | return true; |
6161 | //{ | 6209 | |
6162 | //m_log.DebugFormat("[LLCLIENTVIEW]: Bod {0} {1}", | 6210 | float qdelta1 = Math.Abs(Quaternion.Dot(x.BodyRotation, m_thisAgentUpdateArgs.BodyRotation)); |
6163 | // qdelta1, qdelta2); | 6211 | //qdelta2 = Math.Abs(Quaternion.Dot(x.HeadRotation, m_thisAgentUpdateArgs.HeadRotation)); |
6164 | //m_log.DebugFormat("[LLCLIENTVIEW]: St {0} {1} {2} {3}", | 6212 | |
6165 | // x.ControlFlags, x.Flags, x.Far, x.State); | 6213 | if( |
6166 | //} | 6214 | qdelta1 < QDELTABody // significant if body rotation above(below cos) threshold |
6167 | return movementSignificant; | 6215 | // Ignoring head rotation altogether, because it's not being used for anything interesting up the stack |
6216 | // || qdelta2 < QDELTAHead // significant if head rotation above(below cos) threshold | ||
6217 | ) | ||
6218 | return true; | ||
6219 | |||
6220 | return false; | ||
6168 | } | 6221 | } |
6169 | 6222 | ||
6170 | /// <summary> | 6223 | /// <summary> |
@@ -6175,33 +6228,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6175 | /// <param name='x'></param> | 6228 | /// <param name='x'></param> |
6176 | private bool CheckAgentCameraUpdateSignificance(AgentUpdatePacket.AgentDataBlock x) | 6229 | private bool CheckAgentCameraUpdateSignificance(AgentUpdatePacket.AgentDataBlock x) |
6177 | { | 6230 | { |
6178 | float vdelta1 = Vector3.Distance(x.CameraAtAxis, m_thisAgentUpdateArgs.CameraAtAxis); | 6231 | float vdelta = Vector3.Distance(x.CameraAtAxis, m_thisAgentUpdateArgs.CameraAtAxis); |
6179 | float vdelta2 = Vector3.Distance(x.CameraCenter, m_thisAgentUpdateArgs.CameraCenter); | 6232 | if((vdelta > VDELTA)) |
6180 | float vdelta3 = Vector3.Distance(x.CameraLeftAxis, m_thisAgentUpdateArgs.CameraLeftAxis); | 6233 | return true; |
6181 | float vdelta4 = Vector3.Distance(x.CameraUpAxis, m_thisAgentUpdateArgs.CameraUpAxis); | 6234 | |
6235 | vdelta = Vector3.Distance(x.CameraCenter, m_thisAgentUpdateArgs.CameraCenter); | ||
6236 | if((vdelta > VDELTA)) | ||
6237 | return true; | ||
6182 | 6238 | ||
6183 | bool cameraSignificant = | 6239 | vdelta = Vector3.Distance(x.CameraLeftAxis, m_thisAgentUpdateArgs.CameraLeftAxis); |
6184 | (vdelta1 > VDELTA) || | 6240 | if((vdelta > VDELTA)) |
6185 | (vdelta2 > VDELTA) || | 6241 | return true; |
6186 | (vdelta3 > VDELTA) || | ||
6187 | (vdelta4 > VDELTA) | ||
6188 | ; | ||
6189 | 6242 | ||
6190 | //if (cameraSignificant) | 6243 | vdelta = Vector3.Distance(x.CameraUpAxis, m_thisAgentUpdateArgs.CameraUpAxis); |
6191 | //{ | 6244 | if((vdelta > VDELTA)) |
6192 | //m_log.DebugFormat("[LLCLIENTVIEW]: Cam1 {0} {1}", | 6245 | return true; |
6193 | // x.CameraAtAxis, x.CameraCenter); | ||
6194 | //m_log.DebugFormat("[LLCLIENTVIEW]: Cam2 {0} {1}", | ||
6195 | // x.CameraLeftAxis, x.CameraUpAxis); | ||
6196 | //} | ||
6197 | 6246 | ||
6198 | return cameraSignificant; | 6247 | return false; |
6199 | } | 6248 | } |
6200 | 6249 | ||
6201 | private bool HandleAgentUpdate(IClientAPI sender, Packet packet) | 6250 | private bool HandleAgentUpdate(IClientAPI sender, Packet packet) |
6202 | { | 6251 | { |
6203 | // We got here, which means that something in agent update was significant | ||
6204 | |||
6205 | AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet; | 6252 | AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet; |
6206 | AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData; | 6253 | AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData; |
6207 | 6254 | ||
@@ -6212,10 +6259,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6212 | } | 6259 | } |
6213 | 6260 | ||
6214 | TotalAgentUpdates++; | 6261 | TotalAgentUpdates++; |
6262 | // dont let ignored updates pollute this throttles | ||
6263 | if(SceneAgent == null || SceneAgent.IsChildAgent || SceneAgent.IsInTransit) | ||
6264 | { | ||
6265 | // throttle reset is done at MoveAgentIntoRegion() | ||
6266 | // called by scenepresence on completemovement | ||
6267 | PacketPool.Instance.ReturnPacket(packet); | ||
6268 | return true; | ||
6269 | } | ||
6215 | 6270 | ||
6216 | bool movement = CheckAgentMovementUpdateSignificance(x); | 6271 | bool movement = CheckAgentMovementUpdateSignificance(x); |
6217 | bool camera = CheckAgentCameraUpdateSignificance(x); | 6272 | bool camera = CheckAgentCameraUpdateSignificance(x); |
6218 | 6273 | ||
6219 | // Was there a significant movement/state change? | 6274 | // Was there a significant movement/state change? |
6220 | if (movement) | 6275 | if (movement) |
6221 | { | 6276 | { |
@@ -6224,7 +6279,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6224 | m_thisAgentUpdateArgs.Far = x.Far; | 6279 | m_thisAgentUpdateArgs.Far = x.Far; |
6225 | m_thisAgentUpdateArgs.Flags = x.Flags; | 6280 | m_thisAgentUpdateArgs.Flags = x.Flags; |
6226 | m_thisAgentUpdateArgs.HeadRotation = x.HeadRotation; | 6281 | m_thisAgentUpdateArgs.HeadRotation = x.HeadRotation; |
6227 | // m_thisAgentUpdateArgs.SessionID = x.SessionID; | ||
6228 | m_thisAgentUpdateArgs.State = x.State; | 6282 | m_thisAgentUpdateArgs.State = x.State; |
6229 | 6283 | ||
6230 | UpdateAgent handlerAgentUpdate = OnAgentUpdate; | 6284 | UpdateAgent handlerAgentUpdate = OnAgentUpdate; |
@@ -6235,9 +6289,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6235 | 6289 | ||
6236 | if (handlerAgentUpdate != null) | 6290 | if (handlerAgentUpdate != null) |
6237 | OnAgentUpdate(this, m_thisAgentUpdateArgs); | 6291 | OnAgentUpdate(this, m_thisAgentUpdateArgs); |
6238 | 6292 | ||
6239 | handlerAgentUpdate = null; | ||
6240 | handlerPreAgentUpdate = null; | ||
6241 | } | 6293 | } |
6242 | 6294 | ||
6243 | // Was there a significant camera(s) change? | 6295 | // Was there a significant camera(s) change? |
@@ -6253,7 +6305,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6253 | if (handlerAgentCameraUpdate != null) | 6305 | if (handlerAgentCameraUpdate != null) |
6254 | handlerAgentCameraUpdate(this, m_thisAgentUpdateArgs); | 6306 | handlerAgentCameraUpdate(this, m_thisAgentUpdateArgs); |
6255 | 6307 | ||
6256 | handlerAgentCameraUpdate = null; | ||
6257 | } | 6308 | } |
6258 | 6309 | ||
6259 | PacketPool.Instance.ReturnPacket(packet); | 6310 | PacketPool.Instance.ReturnPacket(packet); |