aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs231
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);