aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/World/Cloud/CloudModule.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/CoreModules/World/Cloud/CloudModule.cs86
1 files changed, 61 insertions, 25 deletions
diff --git a/OpenSim/Region/CoreModules/World/Cloud/CloudModule.cs b/OpenSim/Region/CoreModules/World/Cloud/CloudModule.cs
index d217f36..a450dd6 100644
--- a/OpenSim/Region/CoreModules/World/Cloud/CloudModule.cs
+++ b/OpenSim/Region/CoreModules/World/Cloud/CloudModule.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Threading;
30using Mono.Addins; 31using Mono.Addins;
31using Nini.Config; 32using Nini.Config;
32using OpenMetaverse; 33using OpenMetaverse;
@@ -39,16 +40,20 @@ namespace OpenSim.Region.CoreModules.World
39 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "CloudModule")] 40 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "CloudModule")]
40 public class CloudModule : ICloudModule, INonSharedRegionModule 41 public class CloudModule : ICloudModule, INonSharedRegionModule
41 { 42 {
42// private static readonly log4net.ILog m_log 43// private static readonly log4net.ILog m_log
43// = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 44// = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
44 private uint m_frame = 0; 45 private uint m_frame = 0;
45 private int m_frameUpdateRate = 1000; 46 private int m_frameUpdateRate = 1000;
46 private Random m_rndnums = new Random(Environment.TickCount); 47 private Random m_rndnums;
47 private Scene m_scene = null; 48 private Scene m_scene = null;
48 private bool m_ready = false; 49 private bool m_ready = false;
49 private bool m_enabled = false; 50 private bool m_enabled = false;
50 private float m_cloudDensity = 1.0F; 51 private float m_cloudDensity = 1.0F;
51 private float[] cloudCover = new float[16 * 16]; 52 private float[] cloudCover = new float[16 * 16];
53 private int m_dataVersion;
54 private bool m_busy;
55 private object cloudlock = new object();
56
52 57
53 public void Initialise(IConfigSource config) 58 public void Initialise(IConfigSource config)
54 { 59 {
@@ -70,11 +75,17 @@ namespace OpenSim.Region.CoreModules.World
70 75
71 m_scene = scene; 76 m_scene = scene;
72 77
73 scene.EventManager.OnNewClient += CloudsToClient;
74 scene.RegisterModuleInterface<ICloudModule>(this); 78 scene.RegisterModuleInterface<ICloudModule>(this);
75 scene.EventManager.OnFrame += CloudUpdate; 79 int seed = Environment.TickCount;
80 seed += (int)(scene.RegionInfo.RegionLocX << 16);
81 seed += (int)(scene.RegionInfo.RegionLocY);
82 m_rndnums = new Random(seed);
76 83
77 GenerateCloudCover(); 84 GenerateCloudCover();
85 m_dataVersion = (int)m_scene.AllocateLocalId();
86
87 scene.EventManager.OnNewClient += CloudsToClient;
88 scene.EventManager.OnFrame += CloudUpdate;
78 89
79 m_ready = true; 90 m_ready = true;
80 } 91 }
@@ -89,7 +100,6 @@ namespace OpenSim.Region.CoreModules.World
89 m_scene.EventManager.OnNewClient -= CloudsToClient; 100 m_scene.EventManager.OnNewClient -= CloudsToClient;
90 m_scene.EventManager.OnFrame -= CloudUpdate; 101 m_scene.EventManager.OnFrame -= CloudUpdate;
91 m_scene.UnregisterModuleInterface<ICloudModule>(this); 102 m_scene.UnregisterModuleInterface<ICloudModule>(this);
92
93 m_scene = null; 103 m_scene = null;
94 } 104 }
95 105
@@ -127,7 +137,8 @@ namespace OpenSim.Region.CoreModules.World
127 137
128 if (cloudCover != null) 138 if (cloudCover != null)
129 { 139 {
130 cover = cloudCover[y * 16 + x]; 140 lock(cloudlock)
141 cover = cloudCover[y * 16 + x];
131 } 142 }
132 143
133 return cover; 144 return cover;
@@ -152,7 +163,7 @@ namespace OpenSim.Region.CoreModules.World
152 columnRight = 0; 163 columnRight = 0;
153 columnLeft = x - 1; 164 columnLeft = x - 1;
154 } 165 }
155 else 166 else
156 { 167 {
157 columnRight = x + 1; 168 columnRight = x + 1;
158 columnLeft = x - 1; 169 columnLeft = x - 1;
@@ -174,40 +185,65 @@ namespace OpenSim.Region.CoreModules.World
174 rowAbove = y + 1; 185 rowAbove = y + 1;
175 rowBelow = y - 1; 186 rowBelow = y - 1;
176 } 187 }
177 float neighborAverage = (cloudCover[rowBelow * 16 + columnLeft] + 188 float neighborAverage = (cloudCover[rowBelow * 16 + columnLeft] +
178 cloudCover[y * 16 + columnLeft] + 189 cloudCover[y * 16 + columnLeft] +
179 cloudCover[rowAbove * 16 + columnLeft] + 190 cloudCover[rowAbove * 16 + columnLeft] +
180 cloudCover[rowBelow * 16 + x] + 191 cloudCover[rowBelow * 16 + x] +
181 cloudCover[rowAbove * 16 + x] + 192 cloudCover[rowAbove * 16 + x] +
182 cloudCover[rowBelow * 16 + columnRight] + 193 cloudCover[rowBelow * 16 + columnRight] +
183 cloudCover[y * 16 + columnRight] + 194 cloudCover[y * 16 + columnRight] +
184 cloudCover[rowAbove * 16 + columnRight] + 195 cloudCover[rowAbove * 16 + columnRight] +
185 cloudCover[y * 16 + x]) / 9; 196 cloudCover[y * 16 + x]) / 9;
186 newCover[y * 16 + x] = ((neighborAverage / m_cloudDensity) + 0.175f) % 1.0f; 197 newCover[y * 16 + x] = ((neighborAverage / m_cloudDensity) + 0.175f) % 1.0f;
187 newCover[y * 16 + x] *= m_cloudDensity; 198 newCover[y * 16 + x] *= m_cloudDensity;
188 } 199 }
189 } 200 }
190 Array.Copy(newCover, cloudCover, 16 * 16); 201 Array.Copy(newCover, cloudCover, 16 * 16);
202 m_dataVersion++;
191 } 203 }
192 204
193 private void CloudUpdate() 205 private void CloudUpdate()
194 { 206 {
195 if (((m_frame++ % m_frameUpdateRate) != 0) || !m_ready || (m_cloudDensity == 0)) 207 if ((!m_ready || m_busy || m_cloudDensity == 0 ||
196 { 208 (m_frame++ % m_frameUpdateRate) != 0))
197 return; 209 return;
198 } 210
199 UpdateCloudCover(); 211 if(Monitor.TryEnter(cloudlock))
212 {
213 m_busy = true;
214 Util.FireAndForget(delegate
215 {
216 try
217 {
218 lock(cloudlock)
219 {
220 UpdateCloudCover();
221 m_scene.ForEachClient(delegate(IClientAPI client)
222 {
223 client.SendCloudData(m_dataVersion, cloudCover);
224 });
225 }
226 }
227 finally
228 {
229 m_busy = false;
230 }
231 },
232 null, "CloudModuleUpdate");
233 Monitor.Exit(cloudlock);
234 }
200 } 235 }
201 236
202 public void CloudsToClient(IClientAPI client) 237 public void CloudsToClient(IClientAPI client)
203 { 238 {
204 if (m_ready) 239 if (m_ready)
205 { 240 {
206 client.SendCloudData(cloudCover); 241 lock(cloudlock)
242 client.SendCloudData(m_dataVersion, cloudCover);
207 } 243 }
208 } 244 }
209 245
210 246
211 /// <summary> 247 /// <summary>
212 /// Calculate the cloud cover over the region. 248 /// Calculate the cloud cover over the region.
213 /// </summary> 249 /// </summary>