aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJustin Clarke Casey2008-05-07 14:15:59 +0000
committerJustin Clarke Casey2008-05-07 14:15:59 +0000
commit382b9c18ed9736c88effb869e617ca3e3792d1db (patch)
treefa263f5a5c4ee035e156990679fa56a1880fcc3c
parentDe-tabify source. (diff)
downloadopensim-SC-382b9c18ed9736c88effb869e617ca3e3792d1db.zip
opensim-SC-382b9c18ed9736c88effb869e617ca3e3792d1db.tar.gz
opensim-SC-382b9c18ed9736c88effb869e617ca3e3792d1db.tar.bz2
opensim-SC-382b9c18ed9736c88effb869e617ca3e3792d1db.tar.xz
From: Alan M Webb <awebb@vnet.ibm.com>
The attached patch moves the sun module incrementally nearer where it needs to be. Default behavior, i.e. no overriding configuration is to match Second Life's diurnal/nocturnal rhythm. All designated values are now sent to the client.There remain a couple of unanswered questions about how this SHOULD be implemented though.
-rw-r--r--OpenSim/Framework/IClientAPI.cs2
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs18
-rw-r--r--OpenSim/Region/Environment/Modules/World/Sun/SunModule.cs226
-rw-r--r--OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs2
4 files changed, 193 insertions, 55 deletions
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 9d86036..d71a778 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -832,7 +832,7 @@ namespace OpenSim.Framework
832 void SendDialog(string objectname, LLUUID objectID, LLUUID ownerID, string msg, LLUUID textureID, int ch, string[] buttonlabels); 832 void SendDialog(string objectname, LLUUID objectID, LLUUID ownerID, string msg, LLUUID textureID, int ch, string[] buttonlabels);
833 bool AddMoney(int debit); 833 bool AddMoney(int debit);
834 834
835 void SendSunPos(LLVector3 sunPos, LLVector3 sunVel); 835 void SendSunPos(LLVector3 sunPos, LLVector3 sunVel, ulong CurrentTime, uint SecondsPerSunCycle, uint SecondsPerYear, float OrbitalPosition);
836 void SendViewerTime(int phase); 836 void SendViewerTime(int phase);
837 837
838 void SendAvatarProperties(LLUUID avatarID, string aboutText, string bornOn, string charterMember, string flAbout, 838 void SendAvatarProperties(LLUUID avatarID, string aboutText, string bornOn, string charterMember, string flAbout,
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index f5d4ad3..d183f4a 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -1772,18 +1772,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1772 OutPacket(sound, ThrottleOutPacketType.Task); 1772 OutPacket(sound, ThrottleOutPacketType.Task);
1773 } 1773 }
1774 1774
1775 public void SendSunPos(LLVector3 sunPos, LLVector3 sunVel) 1775 public void SendSunPos(LLVector3 Position, LLVector3 Velocity, ulong CurrentTime, uint SecondsPerSunCycle, uint SecondsPerYear, float OrbitalPosition)
1776 { 1776 {
1777 SimulatorViewerTimeMessagePacket viewertime = (SimulatorViewerTimeMessagePacket)PacketPool.Instance.GetPacket(PacketType.SimulatorViewerTimeMessage); 1777 SimulatorViewerTimeMessagePacket viewertime = (SimulatorViewerTimeMessagePacket)PacketPool.Instance.GetPacket(PacketType.SimulatorViewerTimeMessage);
1778 viewertime.TimeInfo.SunDirection = sunPos; 1778 viewertime.TimeInfo.SunDirection = Position;
1779 viewertime.TimeInfo.SunAngVelocity = sunVel; 1779 viewertime.TimeInfo.SunAngVelocity = Velocity;
1780 viewertime.TimeInfo.UsecSinceStart = (ulong)Util.UnixTimeSinceEpoch(); 1780 viewertime.TimeInfo.UsecSinceStart = CurrentTime;
1781 viewertime.Header.Reliable = false; 1781 viewertime.TimeInfo.SecPerDay = SecondsPerSunCycle;
1782 viewertime.TimeInfo.SecPerYear = SecondsPerYear;
1783 viewertime.TimeInfo.SunPhase = OrbitalPosition;
1784 viewertime.Header.Reliable = false;
1782 OutPacket(viewertime, ThrottleOutPacketType.Task); 1785 OutPacket(viewertime, ThrottleOutPacketType.Task);
1783 } 1786 }
1784 1787
1788 // Currently Deprecated
1785 public void SendViewerTime(int phase) 1789 public void SendViewerTime(int phase)
1786 { 1790 {
1791 /*
1787 Console.WriteLine("SunPhase: {0}", phase); 1792 Console.WriteLine("SunPhase: {0}", phase);
1788 SimulatorViewerTimeMessagePacket viewertime = (SimulatorViewerTimeMessagePacket)PacketPool.Instance.GetPacket(PacketType.SimulatorViewerTimeMessage); 1793 SimulatorViewerTimeMessagePacket viewertime = (SimulatorViewerTimeMessagePacket)PacketPool.Instance.GetPacket(PacketType.SimulatorViewerTimeMessage);
1789 //viewertime.TimeInfo.SecPerDay = 86400; 1794 //viewertime.TimeInfo.SecPerDay = 86400;
@@ -1829,6 +1834,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1829 viewertime.TimeInfo.UsecSinceStart = (ulong)Util.UnixTimeSinceEpoch(); 1834 viewertime.TimeInfo.UsecSinceStart = (ulong)Util.UnixTimeSinceEpoch();
1830 viewertime.Header.Reliable = false; 1835 viewertime.Header.Reliable = false;
1831 OutPacket(viewertime, ThrottleOutPacketType.Task); 1836 OutPacket(viewertime, ThrottleOutPacketType.Task);
1837 */
1832 } 1838 }
1833 1839
1834 public void SendAvatarProperties(LLUUID avatarID, string aboutText, string bornOn, string charterMember, 1840 public void SendAvatarProperties(LLUUID avatarID, string aboutText, string bornOn, string charterMember,
@@ -5474,4 +5480,4 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5474 m_sequence = info.sequence; 5480 m_sequence = info.sequence;
5475 } 5481 }
5476 } 5482 }
5477} \ No newline at end of file 5483}
diff --git a/OpenSim/Region/Environment/Modules/World/Sun/SunModule.cs b/OpenSim/Region/Environment/Modules/World/Sun/SunModule.cs
index 7d9bdd9..75cf786 100644
--- a/OpenSim/Region/Environment/Modules/World/Sun/SunModule.cs
+++ b/OpenSim/Region/Environment/Modules/World/Sun/SunModule.cs
@@ -33,45 +33,136 @@ using OpenSim.Framework;
33using OpenSim.Region.Environment.Interfaces; 33using OpenSim.Region.Environment.Interfaces;
34using OpenSim.Region.Environment.Scenes; 34using OpenSim.Region.Environment.Scenes;
35 35
36namespace OpenSim.Region.Environment.Modules.World.Sun 36namespace OpenSim.Region.Environment.Modules
37{ 37{
38 public class SunModule : IRegionModule 38 public class SunModule : IRegionModule
39 { 39 {
40 //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
41 40
42 private const int m_default_frame = 100; 41 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
43 private const double m_real_day = 24.0;
44 private double m_day_length;
45 private int m_dilation;
46 private int m_frame;
47 private int m_frame_mod;
48 42
49 private Scene m_scene; 43 private const double SeasonalTilt = 0.03 * Math.PI; // A daily shift of approximately 1.7188 degrees
50 private long m_start; 44 private const double AverageTilt = -0.25 * Math.PI; // A 45 degree tilt
45 private const double SunCycle = 2.0D * Math.PI; // A perfect circle measured in radians
46 private const double SeasonalCycle = 2.0D * Math.PI; // Ditto
51 47
52 #region IRegionModule Members 48 //
49 // Per Region Values
50 //
51
52 private bool ready = false;
53
54 // Configurable values
55 private int m_frame_mod = 0;
56 private double m_day_length = 0;
57 private int m_year_length = 0;
58 private double m_day_night = 0;
59 // Configurable defaults Defaults close to SL
60 private int d_frame_mod = 100; // Every 10 seconds (actually less)
61 private double d_day_length = 4; // A VW day is 4 RW hours long
62 private int d_year_length = 60; // There are 60 VW days in a VW year
63 private double d_day_night = 0.45; // axis offset: ratio of light-to-dark, approx 1:3
64
65 // Frame counter
66 private uint m_frame = 0;
67
68 // Cached Scene reference
69 private Scene m_scene = null;
70
71 // Calculated Once in the lifetime of a region
72 private ulong TicksToEpoch; // Elapsed time for 1/1/1970
73 private uint SecondsPerSunCycle; // Length of a virtual day in RW seconds
74 private uint SecondsPerYear; // Length of a virtual year in RW seconds
75 private double SunSpeed; // Rate of passage in radians/second
76 private double SeasonSpeed; // Rate of change for seasonal effects
77 private double HoursToRadians; // Rate of change for seasonal effects
78
79 // Calculated every update
80 private float OrbitalPosition; // Orbital placement at a point in time
81 private double HorizonShift; // Axis offset to skew day and night
82 private double TotalDistanceTravelled; // Distance since beginning of time (in radians)
83 private double SeasonalOffset; // Seaonal variation of tilt
84 private float Magnitude; // Normal tilt
85 private double VWTimeRatio; // VW time as a ratio of real time
86
87 // Working values
88 private LLVector3 Position = new LLVector3(0,0,0);
89 private LLVector3 Velocity = new LLVector3(0,0,0);
90 private LLQuaternion Tilt = new LLQuaternion(1,0,0,0);
91
92 // Current time in elpased seconds since Jan 1st 1970
93 private ulong CurrentTime
94 {
95 get { return (ulong)((((ulong)System.DateTime.Now.Ticks)-TicksToEpoch)/10000000); }
96 }
97
98 // Called immediately after the module is loaded for a given region
99 // i.e. Immediately after instance creation.
53 100
54 public void Initialise(Scene scene, IConfigSource config) 101 public void Initialise(Scene scene, IConfigSource config)
55 { 102 {
56 m_start = DateTime.Now.Ticks; 103
104 m_log.Debug("[SUN] Initializing");
105
106 m_scene = scene;
107
57 m_frame = 0; 108 m_frame = 0;
58 109
110 // Align ticks with Second Life
111
112 TicksToEpoch = (ulong) new System.DateTime(1970,1,1).Ticks;
113
59 // Just in case they don't have the stanzas 114 // Just in case they don't have the stanzas
60 try 115 try
61 { 116 {
62 m_day_length = config.Configs["Sun"].GetDouble("day_length", m_real_day); 117 // Day length in decimal hours
63 m_frame_mod = config.Configs["Sun"].GetInt("frame_rate", m_default_frame); 118 m_year_length = config.Configs["Sun"].GetInt("year_length", d_year_length);
119 // Day length in decimal hours
120 m_day_length = config.Configs["Sun"].GetDouble("day_length", d_day_length);
121 // Day to Night Ratio
122 m_day_night = config.Configs["Sun"].GetDouble("day_night_offset", d_day_night);
123 // Update frequency in frames
124 m_frame_mod = config.Configs["Sun"].GetInt("update_interval", d_frame_mod);
64 } 125 }
65 catch (Exception) 126 catch (Exception e)
66 { 127 {
67 m_day_length = m_real_day; 128 m_log.Debug("[SUN] Configuration access failed, using defaults. Reason: "+e.Message);
68 m_frame_mod = m_default_frame; 129 m_year_length = d_year_length;
130 m_day_length = d_day_length;
131 m_day_night = d_day_night;
132 m_frame_mod = d_frame_mod;
69 } 133 }
70 134
71 m_dilation = (int) (m_real_day / m_day_length); 135 // Time taken to complete a cycle (day and season)
72 m_scene = scene; 136
73 scene.EventManager.OnFrame += SunUpdate; 137 SecondsPerSunCycle = (uint) (m_day_length * 60 * 60);
138 SecondsPerYear = (uint) (SecondsPerSunCycle*m_year_length);
139
140 // Ration of real-to-virtual time
141
142 VWTimeRatio = 24/m_day_length;
143
144 // Speed of rotation needed to complete a cycle in the
145 // designated period (day and season)
146
147 SunSpeed = SunCycle/SecondsPerSunCycle;
148 SeasonSpeed = SeasonalCycle/SecondsPerYear;
149
150 // Horizon translation
151
152 HorizonShift = m_day_night; // Z axis translation
153 HoursToRadians = (SunCycle/24)*VWTimeRatio;
154
155 // Insert our event handling hooks
156
157 scene.EventManager.OnFrame += SunUpdate;
74 scene.EventManager.OnNewClient += SunToClient; 158 scene.EventManager.OnNewClient += SunToClient;
159
160 ready = true;
161
162 m_log.Debug("[SUN] Initialization completed. Day is "+SecondsPerSunCycle+" seconds, and year is "+m_year_length+" days");
163 m_log.Debug("[SUN] Axis offset is "+m_day_night);
164 m_log.Debug("[SUN] Positional data updated every "+m_frame_mod+" frames");
165
75 } 166 }
76 167
77 public void PostInitialise() 168 public void PostInitialise()
@@ -80,6 +171,10 @@ namespace OpenSim.Region.Environment.Modules.World.Sun
80 171
81 public void Close() 172 public void Close()
82 { 173 {
174 ready = false;
175 // Remove our hooks
176 m_scene.EventManager.OnFrame -= SunUpdate;
177 m_scene.EventManager.OnNewClient -= SunToClient;
83 } 178 }
84 179
85 public string Name 180 public string Name
@@ -92,51 +187,88 @@ namespace OpenSim.Region.Environment.Modules.World.Sun
92 get { return false; } 187 get { return false; }
93 } 188 }
94 189
95 #endregion
96
97 public void SunToClient(IClientAPI client) 190 public void SunToClient(IClientAPI client)
98 { 191 {
99 client.SendSunPos(SunPos(HourOfTheDay()), new LLVector3(0, 0.0f, 10.0f)); 192 if(ready)
193 {
194 GenSunPos(); // Generate shared values once
195 client.SendSunPos(Position, Velocity, CurrentTime, SecondsPerSunCycle, SecondsPerYear, OrbitalPosition);
196 }
100 } 197 }
101 198
102 public void SunUpdate() 199 public void SunUpdate()
103 { 200 {
104 if (m_frame < m_frame_mod) 201
202 if(((m_frame++%m_frame_mod) != 0) || !ready)
105 { 203 {
106 m_frame++;
107 return; 204 return;
108 } 205 }
109 // m_log.InfoFormat("[SUN]: I've got an update {0} => {1}", m_scene.RegionsInfo.RegionName, HourOfTheDay()); 206
207 GenSunPos(); // Generate shared values once
208
110 List<ScenePresence> avatars = m_scene.GetAvatars(); 209 List<ScenePresence> avatars = m_scene.GetAvatars();
111 foreach (ScenePresence avatar in avatars) 210 foreach (ScenePresence avatar in avatars)
112 { 211 {
113 avatar.ControllingClient.SendSunPos(SunPos(HourOfTheDay()), new LLVector3(0, 0.0f, 10.0f)); 212 avatar.ControllingClient.SendSunPos(Position, Velocity, CurrentTime, SecondsPerSunCycle, SecondsPerYear, OrbitalPosition);
114 } 213 }
214
115 // set estate settings for region access to sun position 215 // set estate settings for region access to sun position
116 m_scene.RegionInfo.EstateSettings.sunPosition = SunPos(HourOfTheDay()); 216 m_scene.RegionInfo.EstateSettings.sunPosition = Position;
117 217
118 m_frame = 0;
119 } 218 }
120 219
121 // Hour of the Day figures out the hour of the day as a float. 220 /// <summary>
122 // The intent here is that we seed hour of the day with real 221 /// Calculate the sun's orbital position and its velocity.
123 // time when the simulator starts, then run time forward 222 /// </summary>
124 // faster based on time dilation factor. This means that
125 // ticks don't get out of hand
126 private double HourOfTheDay()
127 {
128 long m_addticks = (DateTime.Now.Ticks - m_start) * m_dilation;
129 DateTime dt = new DateTime(m_start + m_addticks);
130 return dt.Hour + (dt.Minute / 60.0);
131 }
132 223
133 private static LLVector3 SunPos(double hour) 224 private void GenSunPos()
134 { 225 {
135 // now we have our radian position 226
136 double rad = (hour / m_real_day) * 2 * Math.PI - (Math.PI / 2.0); 227 TotalDistanceTravelled = SunSpeed * CurrentTime; // distance measured in radians
137 double z = Math.Sin(rad); 228 OrbitalPosition = (float) (TotalDistanceTravelled%SunCycle); // position measured in radians
138 double x = Math.Cos(rad); 229
139 return new LLVector3((float) x, 0f, (float) z); 230 // TotalDistanceTravelled += HoursToRadians-(0.25*Math.PI)*Math.Cos(HoursToRadians)-OrbitalPosition;
231 // OrbitalPosition = (float) (TotalDistanceTravelled%SunCycle);
232
233 SeasonalOffset = SeasonSpeed * CurrentTime; // Present season determined as total radians travelled around season cycle
234
235 Tilt.W = (float) (AverageTilt + (SeasonalTilt*Math.Sin(SeasonalOffset))); // Calculate seasonal orbital N/S tilt
236
237 // m_log.Debug("[SUN] Total distance travelled = "+TotalDistanceTravelled+", present position = "+OrbitalPosition+".");
238 // m_log.Debug("[SUN] Total seasonal progress = "+SeasonalOffset+", present tilt = "+Tilt.W+".");
239
240 // The sun rotates about the Z axis
241
242 Position.X = (float) Math.Cos(-TotalDistanceTravelled);
243 Position.Y = (float) Math.Sin(-TotalDistanceTravelled);
244 Position.Z = 0;
245
246 // For interest we rotate it slightly about the X access.
247 // Celestial tilt is a value that ranges .025
248
249 Position = LLVector3.Rot(Position,Tilt);
250
251 // Finally we shift the axis so that more of the
252 // circle is above the horizon than below. This
253 // makes the nights shorter than the days.
254
255 Position.Z = Position.Z + (float) HorizonShift;
256 Position = LLVector3.Norm(Position);
257
258 // m_log.Debug("[SUN] Position("+Position.X+","+Position.Y+","+Position.Z+")");
259
260 Velocity.X = 0;
261 Velocity.Y = 0;
262 Velocity.Z = (float) SunSpeed;
263
264 // Correct angular velocity to reflect the seasonal rotation
265
266 Magnitude = LLVector3.Mag(Position);
267
268 Velocity = LLVector3.Rot(Velocity, Tilt)*((float)(1.0/Magnitude));
269
270 // m_log.Debug("[SUN] Velocity("+Velocity.X+","+Velocity.Y+","+Velocity.Z+")");
271
140 } 272 }
141 } 273 }
142} \ No newline at end of file 274}
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
index f457773..e6e47cb 100644
--- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
+++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
@@ -573,7 +573,7 @@ namespace OpenSim.Region.Examples.SimpleModule
573 return false; 573 return false;
574 } 574 }
575 575
576 public void SendSunPos(LLVector3 sunPos, LLVector3 sunVel) 576 public void SendSunPos(LLVector3 sunPos, LLVector3 sunVel, ulong time, uint dlen, uint ylen, float phase)
577 { 577 {
578 } 578 }
579 579