aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/World/Sun/SunModule.cs
diff options
context:
space:
mode:
authorMelanie Thielker2009-03-13 23:45:02 +0000
committerMelanie Thielker2009-03-13 23:45:02 +0000
commitddbf81fa07aac8098d9fa8d979969fffd5436f75 (patch)
treed65b3b280a53fe74253af2bfeee9bf3944dfa10b /OpenSim/Region/CoreModules/World/Sun/SunModule.cs
parent* Support loading empty folders in an iar (diff)
downloadopensim-SC_OLD-ddbf81fa07aac8098d9fa8d979969fffd5436f75.zip
opensim-SC_OLD-ddbf81fa07aac8098d9fa8d979969fffd5436f75.tar.gz
opensim-SC_OLD-ddbf81fa07aac8098d9fa8d979969fffd5436f75.tar.bz2
opensim-SC_OLD-ddbf81fa07aac8098d9fa8d979969fffd5436f75.tar.xz
Thank you, mcortez, for a patch that fixes a number of long standing
issues with the sun module. Fixes Mantis #3295
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/CoreModules/World/Sun/SunModule.cs424
1 files changed, 233 insertions, 191 deletions
diff --git a/OpenSim/Region/CoreModules/World/Sun/SunModule.cs b/OpenSim/Region/CoreModules/World/Sun/SunModule.cs
index 7eb29f1..3c950c1 100644
--- a/OpenSim/Region/CoreModules/World/Sun/SunModule.cs
+++ b/OpenSim/Region/CoreModules/World/Sun/SunModule.cs
@@ -39,26 +39,51 @@ namespace OpenSim.Region.CoreModules
39{ 39{
40 public class SunModule : IRegionModule 40 public class SunModule : IRegionModule
41 { 41 {
42 /// <summary>
43 /// Note: Sun Hour can be a little deceaving. Although it's based on a 24 hour clock
44 /// it is not based on ~06:00 == Sun Rise. Rather it is based on 00:00 being sun-rise.
45 /// </summary>
46
42 47
43 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
44 49
45 private const double SeasonalTilt = 0.03 * Math.PI; // A daily shift of approximately 1.7188 degrees 50 //
46 private const double AverageTilt = -0.25 * Math.PI; // A 45 degree tilt 51 // Global Constants used to determine where in the sky the sun is
47 private const double SunCycle = 2.0D * Math.PI; // A perfect circle measured in radians 52 //
48 private const double SeasonalCycle = 2.0D * Math.PI; // Ditto 53 private const double m_SeasonalTilt = 0.03 * Math.PI; // A daily shift of approximately 1.7188 degrees
54 private const double m_AverageTilt = -0.25 * Math.PI; // A 45 degree tilt
55 private const double m_SunCycle = 2.0D * Math.PI; // A perfect circle measured in radians
56 private const double m_SeasonalCycle = 2.0D * Math.PI; // Ditto
49 57
50 // 58 //
51 // Per Region Values 59 // Per Region Values
52 // 60 //
53 61
54 private bool ready = false; 62 private bool ready = false;
63
64
65 // This solves a chick before the egg problem
66 // the local SunFixedHour and SunFixed variables MUST be updated
67 // at least once with the proper Region Settings before we start
68 // updating those region settings in GenSunPos()
69 private bool receivedEstateToolsSunUpdate = false;
55 70
56 // Configurable values 71 // Configurable values
57 private string m_mode = "SL"; 72 private string m_RegionMode = "SL";
58 private int m_frame_mod = 0; 73
59 private double m_day_length = 0; 74 // Sun's position information is updated and sent to clients every m_UpdateInterval frames
60 private int m_year_length = 0; 75 private int m_UpdateInterval = 0;
61 private double m_day_night = 0; 76
77 // Number of real time hours per virtual day
78 private double m_DayLengthHours = 0;
79
80 // Number of virtual days to a virtual year
81 private int m_YearLengthDays = 0;
82
83 // Ratio of Daylight hours to Night time hours. This is accomplished by shifting the
84 // sun's orbit above the horizon
85 private double m_RatioDayNightHoizonShift = 0;
86
62 // private double m_longitude = 0; 87 // private double m_longitude = 0;
63 // private double m_latitude = 0; 88 // private double m_latitude = 0;
64 // Configurable defaults Defaults close to SL 89 // Configurable defaults Defaults close to SL
@@ -66,7 +91,8 @@ namespace OpenSim.Region.CoreModules
66 private int d_frame_mod = 100; // Every 10 seconds (actually less) 91 private int d_frame_mod = 100; // Every 10 seconds (actually less)
67 private double d_day_length = 4; // A VW day is 4 RW hours long 92 private double d_day_length = 4; // A VW day is 4 RW hours long
68 private int d_year_length = 60; // There are 60 VW days in a VW year 93 private int d_year_length = 60; // There are 60 VW days in a VW year
69 private double d_day_night = 0.45; // axis offset: ratio of light-to-dark, approx 1:3 94 private double d_day_night = 0.5; // axis offset: Default Hoizon shift to try and closely match the sun model in LL Viewer
95
70 // private double d_longitude = -73.53; 96 // private double d_longitude = -73.53;
71 // private double d_latitude = 41.29; 97 // private double d_latitude = 41.29;
72 98
@@ -83,7 +109,7 @@ namespace OpenSim.Region.CoreModules
83 private double SunSpeed; // Rate of passage in radians/second 109 private double SunSpeed; // Rate of passage in radians/second
84 private double SeasonSpeed; // Rate of change for seasonal effects 110 private double SeasonSpeed; // Rate of change for seasonal effects
85 // private double HoursToRadians; // Rate of change for seasonal effects 111 // private double HoursToRadians; // Rate of change for seasonal effects
86 private long TicksOffset = 0; // seconds offset from UTC 112 private long TicksUTCOffset = 0; // seconds offset from UTC
87 // Calculated every update 113 // Calculated every update
88 private float OrbitalPosition; // Orbital placement at a point in time 114 private float OrbitalPosition; // Orbital placement at a point in time
89 private double HorizonShift; // Axis offset to skew day and night 115 private double HorizonShift; // Axis offset to skew day and night
@@ -97,58 +123,145 @@ namespace OpenSim.Region.CoreModules
97 private Vector3 Velocity = Vector3.Zero; 123 private Vector3 Velocity = Vector3.Zero;
98 private Quaternion Tilt = new Quaternion(1.0f, 0.0f, 0.0f, 0.0f); 124 private Quaternion Tilt = new Quaternion(1.0f, 0.0f, 0.0f, 0.0f);
99 125
100 private long LindenHourOffset = 0;
101 private bool sunFixed = false;
102 126
103 private Dictionary<UUID, ulong> m_rootAgents = new Dictionary<UUID, ulong>(); 127 // Used to fix the sun in the sky so it doesn't move based on current time
128 private bool m_SunFixed = false;
129 private float m_SunFixedHour = 0f;
130
131 private const int TICKS_PER_SECOND = 10000000;
132
133
104 134
105 // Current time in elapsed seconds since Jan 1st 1970 135 // Current time in elapsed seconds since Jan 1st 1970
106 private ulong CurrentTime 136 private ulong CurrentTime
107 { 137 {
108 get { 138 get
109 return (ulong)(((DateTime.Now.Ticks) - TicksToEpoch + TicksOffset + LindenHourOffset)/10000000); 139 {
140 return (ulong)(((DateTime.Now.Ticks) - TicksToEpoch + TicksUTCOffset) / TICKS_PER_SECOND);
110 } 141 }
111 } 142 }
112 143
113 private float GetLindenEstateHourFromCurrentTime() 144 // Time in seconds since UTC to use to calculate sun position.
145 ulong PosTime = 0;
146
147 /// <summary>
148 /// Calculate the sun's orbital position and its velocity.
149 /// </summary>
150 private void GenSunPos()
114 { 151 {
115 float ticksleftover = ((float)CurrentTime) % ((float)SecondsPerSunCycle); 152 // Time in seconds since UTC to use to calculate sun position.
153 PosTime = CurrentTime;
116 154
117 float hour = (24 * (ticksleftover / SecondsPerSunCycle)) + 6; 155 if (m_SunFixed)
156 {
157 // SunFixedHour represents the "hour of day" we would like
158 // It's represented in 24hr time, with 0 hour being sun-rise
159 // Because our day length is probably not 24hrs {LL is 6} we need to do a bit of math
118 160
119 return hour; 161 // Determine the current "day" from current time, so we can use "today"
120 } 162 // to determine Seasonal Tilt and what'not
121 163
122 private void SetTimeByLindenHour(float LindenHour) 164 // Integer math rounded is on purpose to drop fractional day, determines number
123 { 165 // of virtual days since Epoch
124 // Linden hour is 24 hours with a 6 hour offset. 6-30 166 PosTime = CurrentTime / SecondsPerSunCycle;
125 167
126 if (LindenHour - 6 == 0) 168 // Since we want number of seconds since Epoch, multiply back up
127 { 169 PosTime *= SecondsPerSunCycle;
128 LindenHourOffset = 0; 170
129 return; 171 // Then offset by the current Fixed Sun Hour
172 // Fixed Sun Hour needs to be scaled to reflect the user configured Seconds Per Sun Cycle
173 PosTime += (ulong)((m_SunFixedHour / 24.0) * (ulong)SecondsPerSunCycle);
130 } 174 }
131 175
132 // Remove LindenHourOffset to calculate it from LocalTime 176 TotalDistanceTravelled = SunSpeed * PosTime; // distance measured in radians
133 float ticksleftover = ((float)(((long)(CurrentTime * 10000000) - (long)LindenHourOffset)/ 10000000) % ((float)SecondsPerSunCycle)); 177
134 float hour = (24 * (ticksleftover / SecondsPerSunCycle)); 178 OrbitalPosition = (float)(TotalDistanceTravelled % m_SunCycle); // position measured in radians
179
180 // TotalDistanceTravelled += HoursToRadians-(0.25*Math.PI)*Math.Cos(HoursToRadians)-OrbitalPosition;
181 // OrbitalPosition = (float) (TotalDistanceTravelled%SunCycle);
182
183 SeasonalOffset = SeasonSpeed * PosTime; // Present season determined as total radians travelled around season cycle
184 Tilt.W = (float)(m_AverageTilt + (m_SeasonalTilt * Math.Sin(SeasonalOffset))); // Calculate seasonal orbital N/S tilt
185
186 // m_log.Debug("[SUN] Total distance travelled = "+TotalDistanceTravelled+", present position = "+OrbitalPosition+".");
187 // m_log.Debug("[SUN] Total seasonal progress = "+SeasonalOffset+", present tilt = "+Tilt.W+".");
188
189 // The sun rotates about the Z axis
190
191 Position.X = (float)Math.Cos(-TotalDistanceTravelled);
192 Position.Y = (float)Math.Sin(-TotalDistanceTravelled);
193 Position.Z = 0;
194
195 // For interest we rotate it slightly about the X access.
196 // Celestial tilt is a value that ranges .025
135 197
136 float offsethours = 0; 198 Position *= Tilt;
137 199
138 if (LindenHour - 6 > hour) 200 // Finally we shift the axis so that more of the
201 // circle is above the horizon than below. This
202 // makes the nights shorter than the days.
203
204 Position = Vector3.Normalize(Position);
205 Position.Z = Position.Z + (float)HorizonShift;
206 Position = Vector3.Normalize(Position);
207
208 // m_log.Debug("[SUN] Position("+Position.X+","+Position.Y+","+Position.Z+")");
209
210 Velocity.X = 0;
211 Velocity.Y = 0;
212 Velocity.Z = (float)SunSpeed;
213
214 // Correct angular velocity to reflect the seasonal rotation
215
216 Magnitude = Position.Length();
217 if (m_SunFixed)
139 { 218 {
140 offsethours = hour + ((LindenHour-6) - hour); 219 Velocity.X = 0;
220 Velocity.Y = 0;
221 Velocity.Z = 0;
222
141 } 223 }
142 else 224 else
143 { 225 {
144 offsethours = hour - (hour - (LindenHour - 6)); 226 Velocity = (Velocity * Tilt) * (1.0f / Magnitude);
227 }
228
229 // TODO: Decouple this, so we can get rid of Linden Hour info
230 // Update Region infor with new Sun Position and Hour
231 // set estate settings for region access to sun position
232 if (receivedEstateToolsSunUpdate)
233 {
234 m_scene.RegionInfo.RegionSettings.SunVector = Position;
235 m_scene.RegionInfo.RegionSettings.SunPosition = GetSunHourAsLindenSunHour();
145 } 236 }
146 //m_log.Debug("[OFFSET]: " + hour + " - " + LindenHour + " - " + offsethours.ToString()); 237 }
147 238
148 LindenHourOffset = (long)((float)offsethours * (36000000000/m_day_length)); 239 /// <summary>
149 m_log.Debug("[SUN]: Directive from the Estate Tools to set the sun phase to LindenHour " + GetLindenEstateHourFromCurrentTime().ToString()); 240 /// Used to calculate the "linden sun hour" which is from 6 to 30, with 6 being "sun rise"
241 /// on the left most end of the Sun Slider in the client.
242 /// TODO: Decouple this and send it closer to linden client code.
243 /// </summary>
244 private float GetCurrentTimeAsLindenSunHour()
245 {
246 float ticksleftover = ((float)CurrentTime) % ((float)SecondsPerSunCycle);
247
248 float hour = (24.0f * (ticksleftover / SecondsPerSunCycle)) + 6.0f;
249
250 return hour;
150 } 251 }
151 252
253 private float GetSunHourAsLindenSunHour()
254 {
255 if (m_SunFixed)
256 {
257 return m_SunFixedHour + 6;
258 }
259
260 return GetCurrentTimeAsLindenSunHour();
261 }
262
263 #region IRegion Methods
264
152 // Called immediately after the module is loaded for a given region 265 // Called immediately after the module is loaded for a given region
153 // i.e. Immediately after instance creation. 266 // i.e. Immediately after instance creation.
154 public void Initialise(Scene scene, IConfigSource config) 267 public void Initialise(Scene scene, IConfigSource config)
@@ -158,52 +271,52 @@ namespace OpenSim.Region.CoreModules
158 m_frame = 0; 271 m_frame = 0;
159 272
160 TimeZone local = TimeZone.CurrentTimeZone; 273 TimeZone local = TimeZone.CurrentTimeZone;
161 TicksOffset = local.GetUtcOffset(local.ToLocalTime(DateTime.Now)).Ticks; 274 TicksUTCOffset = local.GetUtcOffset(local.ToLocalTime(DateTime.Now)).Ticks;
162 m_log.Debug("[SUN]: localtime offset is " + TicksOffset); 275 m_log.Debug("[SUN]: localtime offset is " + TicksUTCOffset);
163 276
164 // Align ticks with Second Life 277 // Align ticks with Second Life
165 278
166 TicksToEpoch = new DateTime(1970,1,1).Ticks; 279 TicksToEpoch = new DateTime(1970, 1, 1).Ticks;
167 280
168 // Just in case they don't have the stanzas 281 // Just in case they don't have the stanzas
169 try 282 try
170 { 283 {
171 // Mode: determines how the sun is handled 284 // Mode: determines how the sun is handled
172 m_mode = config.Configs["Sun"].GetString("mode", d_mode); 285 m_RegionMode = config.Configs["Sun"].GetString("mode", d_mode);
173 // Mode: determines how the sun is handled 286 // Mode: determines how the sun is handled
174 // m_latitude = config.Configs["Sun"].GetDouble("latitude", d_latitude); 287 // m_latitude = config.Configs["Sun"].GetDouble("latitude", d_latitude);
175 // Mode: determines how the sun is handled 288 // Mode: determines how the sun is handled
176 // m_longitude = config.Configs["Sun"].GetDouble("longitude", d_longitude); 289 // m_longitude = config.Configs["Sun"].GetDouble("longitude", d_longitude);
177 // Year length in days 290 // Year length in days
178 m_year_length = config.Configs["Sun"].GetInt("year_length", d_year_length); 291 m_YearLengthDays = config.Configs["Sun"].GetInt("year_length", d_year_length);
179 // Day length in decimal hours 292 // Day length in decimal hours
180 m_day_length = config.Configs["Sun"].GetDouble("day_length", d_day_length); 293 m_DayLengthHours = config.Configs["Sun"].GetDouble("day_length", d_day_length);
181 // Day to Night Ratio 294 // Day to Night Ratio
182 m_day_night = config.Configs["Sun"].GetDouble("day_night_offset", d_day_night); 295 m_RatioDayNightHoizonShift = config.Configs["Sun"].GetDouble("day_night_offset", d_day_night);
183 // Update frequency in frames 296 // Update frequency in frames
184 m_frame_mod = config.Configs["Sun"].GetInt("update_interval", d_frame_mod); 297 m_UpdateInterval = config.Configs["Sun"].GetInt("update_interval", d_frame_mod);
185 } 298 }
186 catch (Exception e) 299 catch (Exception e)
187 { 300 {
188 m_log.Debug("[SUN]: Configuration access failed, using defaults. Reason: "+e.Message); 301 m_log.Debug("[SUN]: Configuration access failed, using defaults. Reason: " + e.Message);
189 m_mode = d_mode; 302 m_RegionMode = d_mode;
190 m_year_length = d_year_length; 303 m_YearLengthDays = d_year_length;
191 m_day_length = d_day_length; 304 m_DayLengthHours = d_day_length;
192 m_day_night = d_day_night; 305 m_RatioDayNightHoizonShift = d_day_night;
193 m_frame_mod = d_frame_mod; 306 m_UpdateInterval = d_frame_mod;
194 // m_latitude = d_latitude; 307 // m_latitude = d_latitude;
195 // m_longitude = d_longitude; 308 // m_longitude = d_longitude;
196 } 309 }
197 310
198 switch (m_mode) 311 switch (m_RegionMode)
199 { 312 {
200 case "T1": 313 case "T1":
201 default: 314 default:
202 case "SL": 315 case "SL":
203 // Time taken to complete a cycle (day and season) 316 // Time taken to complete a cycle (day and season)
204 317
205 SecondsPerSunCycle = (uint) (m_day_length * 60 * 60); 318 SecondsPerSunCycle = (uint) (m_DayLengthHours * 60 * 60);
206 SecondsPerYear = (uint) (SecondsPerSunCycle*m_year_length); 319 SecondsPerYear = (uint) (SecondsPerSunCycle*m_YearLengthDays);
207 320
208 // Ration of real-to-virtual time 321 // Ration of real-to-virtual time
209 322
@@ -212,29 +325,27 @@ namespace OpenSim.Region.CoreModules
212 // Speed of rotation needed to complete a cycle in the 325 // Speed of rotation needed to complete a cycle in the
213 // designated period (day and season) 326 // designated period (day and season)
214 327
215 SunSpeed = SunCycle/SecondsPerSunCycle; 328 SunSpeed = m_SunCycle/SecondsPerSunCycle;
216 SeasonSpeed = SeasonalCycle/SecondsPerYear; 329 SeasonSpeed = m_SeasonalCycle/SecondsPerYear;
217 330
218 // Horizon translation 331 // Horizon translation
219 332
220 HorizonShift = m_day_night; // Z axis translation 333 HorizonShift = m_RatioDayNightHoizonShift; // Z axis translation
221 // HoursToRadians = (SunCycle/24)*VWTimeRatio; 334 // HoursToRadians = (SunCycle/24)*VWTimeRatio;
222 335
223 // Insert our event handling hooks 336 // Insert our event handling hooks
224 337
225 scene.EventManager.OnFrame += SunUpdate; 338 scene.EventManager.OnFrame += SunUpdate;
226 scene.EventManager.OnMakeChildAgent += MakeChildAgent;
227 scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; 339 scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel;
228 scene.EventManager.OnClientClosed += ClientLoggedOut; 340 scene.EventManager.OnEstateToolsSunUpdate += EstateToolsSunUpdate;
229 scene.EventManager.OnEstateToolsTimeUpdate += EstateToolsTimeUpdate; 341 scene.EventManager.OnGetCurrentTimeAsLindenSunHour += GetCurrentTimeAsLindenSunHour;
230 scene.EventManager.OnGetSunLindenHour += GetLindenEstateHourFromCurrentTime;
231 342
232 ready = true; 343 ready = true;
233 344
234 m_log.Debug("[SUN]: Mode is "+m_mode); 345 m_log.Debug("[SUN]: Mode is " + m_RegionMode);
235 m_log.Debug("[SUN]: Initialization completed. Day is "+SecondsPerSunCycle+" seconds, and year is "+m_year_length+" days"); 346 m_log.Debug("[SUN]: Initialization completed. Day is " + SecondsPerSunCycle + " seconds, and year is " + m_YearLengthDays + " days");
236 m_log.Debug("[SUN]: Axis offset is "+m_day_night); 347 m_log.Debug("[SUN]: Axis offset is " + m_RatioDayNightHoizonShift);
237 m_log.Debug("[SUN]: Positional data updated every "+m_frame_mod+" frames"); 348 m_log.Debug("[SUN]: Positional data updated every " + m_UpdateInterval + " frames");
238 349
239 break; 350 break;
240 } 351 }
@@ -250,11 +361,9 @@ namespace OpenSim.Region.CoreModules
250 361
251 // Remove our hooks 362 // Remove our hooks
252 m_scene.EventManager.OnFrame -= SunUpdate; 363 m_scene.EventManager.OnFrame -= SunUpdate;
253 m_scene.EventManager.OnMakeChildAgent -= MakeChildAgent;
254 m_scene.EventManager.OnAvatarEnteringNewParcel -= AvatarEnteringParcel; 364 m_scene.EventManager.OnAvatarEnteringNewParcel -= AvatarEnteringParcel;
255 m_scene.EventManager.OnClientClosed -= ClientLoggedOut; 365 m_scene.EventManager.OnEstateToolsSunUpdate -= EstateToolsSunUpdate;
256 m_scene.EventManager.OnEstateToolsTimeUpdate -= EstateToolsTimeUpdate; 366 m_scene.EventManager.OnGetCurrentTimeAsLindenSunHour -= GetCurrentTimeAsLindenSunHour;
257 m_scene.EventManager.OnGetSunLindenHour -= GetLindenEstateHourFromCurrentTime;
258 } 367 }
259 368
260 public string Name 369 public string Name
@@ -266,171 +375,104 @@ namespace OpenSim.Region.CoreModules
266 { 375 {
267 get { return false; } 376 get { return false; }
268 } 377 }
378 #endregion
379
380 #region EventManager Events
269 381
270 public void SunToClient(IClientAPI client) 382 public void SunToClient(IClientAPI client)
271 { 383 {
272 if (m_mode != "T1") 384 if (m_RegionMode != "T1")
273 { 385 {
274 if (ready) 386 if (ready)
275 { 387 {
276 if (!sunFixed) 388 if (m_SunFixed)
277 GenSunPos(); // Generate shared values once 389 {
278 client.SendSunPos(Position, Velocity, CurrentTime, SecondsPerSunCycle, SecondsPerYear, OrbitalPosition); 390 // m_log.DebugFormat("[SUN]: SunHour {0}, Position {1}, PosTime {2}, OrbitalPosition : {3} ", m_SunFixedHour, Position.ToString(), PosTime.ToString(), OrbitalPosition.ToString());
391 client.SendSunPos(Position, Velocity, PosTime, SecondsPerSunCycle, SecondsPerYear, OrbitalPosition);
392 }
393 else
394 {
395 // m_log.DebugFormat("[SUN]: SunHour {0}, Position {1}, PosTime {2}, OrbitalPosition : {3} ", m_SunFixedHour, Position.ToString(), PosTime.ToString(), OrbitalPosition.ToString());
396 client.SendSunPos(Position, Velocity, CurrentTime, SecondsPerSunCycle, SecondsPerYear, OrbitalPosition);
397 }
279 } 398 }
280 } 399 }
281 } 400 }
282 401
283 public void SunUpdate() 402 public void SunUpdate()
284 { 403 {
285 if (((m_frame++%m_frame_mod) != 0) || !ready || sunFixed) 404 if (((m_frame++ % m_UpdateInterval) != 0) || !ready || m_SunFixed || !receivedEstateToolsSunUpdate)
286 { 405 {
287 return; 406 return;
288 } 407 }
289 408
290 GenSunPos(); // Generate shared values once 409 GenSunPos(); // Generate shared values once
291 410
292 List<ScenePresence> avatars = m_scene.GetAvatars(); 411 SunUpdateToAllClients();
293 foreach (ScenePresence avatar in avatars)
294 {
295 if (!avatar.IsChildAgent)
296 avatar.ControllingClient.SendSunPos(Position, Velocity, CurrentTime, SecondsPerSunCycle, SecondsPerYear, OrbitalPosition);
297 }
298
299 // set estate settings for region access to sun position
300 m_scene.RegionInfo.RegionSettings.SunVector = Position;
301 //m_scene.RegionInfo.EstateSettings.sunHour = GetLindenEstateHourFromCurrentTime();
302 } 412 }
303 413
304 public void ForceSunUpdateToAllClients() 414 /// <summary>
415 /// When an avatar enters the region, it's probably a good idea to send them the current sun info
416 /// </summary>
417 /// <param name="avatar"></param>
418 /// <param name="localLandID"></param>
419 /// <param name="regionID"></param>
420 private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, UUID regionID)
305 { 421 {
306 GenSunPos(); // Generate shared values once 422 SunToClient(avatar.ControllingClient);
307
308 List<ScenePresence> avatars = m_scene.GetAvatars();
309 foreach (ScenePresence avatar in avatars)
310 {
311 if (!avatar.IsChildAgent)
312 avatar.ControllingClient.SendSunPos(Position, Velocity, CurrentTime, SecondsPerSunCycle, SecondsPerYear, OrbitalPosition);
313 }
314
315 // set estate settings for region access to sun position
316 m_scene.RegionInfo.RegionSettings.SunVector = Position;
317 m_scene.RegionInfo.RegionSettings.SunPosition = GetLindenEstateHourFromCurrentTime();
318 } 423 }
319 424
320 /// <summary> 425 /// <summary>
321 /// Calculate the sun's orbital position and its velocity. 426 ///
322 /// </summary> 427 /// </summary>
323 private void GenSunPos() 428 /// <param name="regionHandle"></param>
429 /// <param name="FixedTime">Is the sun's position fixed?</param>
430 /// <param name="useEstateTime">Use the Region or Estate Sun hour?</param>
431 /// <param name="FixedSunHour">What hour of the day is the Sun Fixed at?</param>
432 public void EstateToolsSunUpdate(ulong regionHandle, bool FixedSun, bool useEstateTime, float FixedSunHour)
324 { 433 {
325 TotalDistanceTravelled = SunSpeed * CurrentTime; // distance measured in radians 434 if (m_scene.RegionInfo.RegionHandle == regionHandle)
326 OrbitalPosition = (float) (TotalDistanceTravelled%SunCycle); // position measured in radians 435 {
327 436 // Must limit the Sun Hour to 0 ... 24
328 // TotalDistanceTravelled += HoursToRadians-(0.25*Math.PI)*Math.Cos(HoursToRadians)-OrbitalPosition; 437 while (FixedSunHour > 24.0f)
329 // OrbitalPosition = (float) (TotalDistanceTravelled%SunCycle); 438 FixedSunHour -= 24;
330
331 SeasonalOffset = SeasonSpeed * CurrentTime; // Present season determined as total radians travelled around season cycle
332
333 Tilt.W = (float) (AverageTilt + (SeasonalTilt*Math.Sin(SeasonalOffset))); // Calculate seasonal orbital N/S tilt
334
335 // m_log.Debug("[SUN] Total distance travelled = "+TotalDistanceTravelled+", present position = "+OrbitalPosition+".");
336 // m_log.Debug("[SUN] Total seasonal progress = "+SeasonalOffset+", present tilt = "+Tilt.W+".");
337
338 // The sun rotates about the Z axis
339 439
340 Position.X = (float) Math.Cos(-TotalDistanceTravelled); 440 while (FixedSunHour < 0)
341 Position.Y = (float) Math.Sin(-TotalDistanceTravelled); 441 FixedSunHour += 24;
342 Position.Z = 0;
343 442
344 // For interest we rotate it slightly about the X access.
345 // Celestial tilt is a value that ranges .025
346 443
347 Position *= Tilt; 444 m_SunFixedHour = FixedSunHour;
445 m_SunFixed = FixedSun;
348 446
349 // Finally we shift the axis so that more of the 447 m_log.DebugFormat("[SUN]: Sun Settings Update: Fixed Sun? : {0}", m_SunFixed.ToString());
350 // circle is above the horizon than below. This 448 m_log.DebugFormat("[SUN]: Sun Settings Update: Sun Hour : {0}", m_SunFixedHour.ToString());
351 // makes the nights shorter than the days.
352 449
353 Position.Z = Position.Z + (float) HorizonShift; 450 receivedEstateToolsSunUpdate = true;
354 Position = Vector3.Normalize(Position);
355 451
356 // m_log.Debug("[SUN] Position("+Position.X+","+Position.Y+","+Position.Z+")"); 452 // Generate shared values
453 GenSunPos();
357 454
358 Velocity.X = 0; 455 // When sun settings are updated, we should update all clients with new settings.
359 Velocity.Y = 0; 456 SunUpdateToAllClients();
360 Velocity.Z = (float) SunSpeed;
361 457
362 // Correct angular velocity to reflect the seasonal rotation
363 458
364 Magnitude = Position.Length(); 459 m_log.DebugFormat("[SUN]: PosTime : {0}", PosTime.ToString());
365 if (sunFixed)
366 {
367 Velocity.X = 0;
368 Velocity.Y = 0;
369 Velocity.Z = 0;
370 return;
371 } 460 }
372
373 Velocity = (Velocity * Tilt) * (1.0f / Magnitude);
374
375 // m_log.Debug("[SUN] Velocity("+Velocity.X+","+Velocity.Y+","+Velocity.Z+")");
376 } 461 }
377 462
378 private void ClientLoggedOut(UUID AgentId) 463 #endregion
379 {
380 lock (m_rootAgents)
381 {
382 if (m_rootAgents.ContainsKey(AgentId))
383 {
384 m_rootAgents.Remove(AgentId);
385 }
386 }
387 }
388 464
389 private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, UUID regionID)
390 {
391 lock (m_rootAgents)
392 {
393 if (m_rootAgents.ContainsKey(avatar.UUID))
394 {
395 m_rootAgents[avatar.UUID] = avatar.RegionHandle;
396 }
397 else
398 {
399 m_rootAgents.Add(avatar.UUID, avatar.RegionHandle);
400 SunToClient(avatar.ControllingClient);
401 }
402 }
403 //m_log.Info("[FRIEND]: " + avatar.Name + " status:" + (!avatar.IsChildAgent).ToString());
404 }
405 465
406 private void MakeChildAgent(ScenePresence avatar) 466 private void SunUpdateToAllClients()
407 { 467 {
408 lock (m_rootAgents) 468 List<ScenePresence> avatars = m_scene.GetAvatars();
469 foreach (ScenePresence avatar in avatars)
409 { 470 {
410 if (m_rootAgents.ContainsKey(avatar.UUID)) 471 if (!avatar.IsChildAgent)
411 { 472 {
412 if (m_rootAgents[avatar.UUID] == avatar.RegionHandle) 473 SunToClient(avatar.ControllingClient);
413 {
414 m_rootAgents.Remove(avatar.UUID);
415 }
416 } 474 }
417 } 475 }
418 } 476 }
419
420 public void EstateToolsTimeUpdate(ulong regionHandle, bool FixedTime, bool useEstateTime, float LindenHour)
421 {
422 if (m_scene.RegionInfo.RegionHandle == regionHandle)
423 {
424 SetTimeByLindenHour(LindenHour);
425
426 //if (useEstateTime)
427 //LindenHourOffset = 0;
428
429 ForceSunUpdateToAllClients();
430 sunFixed = FixedTime;
431 if (sunFixed)
432 GenSunPos();
433 }
434 }
435 } 477 }
436} 478}