From 54a27f9f5c556e518c2ba18b9a5494d517dfd041 Mon Sep 17 00:00:00 2001 From: Charles Krinke Date: Tue, 31 Mar 2009 02:33:19 +0000 Subject: Thank you kindly, MCortez for a patch that: With some support from HomerH, this patch adds support for Wind Model plugins via the mono.Addin framework. * Adds console & OSSL access to Wind Parameters * Adds plug-in support for custom wind models * Provides two example Wind Model plug-ins Documentation for the wind module is temporarily located at http://code.google.com/p/flotsam/wiki/CoreWindModule [^] -- will move this documentation to http://opensimulator.org [^] after the patch has been committed. --- .../World/Wind/Plugins/ConfigurableWind.cs | 211 +++++++++++++++++++++ .../World/Wind/Plugins/SimpleRandomWind.cs | 139 ++++++++++++++ 2 files changed, 350 insertions(+) create mode 100644 OpenSim/Region/CoreModules/World/Wind/Plugins/ConfigurableWind.cs create mode 100644 OpenSim/Region/CoreModules/World/Wind/Plugins/SimpleRandomWind.cs (limited to 'OpenSim/Region/CoreModules/World/Wind/Plugins') diff --git a/OpenSim/Region/CoreModules/World/Wind/Plugins/ConfigurableWind.cs b/OpenSim/Region/CoreModules/World/Wind/Plugins/ConfigurableWind.cs new file mode 100644 index 0000000..2f5cc31 --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Wind/Plugins/ConfigurableWind.cs @@ -0,0 +1,211 @@ +using System; +using System.Collections.Generic; +using System.Reflection; + +using log4net; +using OpenMetaverse; + +using OpenSim.Region.CoreModules.World.Wind; + +namespace OpenSim.Region.CoreModules.World.Wind.Plugins +{ + class ConfigurableWind : Mono.Addins.TypeExtensionNode, IWindModelPlugin + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private Vector2[] m_windSpeeds = new Vector2[16 * 16]; + private Random m_rndnums = new Random(Environment.TickCount); + + private float m_avgStrength = 5.0f; // Average magnitude of the wind vector + private float m_avgDirection = 0.0f; // Average direction of the wind in degrees + private float m_varStrength = 5.0f; // Max Strength Variance + private float m_varDirection = 30.0f;// Max Direction Variance + private float m_rateChange = 1.0f; // + + private Vector2 m_curPredominateWind = new Vector2(); + + + + #region IPlugin Members + + public string Version + { + get { return "1.0.0.0"; } + } + + public string Name + { + get { return "ConfigurableWind"; } + } + + public void Initialise() + { + + } + + #endregion + + #region IDisposable Members + + public void Dispose() + { + m_windSpeeds = null; + } + + #endregion + + #region IWindModelPlugin Members + + public void WindConfig(OpenSim.Region.Framework.Scenes.Scene scene, Nini.Config.IConfig windConfig) + { + if( windConfig != null ) + { + // Uses strength value if avg_strength not specified + m_avgStrength = windConfig.GetFloat("strength", 5.0F); + m_avgStrength = windConfig.GetFloat("avg_strength", 5.0F); + + m_avgDirection = windConfig.GetFloat("avg_direction", 0.0F); + m_varStrength = windConfig.GetFloat("var_strength", 5.0F); + m_varDirection = windConfig.GetFloat("var_direction", 30.0F); + m_rateChange = windConfig.GetFloat("rate_change", 1.0F); + + LogSettings(); + } + } + + public void WindUpdate(uint frame) + { + double avgAng = m_avgDirection * (Math.PI/180.0f); + double varDir = m_varDirection * (Math.PI/180.0f); + + // Prevailing wind algorithm + // Inspired by Kanker Greenacre + + // TODO: + // * This should probably be based on in-world time. + // * should probably move all these local variables to class members and constants + double time = DateTime.Now.TimeOfDay.Seconds / 86400; + + double theta = time * (2 * Math.PI) * m_rateChange; + + double offset = Math.Sin(theta) * Math.Sin(theta*2) * Math.Sin(theta*9) * Math.Cos(theta*4); + + double windDir = avgAng + (varDir * offset); + + offset = Math.Sin(theta) * Math.Sin(theta*4) + (Math.Sin(theta*13) / 3); + double windSpeed = m_avgStrength + (m_varStrength * offset); + + if (windSpeed<0) + windSpeed=0; + + + + m_curPredominateWind.X = (float)Math.Cos(windDir); + m_curPredominateWind.Y = (float)Math.Sin(windDir); + + m_curPredominateWind.Normalize(); + m_curPredominateWind.X *= (float)windSpeed; + m_curPredominateWind.Y *= (float)windSpeed; + + for (int y = 0; y < 16; y++) + { + for (int x = 0; x < 16; x++) + { + m_windSpeeds[y * 16 + x] = m_curPredominateWind; + } + } + } + + public Vector3 WindSpeed(float fX, float fY, float fZ) + { + return new Vector3(m_curPredominateWind, 0.0f); + } + + public Vector2[] WindLLClientArray() + { + return m_windSpeeds; + } + + public string Description + { + get + { + return "Provides a predominate wind direction that can change within configured variances for direction and speed."; + } + } + + public System.Collections.Generic.Dictionary WindParams() + { + Dictionary Params = new Dictionary(); + + Params.Add("avgStrength", "average wind strength"); + Params.Add("avgDirection", "average wind direction in degrees"); + Params.Add("varStrength", "allowable variance in wind strength"); + Params.Add("varDirection", "allowable variance in wind direction in +/- degrees"); + Params.Add("rateChange", "rate of change"); + + return Params; + } + + public void WindParamSet(string param, float value) + { + switch (param) + { + case "avgStrength": + m_avgStrength = value; + break; + case "avgDirection": + m_avgDirection = value; + break; + case "varStrength": + m_varStrength = value; + break; + case "varDirection": + m_varDirection = value; + break; + case "rateChange": + m_rateChange = value; + break; + } + } + + public float WindParamGet(string param) + { + switch (param) + { + case "avgStrength": + return m_avgStrength; + case "avgDirection": + return m_avgDirection; + case "varStrength": + return m_varStrength; + case "varDirection": + return m_varDirection; + case "rateChange": + return m_rateChange; + default: + throw new Exception(String.Format("Unknown {0} parameter {1}", this.Name, param)); + + } + } + + + + #endregion + + + private void LogSettings() + { + m_log.InfoFormat("[ConfigurableWind] Average Strength : {0}", m_avgStrength); + m_log.InfoFormat("[ConfigurableWind] Average Direction : {0}", m_avgDirection); + m_log.InfoFormat("[ConfigurableWind] Varience Strength : {0}", m_varStrength); + m_log.InfoFormat("[ConfigurableWind] Varience Direction : {0}", m_varDirection); + m_log.InfoFormat("[ConfigurableWind] Rate Change : {0}", m_rateChange); + } + + #region IWindModelPlugin Members + + + #endregion + } +} diff --git a/OpenSim/Region/CoreModules/World/Wind/Plugins/SimpleRandomWind.cs b/OpenSim/Region/CoreModules/World/Wind/Plugins/SimpleRandomWind.cs new file mode 100644 index 0000000..040a3c4 --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Wind/Plugins/SimpleRandomWind.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; + +using OpenMetaverse; + + +namespace OpenSim.Region.CoreModules.World.Wind.Plugins +{ + class SimpleRandomWind : Mono.Addins.TypeExtensionNode, IWindModelPlugin + { + private Vector2[] m_windSpeeds = new Vector2[16 * 16]; + private float m_strength = 1.0f; + private Random m_rndnums = new Random(Environment.TickCount); + + + #region IPlugin Members + + public string Version + { + get { return "1.0.0.0"; } + } + + public string Name + { + get { return "SimpleRandomWind"; } + } + + public void Initialise() + { + + } + + #endregion + + #region IDisposable Members + + public void Dispose() + { + m_windSpeeds = null; + } + + #endregion + + #region IWindModelPlugin Members + + public void WindConfig(OpenSim.Region.Framework.Scenes.Scene scene, Nini.Config.IConfig windConfig) + { + if( windConfig != null ) + { + if( windConfig.Contains("strength") ) + { + m_strength = windConfig.GetFloat("strength", 1.0F); + } + } + } + + public void WindUpdate(uint frame) + { + for (int y = 0; y < 16; y++) + { + for (int x = 0; x < 16; x++) + { + m_windSpeeds[y * 16 + x].X = (float)(m_rndnums.NextDouble() * 2d - 1d); // -1 to 1 + m_windSpeeds[y * 16 + x].Y = (float)(m_rndnums.NextDouble() * 2d - 1d); // -1 to 1 + m_windSpeeds[y * 16 + x].X *= m_strength; + m_windSpeeds[y * 16 + x].Y *= m_strength; + } + } + } + + public Vector3 WindSpeed(float fX, float fY, float fZ) + { + Vector3 windVector = new Vector3(0.0f, 0.0f, 0.0f); + + int x = (int)fX / 16; + int y = (int)fY / 16; + + if (x < 0) x = 0; + if (x > 15) x = 15; + if (y < 0) y = 0; + if (y > 15) y = 15; + + if (m_windSpeeds != null) + { + windVector.X = m_windSpeeds[y * 16 + x].X; + windVector.Y = m_windSpeeds[y * 16 + x].Y; + } + + return windVector; + + } + + public Vector2[] WindLLClientArray() + { + return m_windSpeeds; + } + + public string Description + { + get + { + return "Provides a simple wind model that creates random wind of a given strength in 16m x 16m patches."; + } + } + + public System.Collections.Generic.Dictionary WindParams() + { + Dictionary Params = new Dictionary(); + + Params.Add("strength", "wind strength"); + + return Params; + } + + public void WindParamSet(string param, float value) + { + switch (param) + { + case "strength": + m_strength = value; + break; + } + } + + public float WindParamGet(string param) + { + switch (param) + { + case "strength": + return m_strength; + default: + throw new Exception(String.Format("Unknown {0} parameter {1}", this.Name, param)); + } + } + + #endregion + + } +} -- cgit v1.1