diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 5f8d8f1ab8..90f0336869 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -1390,11 +1390,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// Send the cloud matrix to the client
///
/// 16x16 array of cloud densities
+/*
public virtual void SendCloudData(int version, float[] cloudDensity)
{
Util.FireAndForget(DoSendCloudData, cloudDensity, "LLClientView.SendCloudData");
}
-
+*/
// wind caching
private static int lastWindVersion = 0;
private static List lastWindPackets = new List();
@@ -1445,30 +1446,53 @@ namespace OpenSim.Region.ClientStack.LindenUDP
OutPacket(pkt, ThrottleOutPacketType.Wind);
}
+ // cloud caching
+ private static int lastCloudVersion = 0;
+ private static List lastCloudPackets = new List();
+
///
/// Send cloud layer information to the client.
///
///
- private void DoSendCloudData(object o)
+// private void DoSendCloudData(object o)
+ public virtual void SendCloudData(int version, float[] cloudDensity)
{
- float[] cloudCover = (float[])o;
- TerrainPatch[] patches = new TerrainPatch[1];
- patches[0] = new TerrainPatch();
- patches[0].Data = new float[16 * 16];
+// float[] cloudDensity = (float[])o;
+ bool isNewData;
+ lock(lastCloudPackets)
+ isNewData = lastCloudVersion != version;
- for (int y = 0; y < 16; y++)
+ if(isNewData)
{
- for (int x = 0; x < 16; x++)
+ TerrainPatch[] patches = new TerrainPatch[1];
+ patches[0] = new TerrainPatch();
+ patches[0].Data = new float[16 * 16];
+
+ for (int y = 0; y < 16; y++)
{
- patches[0].Data[y * 16 + x] = cloudCover[y * 16 + x];
+ for (int x = 0; x < 16; x++)
+ {
+ patches[0].Data[y * 16 + x] = cloudDensity[y * 16 + x];
+ }
+ }
+ // neither we or viewers have extended clouds
+ byte layerType = (byte)TerrainPatch.LayerType.Cloud;
+
+ LayerDataPacket layerpack =
+ OpenSimTerrainCompressor.CreateLayerDataPacketStandardSize(
+ patches, layerType);
+ layerpack.Header.Zerocoded = true;
+ lock(lastCloudPackets)
+ {
+ lastCloudPackets.Clear();
+ lastCloudPackets.Add(layerpack);
+ lastCloudVersion = version;
}
}
- // neither we or viewers have extended clouds
- byte layerType = (byte)TerrainPatch.LayerType.Cloud;
- LayerDataPacket layerpack = OpenSimTerrainCompressor.CreateLayerDataPacketStandardSize(patches, layerType);
- layerpack.Header.Zerocoded = true;
- OutPacket(layerpack, ThrottleOutPacketType.Cloud);
+ lock(lastCloudPackets)
+ foreach(LayerDataPacket pkt in lastCloudPackets)
+ OutPacket(pkt, ThrottleOutPacketType.Cloud);
}
///
diff --git a/OpenSim/Region/CoreModules/World/Cloud/CloudModule.cs b/OpenSim/Region/CoreModules/World/Cloud/CloudModule.cs
index f304307586..3c2884b385 100644
--- a/OpenSim/Region/CoreModules/World/Cloud/CloudModule.cs
+++ b/OpenSim/Region/CoreModules/World/Cloud/CloudModule.cs
@@ -27,6 +27,7 @@
using System;
using System.Collections.Generic;
+using System.Threading;
using Mono.Addins;
using Nini.Config;
using OpenMetaverse;
@@ -49,6 +50,10 @@ namespace OpenSim.Region.CoreModules.World
private bool m_enabled = false;
private float m_cloudDensity = 1.0F;
private float[] cloudCover = new float[16 * 16];
+ private int m_dataVersion;
+ private bool m_busy;
+ private object cloudlock = new object();
+
public void Initialise(IConfigSource config)
{
@@ -70,11 +75,13 @@ namespace OpenSim.Region.CoreModules.World
m_scene = scene;
- scene.EventManager.OnNewClient += CloudsToClient;
scene.RegisterModuleInterface(this);
- scene.EventManager.OnFrame += CloudUpdate;
GenerateCloudCover();
+ m_dataVersion = (int)m_scene.AllocateLocalId();
+
+ scene.EventManager.OnNewClient += CloudsToClient;
+ scene.EventManager.OnFrame += CloudUpdate;
m_ready = true;
}
@@ -89,7 +96,6 @@ namespace OpenSim.Region.CoreModules.World
m_scene.EventManager.OnNewClient -= CloudsToClient;
m_scene.EventManager.OnFrame -= CloudUpdate;
m_scene.UnregisterModuleInterface(this);
-
m_scene = null;
}
@@ -127,7 +133,8 @@ namespace OpenSim.Region.CoreModules.World
if (cloudCover != null)
{
- cover = cloudCover[y * 16 + x];
+ lock(cloudlock)
+ cover = cloudCover[y * 16 + x];
}
return cover;
@@ -188,22 +195,48 @@ namespace OpenSim.Region.CoreModules.World
}
}
Array.Copy(newCover, cloudCover, 16 * 16);
+ m_dataVersion++;
}
- private void CloudUpdate()
- {
- if (((m_frame++ % m_frameUpdateRate) != 0) || !m_ready || (m_cloudDensity == 0))
- {
- return;
- }
- UpdateCloudCover();
+ private void CloudUpdate()
+ {
+ if ((!m_ready || m_cloudDensity == 0 || (m_frame++ % m_frameUpdateRate) != 0))
+ {
+ return;
+ }
+
+ if(Monitor.TryEnter(cloudlock))
+ {
+ m_busy = true;
+ Util.FireAndForget(delegate
+ {
+ try
+ {
+ lock(cloudlock)
+ {
+ UpdateCloudCover();
+ m_scene.ForEachClient(delegate(IClientAPI client)
+ {
+ client.SendCloudData(m_dataVersion, cloudCover);
+ });
+ }
+ }
+ finally
+ {
+ m_busy = false;
+ }
+ },
+ null, "CloudModuleUpdate");
+ Monitor.Exit(cloudlock);
+ }
}
public void CloudsToClient(IClientAPI client)
{
if (m_ready)
{
- client.SendCloudData(0, cloudCover);
+ lock(cloudlock)
+ client.SendCloudData(m_dataVersion, cloudCover);
}
}
diff --git a/OpenSim/Region/CoreModules/World/Wind/WindModule.cs b/OpenSim/Region/CoreModules/World/Wind/WindModule.cs
index bc92582c30..95cf57d20d 100644
--- a/OpenSim/Region/CoreModules/World/Wind/WindModule.cs
+++ b/OpenSim/Region/CoreModules/World/Wind/WindModule.cs
@@ -425,7 +425,7 @@ namespace OpenSim.Region.CoreModules
try
{
GenWind();
- m_scene.ForEachRootClient(delegate(IClientAPI client)
+ m_scene.ForEachClient(delegate(IClientAPI client)
{
client.SendWindData(m_dataVersion, windSpeeds);
});