diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 4b9572631a..ad433164d7 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -933,6 +933,15 @@ namespace OpenSim.Framework bool AddMoney(int debit); + /// + /// Update the client as to where the sun is currently located. + /// + /// + /// + /// Seconds since Unix Epoch 01/01/1970 00:00:00 + /// + /// + /// The orbital position is given in radians, and must be "adjusted" for the linden client, see LLClientView void SendSunPos(Vector3 sunPos, Vector3 sunVel, ulong CurrentTime, uint SecondsPerSunCycle, uint SecondsPerYear, float OrbitalPosition); diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 95519bc295..10e5c5a14e 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -87,6 +87,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP private int m_inPacketsChecked; + // Used to adjust Sun Orbit values so Linden based viewers properly position sun + private const float m_sunPainDaHalfOrbitalCutoff = 4.712388980384689858f; + + /* protected variables */ protected static Dictionary PacketHandlers = @@ -2403,10 +2407,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void SendSunPos(Vector3 Position, Vector3 Velocity, ulong CurrentTime, uint SecondsPerSunCycle, uint SecondsPerYear, float OrbitalPosition) { + // Viewers based on the Linden viwer code, do wacky things for oribital positions from Midnight to Sunrise + // So adjust for that + // Contributed by: Godfrey + + if (OrbitalPosition > m_sunPainDaHalfOrbitalCutoff) // things get weird from midnight to sunrise + { + OrbitalPosition = (OrbitalPosition - m_sunPainDaHalfOrbitalCutoff) * 0.6666666667f + m_sunPainDaHalfOrbitalCutoff; + } + + + SimulatorViewerTimeMessagePacket viewertime = (SimulatorViewerTimeMessagePacket)PacketPool.Instance.GetPacket(PacketType.SimulatorViewerTimeMessage); viewertime.TimeInfo.SunDirection = Position; viewertime.TimeInfo.SunAngVelocity = Velocity; - viewertime.TimeInfo.UsecSinceStart = CurrentTime; + + // Sun module used to add 6 hours to adjust for linden sun hour, adding here + // to prevent existing code from breaking if it assumed that 6 hours were included. + // 21600 == 6 hours * 60 minutes * 60 Seconds + viewertime.TimeInfo.UsecSinceStart = CurrentTime + 21600; + viewertime.TimeInfo.SecPerDay = SecondsPerSunCycle; viewertime.TimeInfo.SecPerYear = SecondsPerYear; viewertime.TimeInfo.SunPhase = OrbitalPosition; diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 7a200d44df..3bde9676dd 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -201,7 +201,7 @@ namespace OpenSim.Region.CoreModules.World.Estate m_scene.RegionInfo.RegionSettings.FixedSun = UseFixedSun; m_scene.RegionInfo.RegionSettings.SunPosition = SunHour; - m_scene.EventManager.TriggerEstateToolsTimeUpdate(m_scene.RegionInfo.RegionHandle, UseFixedSun, UseEstateSun, SunHour); + TriggerEstateToolsSunUpdate(); //m_log.Debug("[ESTATE]: UFS: " + UseFixedSun.ToString()); //m_log.Debug("[ESTATE]: SunHour: " + SunHour.ToString()); @@ -819,19 +819,7 @@ namespace OpenSim.Region.CoreModules.World.Estate m_scene.RegionInfo.EstateSettings.Save(); - float sun = (float)m_scene.RegionInfo.RegionSettings.SunPosition; - if (m_scene.RegionInfo.RegionSettings.UseEstateSun) - { - sun = (float)m_scene.RegionInfo.EstateSettings.SunPosition; - if (m_scene.RegionInfo.EstateSettings.UseGlobalTime) - sun = m_scene.EventManager.GetSunLindenHour(); - } - - m_scene.EventManager.TriggerEstateToolsTimeUpdate( - m_scene.RegionInfo.RegionHandle, - m_scene.RegionInfo.EstateSettings.FixedSun || - m_scene.RegionInfo.RegionSettings.FixedSun, - m_scene.RegionInfo.RegionSettings.UseEstateSun, sun); + TriggerEstateToolsSunUpdate(); sendDetailedEstateData(remoteClient, invoice); } @@ -851,6 +839,9 @@ namespace OpenSim.Region.CoreModules.World.Estate public void PostInitialise() { + // Sets up the sun module based no the saved Estate and Region Settings + // DO NOT REMOVE or the sun will stop working + TriggerEstateToolsSunUpdate(); } public void Close() @@ -871,6 +862,40 @@ namespace OpenSim.Region.CoreModules.World.Estate #region Other Functions + private void TriggerEstateToolsSunUpdate() + { + float sun; + if (m_scene.RegionInfo.RegionSettings.UseEstateSun) + { + sun = (float)m_scene.RegionInfo.EstateSettings.SunPosition; + if (m_scene.RegionInfo.EstateSettings.UseGlobalTime) + { + sun = m_scene.EventManager.GetCurrentTimeAsSunLindenHour() - 6.0f; + } + + // + m_scene.EventManager.TriggerEstateToolsSunUpdate( + m_scene.RegionInfo.RegionHandle, + m_scene.RegionInfo.EstateSettings.FixedSun, + m_scene.RegionInfo.RegionSettings.UseEstateSun, + sun); + } + else + { + // Use the Sun Position from the Region Settings + sun = (float)m_scene.RegionInfo.RegionSettings.SunPosition - 6.0f; + + m_scene.EventManager.TriggerEstateToolsSunUpdate( + m_scene.RegionInfo.RegionHandle, + m_scene.RegionInfo.RegionSettings.FixedSun, + m_scene.RegionInfo.RegionSettings.UseEstateSun, + sun); + } + + + } + + public void changeWaterHeight(float height) { setRegionTerrainSettings(height, diff --git a/OpenSim/Region/CoreModules/World/Sun/SunModule.cs b/OpenSim/Region/CoreModules/World/Sun/SunModule.cs index 7eb29f16b0..3c950c154e 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 { public class SunModule : IRegionModule { + /// + /// Note: Sun Hour can be a little deceaving. Although it's based on a 24 hour clock + /// it is not based on ~06:00 == Sun Rise. Rather it is based on 00:00 being sun-rise. + /// + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private const double SeasonalTilt = 0.03 * Math.PI; // A daily shift of approximately 1.7188 degrees - private const double AverageTilt = -0.25 * Math.PI; // A 45 degree tilt - private const double SunCycle = 2.0D * Math.PI; // A perfect circle measured in radians - private const double SeasonalCycle = 2.0D * Math.PI; // Ditto + // + // Global Constants used to determine where in the sky the sun is + // + private const double m_SeasonalTilt = 0.03 * Math.PI; // A daily shift of approximately 1.7188 degrees + private const double m_AverageTilt = -0.25 * Math.PI; // A 45 degree tilt + private const double m_SunCycle = 2.0D * Math.PI; // A perfect circle measured in radians + private const double m_SeasonalCycle = 2.0D * Math.PI; // Ditto // // Per Region Values // - private bool ready = false; + private bool ready = false; + + + // This solves a chick before the egg problem + // the local SunFixedHour and SunFixed variables MUST be updated + // at least once with the proper Region Settings before we start + // updating those region settings in GenSunPos() + private bool receivedEstateToolsSunUpdate = false; // Configurable values - private string m_mode = "SL"; - private int m_frame_mod = 0; - private double m_day_length = 0; - private int m_year_length = 0; - private double m_day_night = 0; + private string m_RegionMode = "SL"; + + // Sun's position information is updated and sent to clients every m_UpdateInterval frames + private int m_UpdateInterval = 0; + + // Number of real time hours per virtual day + private double m_DayLengthHours = 0; + + // Number of virtual days to a virtual year + private int m_YearLengthDays = 0; + + // Ratio of Daylight hours to Night time hours. This is accomplished by shifting the + // sun's orbit above the horizon + private double m_RatioDayNightHoizonShift = 0; + // private double m_longitude = 0; // private double m_latitude = 0; // Configurable defaults Defaults close to SL @@ -66,7 +91,8 @@ namespace OpenSim.Region.CoreModules private int d_frame_mod = 100; // Every 10 seconds (actually less) private double d_day_length = 4; // A VW day is 4 RW hours long private int d_year_length = 60; // There are 60 VW days in a VW year - private double d_day_night = 0.45; // axis offset: ratio of light-to-dark, approx 1:3 + private double d_day_night = 0.5; // axis offset: Default Hoizon shift to try and closely match the sun model in LL Viewer + // private double d_longitude = -73.53; // private double d_latitude = 41.29; @@ -83,7 +109,7 @@ namespace OpenSim.Region.CoreModules private double SunSpeed; // Rate of passage in radians/second private double SeasonSpeed; // Rate of change for seasonal effects // private double HoursToRadians; // Rate of change for seasonal effects - private long TicksOffset = 0; // seconds offset from UTC + private long TicksUTCOffset = 0; // seconds offset from UTC // Calculated every update private float OrbitalPosition; // Orbital placement at a point in time private double HorizonShift; // Axis offset to skew day and night @@ -97,58 +123,145 @@ namespace OpenSim.Region.CoreModules private Vector3 Velocity = Vector3.Zero; private Quaternion Tilt = new Quaternion(1.0f, 0.0f, 0.0f, 0.0f); - private long LindenHourOffset = 0; - private bool sunFixed = false; - private Dictionary m_rootAgents = new Dictionary(); + // Used to fix the sun in the sky so it doesn't move based on current time + private bool m_SunFixed = false; + private float m_SunFixedHour = 0f; + + private const int TICKS_PER_SECOND = 10000000; + + // Current time in elapsed seconds since Jan 1st 1970 private ulong CurrentTime { - get { - return (ulong)(((DateTime.Now.Ticks) - TicksToEpoch + TicksOffset + LindenHourOffset)/10000000); + get + { + return (ulong)(((DateTime.Now.Ticks) - TicksToEpoch + TicksUTCOffset) / TICKS_PER_SECOND); } } - private float GetLindenEstateHourFromCurrentTime() + // Time in seconds since UTC to use to calculate sun position. + ulong PosTime = 0; + + /// + /// Calculate the sun's orbital position and its velocity. + /// + private void GenSunPos() + { + // Time in seconds since UTC to use to calculate sun position. + PosTime = CurrentTime; + + if (m_SunFixed) + { + // SunFixedHour represents the "hour of day" we would like + // It's represented in 24hr time, with 0 hour being sun-rise + // Because our day length is probably not 24hrs {LL is 6} we need to do a bit of math + + // Determine the current "day" from current time, so we can use "today" + // to determine Seasonal Tilt and what'not + + // Integer math rounded is on purpose to drop fractional day, determines number + // of virtual days since Epoch + PosTime = CurrentTime / SecondsPerSunCycle; + + // Since we want number of seconds since Epoch, multiply back up + PosTime *= SecondsPerSunCycle; + + // Then offset by the current Fixed Sun Hour + // Fixed Sun Hour needs to be scaled to reflect the user configured Seconds Per Sun Cycle + PosTime += (ulong)((m_SunFixedHour / 24.0) * (ulong)SecondsPerSunCycle); + } + + TotalDistanceTravelled = SunSpeed * PosTime; // distance measured in radians + + OrbitalPosition = (float)(TotalDistanceTravelled % m_SunCycle); // position measured in radians + + // TotalDistanceTravelled += HoursToRadians-(0.25*Math.PI)*Math.Cos(HoursToRadians)-OrbitalPosition; + // OrbitalPosition = (float) (TotalDistanceTravelled%SunCycle); + + SeasonalOffset = SeasonSpeed * PosTime; // Present season determined as total radians travelled around season cycle + Tilt.W = (float)(m_AverageTilt + (m_SeasonalTilt * Math.Sin(SeasonalOffset))); // Calculate seasonal orbital N/S tilt + + // m_log.Debug("[SUN] Total distance travelled = "+TotalDistanceTravelled+", present position = "+OrbitalPosition+"."); + // m_log.Debug("[SUN] Total seasonal progress = "+SeasonalOffset+", present tilt = "+Tilt.W+"."); + + // The sun rotates about the Z axis + + Position.X = (float)Math.Cos(-TotalDistanceTravelled); + Position.Y = (float)Math.Sin(-TotalDistanceTravelled); + Position.Z = 0; + + // For interest we rotate it slightly about the X access. + // Celestial tilt is a value that ranges .025 + + Position *= Tilt; + + // Finally we shift the axis so that more of the + // circle is above the horizon than below. This + // makes the nights shorter than the days. + + Position = Vector3.Normalize(Position); + Position.Z = Position.Z + (float)HorizonShift; + Position = Vector3.Normalize(Position); + + // m_log.Debug("[SUN] Position("+Position.X+","+Position.Y+","+Position.Z+")"); + + Velocity.X = 0; + Velocity.Y = 0; + Velocity.Z = (float)SunSpeed; + + // Correct angular velocity to reflect the seasonal rotation + + Magnitude = Position.Length(); + if (m_SunFixed) + { + Velocity.X = 0; + Velocity.Y = 0; + Velocity.Z = 0; + + } + else + { + Velocity = (Velocity * Tilt) * (1.0f / Magnitude); + } + + // TODO: Decouple this, so we can get rid of Linden Hour info + // Update Region infor with new Sun Position and Hour + // set estate settings for region access to sun position + if (receivedEstateToolsSunUpdate) + { + m_scene.RegionInfo.RegionSettings.SunVector = Position; + m_scene.RegionInfo.RegionSettings.SunPosition = GetSunHourAsLindenSunHour(); + } + } + + /// + /// Used to calculate the "linden sun hour" which is from 6 to 30, with 6 being "sun rise" + /// on the left most end of the Sun Slider in the client. + /// TODO: Decouple this and send it closer to linden client code. + /// + private float GetCurrentTimeAsLindenSunHour() { float ticksleftover = ((float)CurrentTime) % ((float)SecondsPerSunCycle); - float hour = (24 * (ticksleftover / SecondsPerSunCycle)) + 6; + float hour = (24.0f * (ticksleftover / SecondsPerSunCycle)) + 6.0f; return hour; } - private void SetTimeByLindenHour(float LindenHour) + private float GetSunHourAsLindenSunHour() { - // Linden hour is 24 hours with a 6 hour offset. 6-30 - - if (LindenHour - 6 == 0) + if (m_SunFixed) { - LindenHourOffset = 0; - return; + return m_SunFixedHour + 6; } - // Remove LindenHourOffset to calculate it from LocalTime - float ticksleftover = ((float)(((long)(CurrentTime * 10000000) - (long)LindenHourOffset)/ 10000000) % ((float)SecondsPerSunCycle)); - float hour = (24 * (ticksleftover / SecondsPerSunCycle)); - - float offsethours = 0; - - if (LindenHour - 6 > hour) - { - offsethours = hour + ((LindenHour-6) - hour); - } - else - { - offsethours = hour - (hour - (LindenHour - 6)); - } - //m_log.Debug("[OFFSET]: " + hour + " - " + LindenHour + " - " + offsethours.ToString()); - - LindenHourOffset = (long)((float)offsethours * (36000000000/m_day_length)); - m_log.Debug("[SUN]: Directive from the Estate Tools to set the sun phase to LindenHour " + GetLindenEstateHourFromCurrentTime().ToString()); + return GetCurrentTimeAsLindenSunHour(); } + #region IRegion Methods + // Called immediately after the module is loaded for a given region // i.e. Immediately after instance creation. public void Initialise(Scene scene, IConfigSource config) @@ -158,52 +271,52 @@ namespace OpenSim.Region.CoreModules m_frame = 0; TimeZone local = TimeZone.CurrentTimeZone; - TicksOffset = local.GetUtcOffset(local.ToLocalTime(DateTime.Now)).Ticks; - m_log.Debug("[SUN]: localtime offset is " + TicksOffset); + TicksUTCOffset = local.GetUtcOffset(local.ToLocalTime(DateTime.Now)).Ticks; + m_log.Debug("[SUN]: localtime offset is " + TicksUTCOffset); // Align ticks with Second Life - TicksToEpoch = new DateTime(1970,1,1).Ticks; + TicksToEpoch = new DateTime(1970, 1, 1).Ticks; // Just in case they don't have the stanzas try { // Mode: determines how the sun is handled - m_mode = config.Configs["Sun"].GetString("mode", d_mode); + m_RegionMode = config.Configs["Sun"].GetString("mode", d_mode); // Mode: determines how the sun is handled // m_latitude = config.Configs["Sun"].GetDouble("latitude", d_latitude); // Mode: determines how the sun is handled // m_longitude = config.Configs["Sun"].GetDouble("longitude", d_longitude); // Year length in days - m_year_length = config.Configs["Sun"].GetInt("year_length", d_year_length); + m_YearLengthDays = config.Configs["Sun"].GetInt("year_length", d_year_length); // Day length in decimal hours - m_day_length = config.Configs["Sun"].GetDouble("day_length", d_day_length); + m_DayLengthHours = config.Configs["Sun"].GetDouble("day_length", d_day_length); // Day to Night Ratio - m_day_night = config.Configs["Sun"].GetDouble("day_night_offset", d_day_night); + m_RatioDayNightHoizonShift = config.Configs["Sun"].GetDouble("day_night_offset", d_day_night); // Update frequency in frames - m_frame_mod = config.Configs["Sun"].GetInt("update_interval", d_frame_mod); + m_UpdateInterval = config.Configs["Sun"].GetInt("update_interval", d_frame_mod); } catch (Exception e) { - m_log.Debug("[SUN]: Configuration access failed, using defaults. Reason: "+e.Message); - m_mode = d_mode; - m_year_length = d_year_length; - m_day_length = d_day_length; - m_day_night = d_day_night; - m_frame_mod = d_frame_mod; + m_log.Debug("[SUN]: Configuration access failed, using defaults. Reason: " + e.Message); + m_RegionMode = d_mode; + m_YearLengthDays = d_year_length; + m_DayLengthHours = d_day_length; + m_RatioDayNightHoizonShift = d_day_night; + m_UpdateInterval = d_frame_mod; // m_latitude = d_latitude; // m_longitude = d_longitude; } - switch (m_mode) + switch (m_RegionMode) { case "T1": default: case "SL": // Time taken to complete a cycle (day and season) - SecondsPerSunCycle = (uint) (m_day_length * 60 * 60); - SecondsPerYear = (uint) (SecondsPerSunCycle*m_year_length); + SecondsPerSunCycle = (uint) (m_DayLengthHours * 60 * 60); + SecondsPerYear = (uint) (SecondsPerSunCycle*m_YearLengthDays); // Ration of real-to-virtual time @@ -212,29 +325,27 @@ namespace OpenSim.Region.CoreModules // Speed of rotation needed to complete a cycle in the // designated period (day and season) - SunSpeed = SunCycle/SecondsPerSunCycle; - SeasonSpeed = SeasonalCycle/SecondsPerYear; + SunSpeed = m_SunCycle/SecondsPerSunCycle; + SeasonSpeed = m_SeasonalCycle/SecondsPerYear; // Horizon translation - HorizonShift = m_day_night; // Z axis translation + HorizonShift = m_RatioDayNightHoizonShift; // Z axis translation // HoursToRadians = (SunCycle/24)*VWTimeRatio; // Insert our event handling hooks scene.EventManager.OnFrame += SunUpdate; - scene.EventManager.OnMakeChildAgent += MakeChildAgent; scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; - scene.EventManager.OnClientClosed += ClientLoggedOut; - scene.EventManager.OnEstateToolsTimeUpdate += EstateToolsTimeUpdate; - scene.EventManager.OnGetSunLindenHour += GetLindenEstateHourFromCurrentTime; + scene.EventManager.OnEstateToolsSunUpdate += EstateToolsSunUpdate; + scene.EventManager.OnGetCurrentTimeAsLindenSunHour += GetCurrentTimeAsLindenSunHour; ready = true; - m_log.Debug("[SUN]: Mode is "+m_mode); - m_log.Debug("[SUN]: Initialization completed. Day is "+SecondsPerSunCycle+" seconds, and year is "+m_year_length+" days"); - m_log.Debug("[SUN]: Axis offset is "+m_day_night); - m_log.Debug("[SUN]: Positional data updated every "+m_frame_mod+" frames"); + m_log.Debug("[SUN]: Mode is " + m_RegionMode); + m_log.Debug("[SUN]: Initialization completed. Day is " + SecondsPerSunCycle + " seconds, and year is " + m_YearLengthDays + " days"); + m_log.Debug("[SUN]: Axis offset is " + m_RatioDayNightHoizonShift); + m_log.Debug("[SUN]: Positional data updated every " + m_UpdateInterval + " frames"); break; } @@ -250,11 +361,9 @@ namespace OpenSim.Region.CoreModules // Remove our hooks m_scene.EventManager.OnFrame -= SunUpdate; - m_scene.EventManager.OnMakeChildAgent -= MakeChildAgent; m_scene.EventManager.OnAvatarEnteringNewParcel -= AvatarEnteringParcel; - m_scene.EventManager.OnClientClosed -= ClientLoggedOut; - m_scene.EventManager.OnEstateToolsTimeUpdate -= EstateToolsTimeUpdate; - m_scene.EventManager.OnGetSunLindenHour -= GetLindenEstateHourFromCurrentTime; + m_scene.EventManager.OnEstateToolsSunUpdate -= EstateToolsSunUpdate; + m_scene.EventManager.OnGetCurrentTimeAsLindenSunHour -= GetCurrentTimeAsLindenSunHour; } public string Name @@ -266,170 +375,103 @@ namespace OpenSim.Region.CoreModules { get { return false; } } + #endregion + + #region EventManager Events public void SunToClient(IClientAPI client) { - if (m_mode != "T1") + if (m_RegionMode != "T1") { if (ready) { - if (!sunFixed) - GenSunPos(); // Generate shared values once - client.SendSunPos(Position, Velocity, CurrentTime, SecondsPerSunCycle, SecondsPerYear, OrbitalPosition); + if (m_SunFixed) + { + // m_log.DebugFormat("[SUN]: SunHour {0}, Position {1}, PosTime {2}, OrbitalPosition : {3} ", m_SunFixedHour, Position.ToString(), PosTime.ToString(), OrbitalPosition.ToString()); + client.SendSunPos(Position, Velocity, PosTime, SecondsPerSunCycle, SecondsPerYear, OrbitalPosition); + } + else + { + // m_log.DebugFormat("[SUN]: SunHour {0}, Position {1}, PosTime {2}, OrbitalPosition : {3} ", m_SunFixedHour, Position.ToString(), PosTime.ToString(), OrbitalPosition.ToString()); + client.SendSunPos(Position, Velocity, CurrentTime, SecondsPerSunCycle, SecondsPerYear, OrbitalPosition); + } } } } public void SunUpdate() { - if (((m_frame++%m_frame_mod) != 0) || !ready || sunFixed) + if (((m_frame++ % m_UpdateInterval) != 0) || !ready || m_SunFixed || !receivedEstateToolsSunUpdate) { return; } GenSunPos(); // Generate shared values once - List avatars = m_scene.GetAvatars(); - foreach (ScenePresence avatar in avatars) - { - if (!avatar.IsChildAgent) - avatar.ControllingClient.SendSunPos(Position, Velocity, CurrentTime, SecondsPerSunCycle, SecondsPerYear, OrbitalPosition); - } - - // set estate settings for region access to sun position - m_scene.RegionInfo.RegionSettings.SunVector = Position; - //m_scene.RegionInfo.EstateSettings.sunHour = GetLindenEstateHourFromCurrentTime(); - } - - public void ForceSunUpdateToAllClients() - { - GenSunPos(); // Generate shared values once - - List avatars = m_scene.GetAvatars(); - foreach (ScenePresence avatar in avatars) - { - if (!avatar.IsChildAgent) - avatar.ControllingClient.SendSunPos(Position, Velocity, CurrentTime, SecondsPerSunCycle, SecondsPerYear, OrbitalPosition); - } - - // set estate settings for region access to sun position - m_scene.RegionInfo.RegionSettings.SunVector = Position; - m_scene.RegionInfo.RegionSettings.SunPosition = GetLindenEstateHourFromCurrentTime(); + SunUpdateToAllClients(); } /// - /// Calculate the sun's orbital position and its velocity. + /// When an avatar enters the region, it's probably a good idea to send them the current sun info /// - private void GenSunPos() - { - TotalDistanceTravelled = SunSpeed * CurrentTime; // distance measured in radians - OrbitalPosition = (float) (TotalDistanceTravelled%SunCycle); // position measured in radians - - // TotalDistanceTravelled += HoursToRadians-(0.25*Math.PI)*Math.Cos(HoursToRadians)-OrbitalPosition; - // OrbitalPosition = (float) (TotalDistanceTravelled%SunCycle); - - SeasonalOffset = SeasonSpeed * CurrentTime; // Present season determined as total radians travelled around season cycle - - Tilt.W = (float) (AverageTilt + (SeasonalTilt*Math.Sin(SeasonalOffset))); // Calculate seasonal orbital N/S tilt - - // m_log.Debug("[SUN] Total distance travelled = "+TotalDistanceTravelled+", present position = "+OrbitalPosition+"."); - // m_log.Debug("[SUN] Total seasonal progress = "+SeasonalOffset+", present tilt = "+Tilt.W+"."); - - // The sun rotates about the Z axis - - Position.X = (float) Math.Cos(-TotalDistanceTravelled); - Position.Y = (float) Math.Sin(-TotalDistanceTravelled); - Position.Z = 0; - - // For interest we rotate it slightly about the X access. - // Celestial tilt is a value that ranges .025 - - Position *= Tilt; - - // Finally we shift the axis so that more of the - // circle is above the horizon than below. This - // makes the nights shorter than the days. - - Position.Z = Position.Z + (float) HorizonShift; - Position = Vector3.Normalize(Position); - - // m_log.Debug("[SUN] Position("+Position.X+","+Position.Y+","+Position.Z+")"); - - Velocity.X = 0; - Velocity.Y = 0; - Velocity.Z = (float) SunSpeed; - - // Correct angular velocity to reflect the seasonal rotation - - Magnitude = Position.Length(); - if (sunFixed) - { - Velocity.X = 0; - Velocity.Y = 0; - Velocity.Z = 0; - return; - } - - Velocity = (Velocity * Tilt) * (1.0f / Magnitude); - - // m_log.Debug("[SUN] Velocity("+Velocity.X+","+Velocity.Y+","+Velocity.Z+")"); - } - - private void ClientLoggedOut(UUID AgentId) - { - lock (m_rootAgents) - { - if (m_rootAgents.ContainsKey(AgentId)) - { - m_rootAgents.Remove(AgentId); - } - } - } - + /// + /// + /// private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, UUID regionID) { - lock (m_rootAgents) - { - if (m_rootAgents.ContainsKey(avatar.UUID)) - { - m_rootAgents[avatar.UUID] = avatar.RegionHandle; - } - else - { - m_rootAgents.Add(avatar.UUID, avatar.RegionHandle); - SunToClient(avatar.ControllingClient); - } - } - //m_log.Info("[FRIEND]: " + avatar.Name + " status:" + (!avatar.IsChildAgent).ToString()); + SunToClient(avatar.ControllingClient); } - private void MakeChildAgent(ScenePresence avatar) - { - lock (m_rootAgents) - { - if (m_rootAgents.ContainsKey(avatar.UUID)) - { - if (m_rootAgents[avatar.UUID] == avatar.RegionHandle) - { - m_rootAgents.Remove(avatar.UUID); - } - } - } - } - - public void EstateToolsTimeUpdate(ulong regionHandle, bool FixedTime, bool useEstateTime, float LindenHour) + /// + /// + /// + /// + /// Is the sun's position fixed? + /// Use the Region or Estate Sun hour? + /// What hour of the day is the Sun Fixed at? + public void EstateToolsSunUpdate(ulong regionHandle, bool FixedSun, bool useEstateTime, float FixedSunHour) { if (m_scene.RegionInfo.RegionHandle == regionHandle) { - SetTimeByLindenHour(LindenHour); + // Must limit the Sun Hour to 0 ... 24 + while (FixedSunHour > 24.0f) + FixedSunHour -= 24; - //if (useEstateTime) - //LindenHourOffset = 0; + while (FixedSunHour < 0) + FixedSunHour += 24; - ForceSunUpdateToAllClients(); - sunFixed = FixedTime; - if (sunFixed) - GenSunPos(); + + m_SunFixedHour = FixedSunHour; + m_SunFixed = FixedSun; + + m_log.DebugFormat("[SUN]: Sun Settings Update: Fixed Sun? : {0}", m_SunFixed.ToString()); + m_log.DebugFormat("[SUN]: Sun Settings Update: Sun Hour : {0}", m_SunFixedHour.ToString()); + + receivedEstateToolsSunUpdate = true; + + // Generate shared values + GenSunPos(); + + // When sun settings are updated, we should update all clients with new settings. + SunUpdateToAllClients(); + + + m_log.DebugFormat("[SUN]: PosTime : {0}", PosTime.ToString()); + } + } + + #endregion + + + private void SunUpdateToAllClients() + { + List avatars = m_scene.GetAvatars(); + foreach (ScenePresence avatar in avatars) + { + if (!avatar.IsChildAgent) + { + SunToClient(avatar.ControllingClient); + } } } } diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 8a556d98f6..8621f701d9 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -202,10 +202,10 @@ namespace OpenSim.Region.Framework.Scenes public event ScriptTimerEvent OnScriptTimerEvent; - public delegate void EstateToolsTimeUpdate(ulong regionHandle, bool FixedTime, bool EstateSun, float LindenHour); + public delegate void EstateToolsSunUpdate(ulong regionHandle, bool FixedTime, bool EstateSun, float LindenHour); public delegate void GetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID); - public event EstateToolsTimeUpdate OnEstateToolsTimeUpdate; + public event EstateToolsSunUpdate OnEstateToolsSunUpdate; public delegate void ObjectBeingRemovedFromScene(SceneObjectGroup obj); public event ObjectBeingRemovedFromScene OnObjectBeingRemovedFromScene; @@ -264,7 +264,7 @@ namespace OpenSim.Region.Framework.Scenes public event ChatBroadcastEvent OnChatBroadcast; public delegate float SunLindenHour(); - public event SunLindenHour OnGetSunLindenHour; + public event SunLindenHour OnGetCurrentTimeAsLindenSunHour; /// /// Called when oar file has finished loading, although @@ -411,14 +411,14 @@ namespace OpenSim.Region.Framework.Scenes private ParcelPrimCountTainted handlerParcelPrimCountTainted = null; private ObjectBeingRemovedFromScene handlerObjectBeingRemovedFromScene = null; private ScriptTimerEvent handlerScriptTimerEvent = null; - private EstateToolsTimeUpdate handlerEstateToolsTimeUpdate = null; + private EstateToolsSunUpdate handlerEstateToolsSunUpdate = null; private ScriptColliding handlerCollidingStart = null; private ScriptColliding handlerColliding = null; private ScriptColliding handlerCollidingEnd = null; private GetScriptRunning handlerGetScriptRunning = null; - private SunLindenHour handlerSunGetLindenHour = null; + private SunLindenHour handlerCurrentTimeAsLindenSunHour = null; private OnSetRootAgentSceneDelegate handlerSetRootAgentScene = null; private OarFileLoaded handlerOarFileLoaded = null; @@ -910,21 +910,28 @@ namespace OpenSim.Region.Framework.Scenes } } - public void TriggerEstateToolsTimeUpdate(ulong regionHandle, bool FixedTime, bool useEstateTime, float LindenHour) + /// + /// Updates the system as to how the position of the sun should be handled. + /// + /// + /// True if the Sun Position is fixed + /// True if the Estate Settings should be used instead of region + /// The hour 0.0 <= FixedSunHour <= 24.0 at which the sun is fixed at. Sun Hour 0 is sun-rise, when Day/Night ratio is 1:1 + public void TriggerEstateToolsSunUpdate(ulong regionHandle, bool FixedTime, bool useEstateTime, float FixedSunHour) { - handlerEstateToolsTimeUpdate = OnEstateToolsTimeUpdate; - if (handlerEstateToolsTimeUpdate != null) + handlerEstateToolsSunUpdate = OnEstateToolsSunUpdate; + if (handlerEstateToolsSunUpdate != null) { - handlerEstateToolsTimeUpdate(regionHandle, FixedTime, useEstateTime, LindenHour); + handlerEstateToolsSunUpdate(regionHandle, FixedTime, useEstateTime, FixedSunHour); } } - public float GetSunLindenHour() + public float GetCurrentTimeAsSunLindenHour() { - handlerSunGetLindenHour = OnGetSunLindenHour; - if (handlerSunGetLindenHour != null) + handlerCurrentTimeAsLindenSunHour = OnGetCurrentTimeAsLindenSunHour; + if (handlerCurrentTimeAsLindenSunHour != null) { - return handlerSunGetLindenHour(); + return handlerCurrentTimeAsLindenSunHour(); } return 6; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index e96dd2643a..6b3afe0ab8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -754,6 +754,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } + /// + /// Changes the Region Sun Settings, then Triggers a Sun Update + /// + /// True to use Estate Sun instead of Region Sun + /// True to keep the sun stationary + /// The "Sun Hour" that is desired, 0...24, with 0 just after SunRise + public void osSetRegionSunSettings(bool useEstateSun, bool sunFixed, double sunHour) + { + CheckThreatLevel(ThreatLevel.Nuisance, "osSetRegionSunSettings"); + + m_host.AddScriptLPS(1); + //Check to make sure that the script's owner is the estate manager/master + //World.Permissions.GenericEstatePermission( + if (World.Permissions.IsGod(m_host.OwnerID)) + { + World.RegionInfo.RegionSettings.UseEstateSun = useEstateSun; + World.RegionInfo.RegionSettings.SunPosition = sunHour + 6; // LL Region Sun Hour is 6 to 30 + World.RegionInfo.RegionSettings.FixedSun = sunFixed; + World.RegionInfo.RegionSettings.Save(); + + World.EventManager.TriggerEstateToolsSunUpdate(World.RegionInfo.RegionHandle, sunFixed, useEstateSun, (float)sunHour); + } + } + + + + public double osList2Double(LSL_Types.list src, int index) { // There is really no double type in OSSL. C# and other diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 6eccf518e7..3656f92c67 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -95,7 +95,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void osSetStateEvents(int events); double osList2Double(LSL_Types.list src, int index); + void osSetRegionWaterHeight(double height); + void osSetRegionSunSettings(bool useEstateSun, bool sunFixed, double sunHour); string osGetScriptEngineName(); string osGetSimulatorVersion(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 318ec2f4f9..d316ac939b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -62,6 +62,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_OSSL_Functions.osSetRegionWaterHeight(height); } + public void osSetRegionSunSettings(bool useEstateSun, bool sunFixed, double sunHour) + { + m_OSSL_Functions.osSetRegionSunSettings(useEstateSun, sunFixed, sunHour); + } + public double osList2Double(LSL_Types.list src, int index) { return m_OSSL_Functions.osList2Double(src, index); diff --git a/bin/config.preview.donotuseyet-v2/defaults/region.ini.defaults b/bin/config.preview.donotuseyet-v2/defaults/region.ini.defaults index 9d61b1eec4..892393517f 100644 --- a/bin/config.preview.donotuseyet-v2/defaults/region.ini.defaults +++ b/bin/config.preview.donotuseyet-v2/defaults/region.ini.defaults @@ -86,8 +86,9 @@ ;day_length = 4 ; Year length in days ;year_length = 60 - ; Day to Night Ratio - ;day_night_offset = 0.45 + ; Horizon shift, changes Day to Night Ratio, more shift, the time the sun spends above the horizon, + ; .5 matches very closely with what LL based viewers display + ;day_night_offset = 0.5 ; send a Sun update every update_interval # of frames. A lower number will ; make for smoother sun transition at the cost of network ;update_interval = 100