OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
CloudModule.cs
Go to the documentation of this file.
1 /*
2  * Copyright (c) Contributors, http://opensimulator.org/
3  * See CONTRIBUTORS.TXT for a full list of copyright holders.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the OpenSimulator Project nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 using System;
29 using System.Collections.Generic;
30 using Mono.Addins;
31 using Nini.Config;
32 using OpenMetaverse;
33 using OpenSim.Framework;
34 using OpenSim.Region.Framework.Interfaces;
35 using OpenSim.Region.Framework.Scenes;
36 
37 namespace OpenSim.Region.CoreModules.World
38 {
39  [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "CloudModule")]
41  {
42 // private static readonly log4net.ILog m_log
43 // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
44  private uint m_frame = 0;
45  private int m_frameUpdateRate = 1000;
46  private Random m_rndnums = new Random(Environment.TickCount);
47  private Scene m_scene = null;
48  private bool m_ready = false;
49  private bool m_enabled = false;
50  private float m_cloudDensity = 1.0F;
51  private float[] cloudCover = new float[16 * 16];
52 
53  public void Initialise(IConfigSource config)
54  {
55  IConfig cloudConfig = config.Configs["Cloud"];
56 
57  if (cloudConfig != null)
58  {
59  m_enabled = cloudConfig.GetBoolean("enabled", false);
60  m_cloudDensity = cloudConfig.GetFloat("density", 0.5F);
61  m_frameUpdateRate = cloudConfig.GetInt("cloud_update_rate", 1000);
62  }
63 
64  }
65 
66  public void AddRegion(Scene scene)
67  {
68  if (!m_enabled)
69  return;
70 
71  m_scene = scene;
72 
73  scene.EventManager.OnNewClient += CloudsToClient;
74  scene.RegisterModuleInterface<ICloudModule>(this);
75  scene.EventManager.OnFrame += CloudUpdate;
76 
77  GenerateCloudCover();
78 
79  m_ready = true;
80  }
81 
82  public void RemoveRegion(Scene scene)
83  {
84  if (!m_enabled)
85  return;
86 
87  m_ready = false;
88  // Remove our hooks
89  m_scene.EventManager.OnNewClient -= CloudsToClient;
90  m_scene.EventManager.OnFrame -= CloudUpdate;
91  m_scene.UnregisterModuleInterface<ICloudModule>(this);
92 
93  m_scene = null;
94  }
95 
96  public void RegionLoaded(Scene scene)
97  {
98  }
99 
100  public void PostInitialise()
101  {
102  }
103 
104  public void Close()
105  {
106  }
107 
108  public string Name
109  {
110  get { return "CloudModule"; }
111  }
112 
113  public Type ReplaceableInterface
114  {
115  get { return null; }
116  }
117 
118  public float CloudCover(int x, int y, int z)
119  {
120  float cover = 0f;
121  x /= 16;
122  y /= 16;
123  if (x < 0) x = 0;
124  if (x > 15) x = 15;
125  if (y < 0) y = 0;
126  if (y > 15) y = 15;
127 
128  if (cloudCover != null)
129  {
130  cover = cloudCover[y * 16 + x];
131  }
132 
133  return cover;
134  }
135 
136  private void UpdateCloudCover()
137  {
138  float[] newCover = new float[16 * 16];
139  int rowAbove = new int();
140  int rowBelow = new int();
141  int columnLeft = new int();
142  int columnRight = new int();
143  for (int x = 0; x < 16; x++)
144  {
145  if (x == 0)
146  {
147  columnRight = x + 1;
148  columnLeft = 15;
149  }
150  else if (x == 15)
151  {
152  columnRight = 0;
153  columnLeft = x - 1;
154  }
155  else
156  {
157  columnRight = x + 1;
158  columnLeft = x - 1;
159  }
160  for (int y = 0; y< 16; y++)
161  {
162  if (y == 0)
163  {
164  rowAbove = y + 1;
165  rowBelow = 15;
166  }
167  else if (y == 15)
168  {
169  rowAbove = 0;
170  rowBelow = y - 1;
171  }
172  else
173  {
174  rowAbove = y + 1;
175  rowBelow = y - 1;
176  }
177  float neighborAverage = (cloudCover[rowBelow * 16 + columnLeft] +
178  cloudCover[y * 16 + columnLeft] +
179  cloudCover[rowAbove * 16 + columnLeft] +
180  cloudCover[rowBelow * 16 + x] +
181  cloudCover[rowAbove * 16 + x] +
182  cloudCover[rowBelow * 16 + columnRight] +
183  cloudCover[y * 16 + columnRight] +
184  cloudCover[rowAbove * 16 + columnRight] +
185  cloudCover[y * 16 + x]) / 9;
186  newCover[y * 16 + x] = ((neighborAverage / m_cloudDensity) + 0.175f) % 1.0f;
187  newCover[y * 16 + x] *= m_cloudDensity;
188  }
189  }
190  Array.Copy(newCover, cloudCover, 16 * 16);
191  }
192 
193  private void CloudUpdate()
194  {
195  if (((m_frame++ % m_frameUpdateRate) != 0) || !m_ready || (m_cloudDensity == 0))
196  {
197  return;
198  }
199  UpdateCloudCover();
200  }
201 
202  public void CloudsToClient(IClientAPI client)
203  {
204  if (m_ready)
205  {
206  client.SendCloudData(cloudCover);
207  }
208  }
209 
210 
214  private void GenerateCloudCover()
215  {
216  for (int y = 0; y < 16; y++)
217  {
218  for (int x = 0; x < 16; x++)
219  {
220  cloudCover[y * 16 + x] = (float)(m_rndnums.NextDouble()); // 0 to 1
221  cloudCover[y * 16 + x] *= m_cloudDensity;
222  }
223  }
224  }
225  }
226 }
void AddRegion(Scene scene)
This is called whenever a Scene is added. For shared modules, this can happen several times...
Definition: CloudModule.cs:66
void RemoveRegion(Scene scene)
This is called whenever a Scene is removed. For shared modules, this can happen several times...
Definition: CloudModule.cs:82
float CloudCover(int x, int y, int z)
Retrieves the cloud density at the given region coordinates
Definition: CloudModule.cs:118
void RegionLoaded(Scene scene)
This will be called once for every scene loaded. In a shared module this will be multiple times in on...
Definition: CloudModule.cs:96
void Close()
This is the inverse to Initialise. After a Close(), this instance won't be usable anymore...
Definition: CloudModule.cs:104
void Initialise(IConfigSource config)
This is called to initialize the region module. For shared modules, this is called exactly once...
Definition: CloudModule.cs:53