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.0.6.0-stable
parent
0ea48cf786
commit
382b9c18ed
|
@ -832,7 +832,7 @@ namespace OpenSim.Framework
|
||||||
void SendDialog(string objectname, LLUUID objectID, LLUUID ownerID, string msg, LLUUID textureID, int ch, string[] buttonlabels);
|
void SendDialog(string objectname, LLUUID objectID, LLUUID ownerID, string msg, LLUUID textureID, int ch, string[] buttonlabels);
|
||||||
bool AddMoney(int debit);
|
bool AddMoney(int debit);
|
||||||
|
|
||||||
void SendSunPos(LLVector3 sunPos, LLVector3 sunVel);
|
void SendSunPos(LLVector3 sunPos, LLVector3 sunVel, ulong CurrentTime, uint SecondsPerSunCycle, uint SecondsPerYear, float OrbitalPosition);
|
||||||
void SendViewerTime(int phase);
|
void SendViewerTime(int phase);
|
||||||
|
|
||||||
void SendAvatarProperties(LLUUID avatarID, string aboutText, string bornOn, string charterMember, string flAbout,
|
void SendAvatarProperties(LLUUID avatarID, string aboutText, string bornOn, string charterMember, string flAbout,
|
||||||
|
|
|
@ -1772,18 +1772,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
OutPacket(sound, ThrottleOutPacketType.Task);
|
OutPacket(sound, ThrottleOutPacketType.Task);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendSunPos(LLVector3 sunPos, LLVector3 sunVel)
|
public void SendSunPos(LLVector3 Position, LLVector3 Velocity, ulong CurrentTime, uint SecondsPerSunCycle, uint SecondsPerYear, float OrbitalPosition)
|
||||||
{
|
{
|
||||||
SimulatorViewerTimeMessagePacket viewertime = (SimulatorViewerTimeMessagePacket)PacketPool.Instance.GetPacket(PacketType.SimulatorViewerTimeMessage);
|
SimulatorViewerTimeMessagePacket viewertime = (SimulatorViewerTimeMessagePacket)PacketPool.Instance.GetPacket(PacketType.SimulatorViewerTimeMessage);
|
||||||
viewertime.TimeInfo.SunDirection = sunPos;
|
viewertime.TimeInfo.SunDirection = Position;
|
||||||
viewertime.TimeInfo.SunAngVelocity = sunVel;
|
viewertime.TimeInfo.SunAngVelocity = Velocity;
|
||||||
viewertime.TimeInfo.UsecSinceStart = (ulong)Util.UnixTimeSinceEpoch();
|
viewertime.TimeInfo.UsecSinceStart = CurrentTime;
|
||||||
viewertime.Header.Reliable = false;
|
viewertime.TimeInfo.SecPerDay = SecondsPerSunCycle;
|
||||||
|
viewertime.TimeInfo.SecPerYear = SecondsPerYear;
|
||||||
|
viewertime.TimeInfo.SunPhase = OrbitalPosition;
|
||||||
|
viewertime.Header.Reliable = false;
|
||||||
OutPacket(viewertime, ThrottleOutPacketType.Task);
|
OutPacket(viewertime, ThrottleOutPacketType.Task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Currently Deprecated
|
||||||
public void SendViewerTime(int phase)
|
public void SendViewerTime(int phase)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
Console.WriteLine("SunPhase: {0}", phase);
|
Console.WriteLine("SunPhase: {0}", phase);
|
||||||
SimulatorViewerTimeMessagePacket viewertime = (SimulatorViewerTimeMessagePacket)PacketPool.Instance.GetPacket(PacketType.SimulatorViewerTimeMessage);
|
SimulatorViewerTimeMessagePacket viewertime = (SimulatorViewerTimeMessagePacket)PacketPool.Instance.GetPacket(PacketType.SimulatorViewerTimeMessage);
|
||||||
//viewertime.TimeInfo.SecPerDay = 86400;
|
//viewertime.TimeInfo.SecPerDay = 86400;
|
||||||
|
@ -1829,6 +1834,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
viewertime.TimeInfo.UsecSinceStart = (ulong)Util.UnixTimeSinceEpoch();
|
viewertime.TimeInfo.UsecSinceStart = (ulong)Util.UnixTimeSinceEpoch();
|
||||||
viewertime.Header.Reliable = false;
|
viewertime.Header.Reliable = false;
|
||||||
OutPacket(viewertime, ThrottleOutPacketType.Task);
|
OutPacket(viewertime, ThrottleOutPacketType.Task);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendAvatarProperties(LLUUID avatarID, string aboutText, string bornOn, string charterMember,
|
public void SendAvatarProperties(LLUUID avatarID, string aboutText, string bornOn, string charterMember,
|
||||||
|
|
|
@ -33,45 +33,136 @@ using OpenSim.Framework;
|
||||||
using OpenSim.Region.Environment.Interfaces;
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
using OpenSim.Region.Environment.Scenes;
|
using OpenSim.Region.Environment.Scenes;
|
||||||
|
|
||||||
namespace OpenSim.Region.Environment.Modules.World.Sun
|
namespace OpenSim.Region.Environment.Modules
|
||||||
{
|
{
|
||||||
public class SunModule : IRegionModule
|
public class SunModule : IRegionModule
|
||||||
{
|
{
|
||||||
//private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
private const int m_default_frame = 100;
|
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
private const double m_real_day = 24.0;
|
|
||||||
private double m_day_length;
|
|
||||||
private int m_dilation;
|
|
||||||
private int m_frame;
|
|
||||||
private int m_frame_mod;
|
|
||||||
|
|
||||||
private Scene m_scene;
|
private const double SeasonalTilt = 0.03 * Math.PI; // A daily shift of approximately 1.7188 degrees
|
||||||
private long m_start;
|
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
|
||||||
|
|
||||||
#region IRegionModule Members
|
//
|
||||||
|
// Per Region Values
|
||||||
|
//
|
||||||
|
|
||||||
|
private bool ready = false;
|
||||||
|
|
||||||
|
// Configurable values
|
||||||
|
private int m_frame_mod = 0;
|
||||||
|
private double m_day_length = 0;
|
||||||
|
private int m_year_length = 0;
|
||||||
|
private double m_day_night = 0;
|
||||||
|
// Configurable defaults Defaults close to SL
|
||||||
|
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
|
||||||
|
|
||||||
|
// Frame counter
|
||||||
|
private uint m_frame = 0;
|
||||||
|
|
||||||
|
// Cached Scene reference
|
||||||
|
private Scene m_scene = null;
|
||||||
|
|
||||||
|
// Calculated Once in the lifetime of a region
|
||||||
|
private ulong TicksToEpoch; // Elapsed time for 1/1/1970
|
||||||
|
private uint SecondsPerSunCycle; // Length of a virtual day in RW seconds
|
||||||
|
private uint SecondsPerYear; // Length of a virtual year in RW seconds
|
||||||
|
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
|
||||||
|
|
||||||
|
// Calculated every update
|
||||||
|
private float OrbitalPosition; // Orbital placement at a point in time
|
||||||
|
private double HorizonShift; // Axis offset to skew day and night
|
||||||
|
private double TotalDistanceTravelled; // Distance since beginning of time (in radians)
|
||||||
|
private double SeasonalOffset; // Seaonal variation of tilt
|
||||||
|
private float Magnitude; // Normal tilt
|
||||||
|
private double VWTimeRatio; // VW time as a ratio of real time
|
||||||
|
|
||||||
|
// Working values
|
||||||
|
private LLVector3 Position = new LLVector3(0,0,0);
|
||||||
|
private LLVector3 Velocity = new LLVector3(0,0,0);
|
||||||
|
private LLQuaternion Tilt = new LLQuaternion(1,0,0,0);
|
||||||
|
|
||||||
|
// Current time in elpased seconds since Jan 1st 1970
|
||||||
|
private ulong CurrentTime
|
||||||
|
{
|
||||||
|
get { return (ulong)((((ulong)System.DateTime.Now.Ticks)-TicksToEpoch)/10000000); }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called immediately after the module is loaded for a given region
|
||||||
|
// i.e. Immediately after instance creation.
|
||||||
|
|
||||||
public void Initialise(Scene scene, IConfigSource config)
|
public void Initialise(Scene scene, IConfigSource config)
|
||||||
{
|
{
|
||||||
m_start = DateTime.Now.Ticks;
|
|
||||||
|
m_log.Debug("[SUN] Initializing");
|
||||||
|
|
||||||
|
m_scene = scene;
|
||||||
|
|
||||||
m_frame = 0;
|
m_frame = 0;
|
||||||
|
|
||||||
|
// Align ticks with Second Life
|
||||||
|
|
||||||
|
TicksToEpoch = (ulong) new System.DateTime(1970,1,1).Ticks;
|
||||||
|
|
||||||
// Just in case they don't have the stanzas
|
// Just in case they don't have the stanzas
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_day_length = config.Configs["Sun"].GetDouble("day_length", m_real_day);
|
// Day length in decimal hours
|
||||||
m_frame_mod = config.Configs["Sun"].GetInt("frame_rate", m_default_frame);
|
m_year_length = 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);
|
||||||
|
// Day to Night Ratio
|
||||||
|
m_day_night = 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);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_day_length = m_real_day;
|
m_log.Debug("[SUN] Configuration access failed, using defaults. Reason: "+e.Message);
|
||||||
m_frame_mod = m_default_frame;
|
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_dilation = (int) (m_real_day / m_day_length);
|
// Time taken to complete a cycle (day and season)
|
||||||
m_scene = scene;
|
|
||||||
scene.EventManager.OnFrame += SunUpdate;
|
SecondsPerSunCycle = (uint) (m_day_length * 60 * 60);
|
||||||
|
SecondsPerYear = (uint) (SecondsPerSunCycle*m_year_length);
|
||||||
|
|
||||||
|
// Ration of real-to-virtual time
|
||||||
|
|
||||||
|
VWTimeRatio = 24/m_day_length;
|
||||||
|
|
||||||
|
// Speed of rotation needed to complete a cycle in the
|
||||||
|
// designated period (day and season)
|
||||||
|
|
||||||
|
SunSpeed = SunCycle/SecondsPerSunCycle;
|
||||||
|
SeasonSpeed = SeasonalCycle/SecondsPerYear;
|
||||||
|
|
||||||
|
// Horizon translation
|
||||||
|
|
||||||
|
HorizonShift = m_day_night; // Z axis translation
|
||||||
|
HoursToRadians = (SunCycle/24)*VWTimeRatio;
|
||||||
|
|
||||||
|
// Insert our event handling hooks
|
||||||
|
|
||||||
|
scene.EventManager.OnFrame += SunUpdate;
|
||||||
scene.EventManager.OnNewClient += SunToClient;
|
scene.EventManager.OnNewClient += SunToClient;
|
||||||
|
|
||||||
|
ready = true;
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PostInitialise()
|
public void PostInitialise()
|
||||||
|
@ -80,6 +171,10 @@ namespace OpenSim.Region.Environment.Modules.World.Sun
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
|
ready = false;
|
||||||
|
// Remove our hooks
|
||||||
|
m_scene.EventManager.OnFrame -= SunUpdate;
|
||||||
|
m_scene.EventManager.OnNewClient -= SunToClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
|
@ -92,51 +187,88 @@ namespace OpenSim.Region.Environment.Modules.World.Sun
|
||||||
get { return false; }
|
get { return false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
public void SunToClient(IClientAPI client)
|
public void SunToClient(IClientAPI client)
|
||||||
{
|
{
|
||||||
client.SendSunPos(SunPos(HourOfTheDay()), new LLVector3(0, 0.0f, 10.0f));
|
if(ready)
|
||||||
|
{
|
||||||
|
GenSunPos(); // Generate shared values once
|
||||||
|
client.SendSunPos(Position, Velocity, CurrentTime, SecondsPerSunCycle, SecondsPerYear, OrbitalPosition);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SunUpdate()
|
public void SunUpdate()
|
||||||
{
|
{
|
||||||
if (m_frame < m_frame_mod)
|
|
||||||
|
if(((m_frame++%m_frame_mod) != 0) || !ready)
|
||||||
{
|
{
|
||||||
m_frame++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// m_log.InfoFormat("[SUN]: I've got an update {0} => {1}", m_scene.RegionsInfo.RegionName, HourOfTheDay());
|
|
||||||
|
GenSunPos(); // Generate shared values once
|
||||||
|
|
||||||
List<ScenePresence> avatars = m_scene.GetAvatars();
|
List<ScenePresence> avatars = m_scene.GetAvatars();
|
||||||
foreach (ScenePresence avatar in avatars)
|
foreach (ScenePresence avatar in avatars)
|
||||||
{
|
{
|
||||||
avatar.ControllingClient.SendSunPos(SunPos(HourOfTheDay()), new LLVector3(0, 0.0f, 10.0f));
|
avatar.ControllingClient.SendSunPos(Position, Velocity, CurrentTime, SecondsPerSunCycle, SecondsPerYear, OrbitalPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set estate settings for region access to sun position
|
// set estate settings for region access to sun position
|
||||||
m_scene.RegionInfo.EstateSettings.sunPosition = SunPos(HourOfTheDay());
|
m_scene.RegionInfo.EstateSettings.sunPosition = Position;
|
||||||
|
|
||||||
m_frame = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hour of the Day figures out the hour of the day as a float.
|
/// <summary>
|
||||||
// The intent here is that we seed hour of the day with real
|
/// Calculate the sun's orbital position and its velocity.
|
||||||
// time when the simulator starts, then run time forward
|
/// </summary>
|
||||||
// faster based on time dilation factor. This means that
|
|
||||||
// ticks don't get out of hand
|
|
||||||
private double HourOfTheDay()
|
|
||||||
{
|
|
||||||
long m_addticks = (DateTime.Now.Ticks - m_start) * m_dilation;
|
|
||||||
DateTime dt = new DateTime(m_start + m_addticks);
|
|
||||||
return dt.Hour + (dt.Minute / 60.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static LLVector3 SunPos(double hour)
|
private void GenSunPos()
|
||||||
{
|
{
|
||||||
// now we have our radian position
|
|
||||||
double rad = (hour / m_real_day) * 2 * Math.PI - (Math.PI / 2.0);
|
TotalDistanceTravelled = SunSpeed * CurrentTime; // distance measured in radians
|
||||||
double z = Math.Sin(rad);
|
OrbitalPosition = (float) (TotalDistanceTravelled%SunCycle); // position measured in radians
|
||||||
double x = Math.Cos(rad);
|
|
||||||
return new LLVector3((float) x, 0f, (float) z);
|
// 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 = LLVector3.Rot(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 = LLVector3.Norm(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 = LLVector3.Mag(Position);
|
||||||
|
|
||||||
|
Velocity = LLVector3.Rot(Velocity, Tilt)*((float)(1.0/Magnitude));
|
||||||
|
|
||||||
|
// m_log.Debug("[SUN] Velocity("+Velocity.X+","+Velocity.Y+","+Velocity.Z+")");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -573,7 +573,7 @@ namespace OpenSim.Region.Examples.SimpleModule
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendSunPos(LLVector3 sunPos, LLVector3 sunVel)
|
public void SendSunPos(LLVector3 sunPos, LLVector3 sunVel, ulong time, uint dlen, uint ylen, float phase)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue