Merge branch 'master' of /home/opensim/var/repo/opensim
						commit
						0b2e8421ce
					
				|  | @ -2202,5 +2202,18 @@ VALUES | |||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void SaveExtra(UUID regionID, string name, string value) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public void RemoveExtra(UUID regionID, string name) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public Dictionary<string, string> GetExtra(UUID regionID) | ||||
|         { | ||||
|             return null; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1966,5 +1966,74 @@ namespace OpenSim.Data.MySQL | |||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void SaveExtra(UUID regionID, string name, string val) | ||||
|         { | ||||
|             lock (m_dbLock) | ||||
|             { | ||||
|                 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||||
|                 { | ||||
|                     dbcon.Open(); | ||||
| 
 | ||||
|                     using (MySqlCommand cmd = dbcon.CreateCommand()) | ||||
|                     { | ||||
|                         cmd.CommandText = "replace into regionextra values (?RegionID, ?Name, ?value)"; | ||||
|                         cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); | ||||
|                         cmd.Parameters.AddWithValue("?Name", name); | ||||
|                         cmd.Parameters.AddWithValue("?value", val); | ||||
| 
 | ||||
|                         cmd.ExecuteNonQuery(); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void RemoveExtra(UUID regionID, string name) | ||||
|         { | ||||
|             lock (m_dbLock) | ||||
|             { | ||||
|                 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||||
|                 { | ||||
|                     dbcon.Open(); | ||||
| 
 | ||||
|                     using (MySqlCommand cmd = dbcon.CreateCommand()) | ||||
|                     { | ||||
|                         cmd.CommandText = "delete from regionextra where RegionID=?RegionID and Name=?Name"; | ||||
|                         cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); | ||||
|                         cmd.Parameters.AddWithValue("?Name", name); | ||||
| 
 | ||||
|                         cmd.ExecuteNonQuery(); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public Dictionary<string, string> GetExtra(UUID regionID) | ||||
|         { | ||||
|             Dictionary<string, string> ret = new Dictionary<string, string>(); | ||||
| 
 | ||||
|             lock (m_dbLock) | ||||
|             { | ||||
|                 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||||
|                 { | ||||
|                     dbcon.Open(); | ||||
| 
 | ||||
|                     using (MySqlCommand cmd = dbcon.CreateCommand()) | ||||
|                     { | ||||
|                         cmd.CommandText = "select * from regionextra where RegionID=?RegionID"; | ||||
|                         cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); | ||||
|                         using (IDataReader r = cmd.ExecuteReader()) | ||||
|                         { | ||||
|                             while (r.Read()) | ||||
|                             { | ||||
|                                 ret[r["Name"].ToString()] = r["value"].ToString(); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             return ret; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -895,3 +895,10 @@ CREATE TABLE `regionenvironment` ( | |||
| 
 | ||||
| COMMIT; | ||||
| 
 | ||||
| :VERSION 45 | ||||
| 
 | ||||
| BEGIN; | ||||
| 
 | ||||
| CREATE TABLE `regionextra` (`RegionID` char(36) not null, `Name` varchar(32) not null, `value` text, primary key(`RegionID`, `Name`)); | ||||
| 
 | ||||
| COMMIT; | ||||
|  |  | |||
|  | @ -151,5 +151,18 @@ namespace OpenSim.Data.Null | |||
|         public void Shutdown() | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public void SaveExtra(UUID regionID, string name, string value) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public void RemoveExtra(UUID regionID, string name) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public Dictionary<string, string> GetExtra(UUID regionID) | ||||
|         { | ||||
|             return null; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -2890,5 +2890,17 @@ namespace OpenSim.Data.SQLite | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void SaveExtra(UUID regionID, string name, string value) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public void RemoveExtra(UUID regionID, string name) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public Dictionary<string, string> GetExtra(UUID regionID) | ||||
|         { | ||||
|             return null; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -199,7 +199,14 @@ namespace OpenSim.Framework | |||
|     // | ||||
|     public class Cache | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Must only be accessed under lock. | ||||
|         /// </summary> | ||||
|         private List<CacheItemBase> m_Index = new List<CacheItemBase>(); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Must only be accessed under m_Index lock. | ||||
|         /// </summary> | ||||
|         private Dictionary<string, CacheItemBase> m_Lookup = | ||||
|             new Dictionary<string, CacheItemBase>(); | ||||
| 
 | ||||
|  | @ -320,19 +327,19 @@ namespace OpenSim.Framework | |||
|             { | ||||
|                 if (m_Lookup.ContainsKey(index)) | ||||
|                     item = m_Lookup[index]; | ||||
|             } | ||||
| 
 | ||||
|             if (item == null) | ||||
|             { | ||||
|                 if (item == null) | ||||
|                 { | ||||
|                     Expire(true); | ||||
|                     return null; | ||||
|                 } | ||||
|      | ||||
|                 item.hits++; | ||||
|                 item.lastUsed = DateTime.Now; | ||||
|      | ||||
|                 Expire(true); | ||||
|                 return null; | ||||
|             } | ||||
| 
 | ||||
|             item.hits++; | ||||
|             item.lastUsed = DateTime.Now; | ||||
| 
 | ||||
|             Expire(true); | ||||
| 
 | ||||
|             return item; | ||||
|         } | ||||
| 
 | ||||
|  | @ -385,7 +392,10 @@ namespace OpenSim.Framework | |||
|         // | ||||
|         public Object Find(Predicate<CacheItemBase> d) | ||||
|         { | ||||
|             CacheItemBase item = m_Index.Find(d); | ||||
|             CacheItemBase item; | ||||
| 
 | ||||
|             lock (m_Index) | ||||
|                 item = m_Index.Find(d); | ||||
| 
 | ||||
|             if (item == null) | ||||
|                 return null; | ||||
|  | @ -419,12 +429,12 @@ namespace OpenSim.Framework | |||
|         public virtual void Store(string index, Object data, Type container, | ||||
|                 Object[] parameters) | ||||
|         { | ||||
|             Expire(false); | ||||
| 
 | ||||
|             CacheItemBase item; | ||||
| 
 | ||||
|             lock (m_Index) | ||||
|             { | ||||
|                 Expire(false); | ||||
| 
 | ||||
|                 if (m_Index.Contains(new CacheItemBase(index))) | ||||
|                 { | ||||
|                     if ((m_Flags & CacheFlags.AllowUpdate) != 0) | ||||
|  | @ -450,9 +460,17 @@ namespace OpenSim.Framework | |||
|                 m_Index.Add(item); | ||||
|                 m_Lookup[index] = item; | ||||
|             } | ||||
| 
 | ||||
|             item.Store(data); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Expire items as appropriate. | ||||
|         /// </summary> | ||||
|         /// <remarks> | ||||
|         /// Callers must lock m_Index. | ||||
|         /// </remarks> | ||||
|         /// <param name='getting'></param> | ||||
|         protected virtual void Expire(bool getting) | ||||
|         { | ||||
|             if (getting && (m_Strategy == CacheStrategy.Aggressive)) | ||||
|  | @ -475,12 +493,10 @@ namespace OpenSim.Framework | |||
| 
 | ||||
|             switch (m_Strategy) | ||||
|             { | ||||
|             case CacheStrategy.Aggressive: | ||||
|                 if (Count < Size) | ||||
|                     return; | ||||
|                 case CacheStrategy.Aggressive: | ||||
|                     if (Count < Size) | ||||
|                         return; | ||||
| 
 | ||||
|                 lock (m_Index) | ||||
|                 { | ||||
|                     m_Index.Sort(new SortLRU()); | ||||
|                     m_Index.Reverse(); | ||||
| 
 | ||||
|  | @ -490,7 +506,7 @@ namespace OpenSim.Framework | |||
| 
 | ||||
|                     ExpireDelegate doExpire = OnExpire; | ||||
| 
 | ||||
|                 if (doExpire != null) | ||||
|                     if (doExpire != null) | ||||
|                     { | ||||
|                         List<CacheItemBase> candidates = | ||||
|                                 m_Index.GetRange(target, Count - target); | ||||
|  | @ -513,27 +529,34 @@ namespace OpenSim.Framework | |||
|                         foreach (CacheItemBase item in m_Index) | ||||
|                             m_Lookup[item.uuid] = item; | ||||
|                     } | ||||
|                 } | ||||
|                 break; | ||||
|             default: | ||||
|                 break; | ||||
| 
 | ||||
|                     break; | ||||
| 
 | ||||
|                     default: | ||||
|                         break; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void Invalidate(string uuid) | ||||
|         { | ||||
|             if (!m_Lookup.ContainsKey(uuid)) | ||||
|                 return; | ||||
|             lock (m_Index) | ||||
|             { | ||||
|                 if (!m_Lookup.ContainsKey(uuid)) | ||||
|                     return; | ||||
| 
 | ||||
|             CacheItemBase item = m_Lookup[uuid]; | ||||
|             m_Lookup.Remove(uuid); | ||||
|             m_Index.Remove(item); | ||||
|                 CacheItemBase item = m_Lookup[uuid]; | ||||
|                 m_Lookup.Remove(uuid); | ||||
|                 m_Index.Remove(item); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void Clear() | ||||
|         { | ||||
|             m_Index.Clear(); | ||||
|             m_Lookup.Clear(); | ||||
|             lock (m_Index) | ||||
|             { | ||||
|                 m_Index.Clear(); | ||||
|                 m_Lookup.Clear(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
|  | @ -678,6 +678,8 @@ namespace OpenSim.Framework.Console | |||
|     { | ||||
| //        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
| 
 | ||||
|         public event OnOutputDelegate OnOutput; | ||||
| 
 | ||||
|         public ICommands Commands { get; private set; } | ||||
| 
 | ||||
|         public CommandConsole(string defaultPrompt) : base(defaultPrompt) | ||||
|  | @ -697,6 +699,13 @@ namespace OpenSim.Framework.Console | |||
|                 Output(s); | ||||
|         } | ||||
| 
 | ||||
|         protected void FireOnOutput(string text) | ||||
|         { | ||||
|             OnOutputDelegate onOutput = OnOutput; | ||||
|             if (onOutput != null) | ||||
|                 onOutput(text); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Display a command prompt on the console and wait for user input | ||||
|         /// </summary> | ||||
|  |  | |||
|  | @ -319,6 +319,8 @@ namespace OpenSim.Framework.Console | |||
| 
 | ||||
|         public override void Output(string text, string level) | ||||
|         { | ||||
|             FireOnOutput(text); | ||||
| 
 | ||||
|             lock (m_commandLine) | ||||
|             { | ||||
|                 if (m_cursorYPosition == -1) | ||||
|  | @ -509,4 +511,4 @@ namespace OpenSim.Framework.Console | |||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
|  |  | |||
|  | @ -40,6 +40,8 @@ namespace OpenSim.Framework.Console | |||
|     /// </summary> | ||||
|     public class MockConsole : ICommandConsole | ||||
|     { | ||||
|         public event OnOutputDelegate OnOutput; | ||||
| 
 | ||||
|         private MockCommands m_commands = new MockCommands(); | ||||
| 
 | ||||
|         public ICommands Commands { get { return m_commands; } } | ||||
|  | @ -76,4 +78,4 @@ namespace OpenSim.Framework.Console | |||
|         public string[] Resolve(string[] cmd) { return null; } | ||||
|         public XmlElement GetXml(XmlDocument doc) { return null; } | ||||
|     } | ||||
| } | ||||
| } | ||||
|  |  | |||
|  | @ -100,6 +100,7 @@ namespace OpenSim.Framework.Console | |||
|                 m_LineNumber++; | ||||
|                 m_Scrollback.Add(String.Format("{0}", m_LineNumber)+":"+level+":"+text); | ||||
|             } | ||||
|             FireOnOutput(text.Trim()); | ||||
|             System.Console.WriteLine(text.Trim()); | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1033,7 +1033,21 @@ namespace OpenSim.Framework | |||
| 
 | ||||
|         void InPacket(object NewPack); | ||||
|         void ProcessInPacket(Packet NewPack); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Close this client | ||||
|         /// </summary> | ||||
|         void Close(); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Close this client | ||||
|         /// </summary> | ||||
|         /// <param name='force'> | ||||
|         /// If true, attempts the close without checking active status.  You do not want to try this except as a last | ||||
|         /// ditch attempt where Active == false but the ScenePresence still exists. | ||||
|         /// </param> | ||||
|         void Close(bool force); | ||||
| 
 | ||||
|         void Kick(string message); | ||||
|          | ||||
|         /// <summary> | ||||
|  |  | |||
|  | @ -74,8 +74,12 @@ namespace OpenSim.Framework | |||
|         XmlElement GetXml(XmlDocument doc); | ||||
|     } | ||||
| 
 | ||||
|     public delegate void OnOutputDelegate(string message); | ||||
| 
 | ||||
|     public interface ICommandConsole : IConsole | ||||
|     { | ||||
|         event OnOutputDelegate OnOutput; | ||||
| 
 | ||||
|         ICommands Commands { get; } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -87,4 +91,4 @@ namespace OpenSim.Framework | |||
| 
 | ||||
|         string ReadLine(string p, bool isCommand, bool e); | ||||
|     } | ||||
| } | ||||
| } | ||||
|  |  | |||
|  | @ -89,6 +89,17 @@ namespace OpenSim.Framework.Monitoring | |||
|                 FirstTick = Environment.TickCount & Int32.MaxValue; | ||||
|                 LastTick = FirstTick; | ||||
|             } | ||||
| 
 | ||||
|             public ThreadWatchdogInfo(ThreadWatchdogInfo previousTwi) | ||||
|             { | ||||
|                 Thread = previousTwi.Thread; | ||||
|                 FirstTick = previousTwi.FirstTick; | ||||
|                 LastTick = previousTwi.LastTick; | ||||
|                 Timeout = previousTwi.Timeout; | ||||
|                 IsTimedOut = previousTwi.IsTimedOut; | ||||
|                 AlarmIfTimeout = previousTwi.AlarmIfTimeout; | ||||
|                 AlarmMethod = previousTwi.AlarmMethod; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -97,6 +108,32 @@ namespace OpenSim.Framework.Monitoring | |||
|         /// /summary> | ||||
|         public static event Action<ThreadWatchdogInfo> OnWatchdogTimeout; | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Is this watchdog active? | ||||
|         /// </summary> | ||||
|         public static bool Enabled | ||||
|         { | ||||
|             get { return m_enabled; } | ||||
|             set | ||||
|             { | ||||
| //                m_log.DebugFormat("[MEMORY WATCHDOG]: Setting MemoryWatchdog.Enabled to {0}", value); | ||||
| 
 | ||||
|                 if (value == m_enabled) | ||||
|                     return; | ||||
| 
 | ||||
|                 m_enabled = value; | ||||
| 
 | ||||
|                 if (m_enabled) | ||||
|                 { | ||||
|                     // Set now so we don't get alerted on the first run | ||||
|                     LastWatchdogThreadTick = Environment.TickCount & Int32.MaxValue; | ||||
|                 } | ||||
| 
 | ||||
|                 m_watchdogTimer.Enabled = m_enabled; | ||||
|             } | ||||
|         } | ||||
|         private static bool m_enabled; | ||||
| 
 | ||||
|         private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||||
|         private static Dictionary<int, ThreadWatchdogInfo> m_threads; | ||||
|         private static System.Timers.Timer m_watchdogTimer; | ||||
|  | @ -115,11 +152,6 @@ namespace OpenSim.Framework.Monitoring | |||
|             m_watchdogTimer = new System.Timers.Timer(WATCHDOG_INTERVAL_MS); | ||||
|             m_watchdogTimer.AutoReset = false; | ||||
|             m_watchdogTimer.Elapsed += WatchdogTimerElapsed; | ||||
| 
 | ||||
|             // Set now so we don't get alerted on the first run | ||||
|             LastWatchdogThreadTick = Environment.TickCount & Int32.MaxValue; | ||||
| 
 | ||||
|             m_watchdogTimer.Start(); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -314,7 +346,9 @@ namespace OpenSim.Framework.Monitoring | |||
|                                 if (callbackInfos == null) | ||||
|                                     callbackInfos = new List<ThreadWatchdogInfo>(); | ||||
| 
 | ||||
|                                 callbackInfos.Add(threadInfo); | ||||
|                                 // Send a copy of the watchdog info to prevent race conditions where the watchdog | ||||
|                                 // thread updates the monitoring info after an alarm has been sent out. | ||||
|                                 callbackInfos.Add(new ThreadWatchdogInfo(threadInfo)); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|  |  | |||
|  | @ -120,7 +120,9 @@ namespace OpenSim.Framework | |||
|         public UUID lastMapUUID = UUID.Zero; | ||||
|         public string lastMapRefresh = "0"; | ||||
| 
 | ||||
|         private float m_nonphysPrimMin = 0; | ||||
|         private int m_nonphysPrimMax = 0; | ||||
|         private float m_physPrimMin = 0; | ||||
|         private int m_physPrimMax = 0; | ||||
|         private bool m_clampPrimSize = false; | ||||
|         private int m_objectCapacity = 0; | ||||
|  | @ -285,11 +287,21 @@ namespace OpenSim.Framework | |||
|             set { m_windlight = value; } | ||||
|         } | ||||
| 
 | ||||
|         public float NonphysPrimMin | ||||
|         { | ||||
|             get { return m_nonphysPrimMin; } | ||||
|         } | ||||
| 
 | ||||
|         public int NonphysPrimMax | ||||
|         { | ||||
|             get { return m_nonphysPrimMax; } | ||||
|         } | ||||
| 
 | ||||
|         public float PhysPrimMin | ||||
|         { | ||||
|             get { return m_physPrimMin; } | ||||
|         } | ||||
| 
 | ||||
|         public int PhysPrimMax | ||||
|         { | ||||
|             get { return m_physPrimMax; } | ||||
|  | @ -623,16 +635,28 @@ namespace OpenSim.Framework | |||
|             m_regionType = config.GetString("RegionType", String.Empty); | ||||
|             allKeys.Remove("RegionType"); | ||||
| 
 | ||||
|             // Prim stuff | ||||
|             // | ||||
|             #region Prim stuff | ||||
| 
 | ||||
|             m_nonphysPrimMin = config.GetFloat("NonphysicalPrimMin", 0); | ||||
|             allKeys.Remove("NonphysicalPrimMin"); | ||||
| 
 | ||||
|             m_nonphysPrimMax = config.GetInt("NonphysicalPrimMax", 0); | ||||
|             allKeys.Remove("NonphysicalPrimMax"); | ||||
| 
 | ||||
|             m_physPrimMin = config.GetFloat("PhysicalPrimMin", 0); | ||||
|             allKeys.Remove("PhysicalPrimMin"); | ||||
| 
 | ||||
|             m_physPrimMax = config.GetInt("PhysicalPrimMax", 0); | ||||
|             allKeys.Remove("PhysicalPrimMax"); | ||||
|              | ||||
|             m_clampPrimSize = config.GetBoolean("ClampPrimSize", false); | ||||
|             allKeys.Remove("ClampPrimSize"); | ||||
|              | ||||
|             m_objectCapacity = config.GetInt("MaxPrims", 15000); | ||||
|             allKeys.Remove("MaxPrims"); | ||||
|              | ||||
|             #endregion | ||||
| 
 | ||||
|             m_agentCapacity = config.GetInt("MaxAgents", 100); | ||||
|             allKeys.Remove("MaxAgents"); | ||||
| 
 | ||||
|  | @ -668,10 +692,18 @@ namespace OpenSim.Framework | |||
| 
 | ||||
|             config.Set("ExternalHostName", m_externalHostName); | ||||
| 
 | ||||
|             if (m_nonphysPrimMin != 0) | ||||
|                 config.Set("NonphysicalPrimMax", m_nonphysPrimMin); | ||||
| 
 | ||||
|             if (m_nonphysPrimMax != 0) | ||||
|                 config.Set("NonphysicalPrimMax", m_nonphysPrimMax); | ||||
| 
 | ||||
|             if (m_physPrimMin != 0) | ||||
|                 config.Set("PhysicalPrimMax", m_physPrimMin); | ||||
|              | ||||
|             if (m_physPrimMax != 0) | ||||
|                 config.Set("PhysicalPrimMax", m_physPrimMax); | ||||
|                          | ||||
|             config.Set("ClampPrimSize", m_clampPrimSize.ToString()); | ||||
| 
 | ||||
|             if (m_objectCapacity != 0) | ||||
|  | @ -754,9 +786,15 @@ namespace OpenSim.Framework | |||
|             configMember.addConfigurationOption("lastmap_refresh", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, | ||||
|                                                 "Last Map Refresh", Util.UnixTimeSinceEpoch().ToString(), true); | ||||
| 
 | ||||
|             configMember.addConfigurationOption("nonphysical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, | ||||
|                                                 "Minimum size for nonphysical prims", m_nonphysPrimMin.ToString(), true); | ||||
| 
 | ||||
|             configMember.addConfigurationOption("nonphysical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32, | ||||
|                                                 "Maximum size for nonphysical prims", m_nonphysPrimMax.ToString(), true); | ||||
| 
 | ||||
|             configMember.addConfigurationOption("physical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, | ||||
|                                                 "Minimum size for nonphysical prims", m_physPrimMin.ToString(), true); | ||||
| 
 | ||||
|             configMember.addConfigurationOption("physical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32, | ||||
|                                                 "Maximum size for physical prims", m_physPrimMax.ToString(), true); | ||||
| 
 | ||||
|  |  | |||
|  | @ -850,6 +850,12 @@ namespace OpenSim.Framework | |||
|             return Math.Min(Math.Max(x, min), max); | ||||
|         } | ||||
| 
 | ||||
|         public static Vector3 Clip(Vector3 vec, float min, float max) | ||||
|         { | ||||
|             return new Vector3(Clip(vec.X, min, max), Clip(vec.Y, min, max), | ||||
|                 Clip(vec.Z, min, max)); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Convert an UUID to a raw uuid string.  Right now this is a string without hyphens. | ||||
|         /// </summary> | ||||
|  |  | |||
|  | @ -35,6 +35,7 @@ using System.Text; | |||
| using System.Text.RegularExpressions; | ||||
| using System.Timers; | ||||
| using log4net; | ||||
| using NDesk.Options; | ||||
| using Nini.Config; | ||||
| using OpenMetaverse; | ||||
| using OpenSim.Framework; | ||||
|  | @ -310,8 +311,11 @@ namespace OpenSim | |||
|                                           "Change the scale of a named prim", HandleEditScale); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("Users", false, "kick user", | ||||
|                                           "kick user <first> <last> [message]", | ||||
|                                           "Kick a user off the simulator", KickUserCommand); | ||||
|                                           "kick user <first> <last> [--force] [message]", | ||||
|                                           "Kick a user off the simulator", | ||||
|                                           "The --force option will kick the user without any checks to see whether it's already in the process of closing\n" | ||||
|                                           + "Only use this option if you are sure the avatar is inactive and a normal kick user operation does not removed them", | ||||
|                                           KickUserCommand); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("Users", false, "show users", | ||||
|                                           "show users [full]", | ||||
|  | @ -416,6 +420,7 @@ namespace OpenSim | |||
|             { | ||||
|                 RunCommandScript(m_shutdownCommandsFile); | ||||
|             } | ||||
|              | ||||
|             base.ShutdownSpecific(); | ||||
|         } | ||||
| 
 | ||||
|  | @ -453,11 +458,17 @@ namespace OpenSim | |||
|         /// <param name="cmdparams">name of avatar to kick</param> | ||||
|         private void KickUserCommand(string module, string[] cmdparams) | ||||
|         { | ||||
|             if (cmdparams.Length < 4) | ||||
|             bool force = false; | ||||
|              | ||||
|             OptionSet options = new OptionSet().Add("f|force", delegate (string v) { force = v != null; }); | ||||
| 
 | ||||
|             List<string> mainParams = options.Parse(cmdparams); | ||||
| 
 | ||||
|             if (mainParams.Count < 4) | ||||
|                 return; | ||||
| 
 | ||||
|             string alert = null; | ||||
|             if (cmdparams.Length > 4) | ||||
|             if (mainParams.Count > 4) | ||||
|                 alert = String.Format("\n{0}\n", String.Join(" ", cmdparams, 4, cmdparams.Length - 4)); | ||||
| 
 | ||||
|             IList agents = SceneManager.GetCurrentSceneAvatars(); | ||||
|  | @ -466,8 +477,8 @@ namespace OpenSim | |||
|             { | ||||
|                 RegionInfo regionInfo = presence.Scene.RegionInfo; | ||||
| 
 | ||||
|                 if (presence.Firstname.ToLower().Contains(cmdparams[2].ToLower()) && | ||||
|                     presence.Lastname.ToLower().Contains(cmdparams[3].ToLower())) | ||||
|                 if (presence.Firstname.ToLower().Contains(mainParams[2].ToLower()) && | ||||
|                     presence.Lastname.ToLower().Contains(mainParams[3].ToLower())) | ||||
|                 { | ||||
|                     MainConsole.Instance.Output( | ||||
|                         String.Format( | ||||
|  | @ -480,7 +491,7 @@ namespace OpenSim | |||
|                     else | ||||
|                         presence.ControllingClient.Kick("\nThe OpenSim manager kicked you out.\n"); | ||||
| 
 | ||||
|                     presence.Scene.IncomingCloseAgent(presence.UUID); | ||||
|                     presence.Scene.IncomingCloseAgent(presence.UUID, force); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|  |  | |||
|  | @ -305,8 +305,13 @@ namespace OpenSim | |||
|             m_httpServerPort = m_networkServersInfo.HttpListenerPort; | ||||
|             SceneManager.OnRestartSim += handleRestartRegion; | ||||
| 
 | ||||
|             // Only start the memory watchdog once all regions are ready | ||||
|             SceneManager.OnRegionsReadyStatusChange += sm => MemoryWatchdog.Enabled = sm.AllRegionsReady; | ||||
|             // Only enable the watchdogs when all regions are ready.  Otherwise we get false positives when cpu is | ||||
|             // heavily used during initial startup. | ||||
|             // | ||||
|             // FIXME: It's also possible that region ready status should be flipped during an OAR load since this | ||||
|             // also makes heavy use of the CPU. | ||||
|             SceneManager.OnRegionsReadyStatusChange | ||||
|                 += sm => { MemoryWatchdog.Enabled = sm.AllRegionsReady; Watchdog.Enabled = sm.AllRegionsReady; }; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  |  | |||
|  | @ -94,7 +94,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests | |||
|             UUID spId = TestHelpers.ParseTail(0x1); | ||||
| 
 | ||||
|             SceneHelpers.AddScenePresence(m_scene, spId); | ||||
|             m_scene.IncomingCloseAgent(spId); | ||||
|             m_scene.IncomingCloseAgent(spId, false); | ||||
| 
 | ||||
|             // TODO: Add more assertions for the other aspects of event queues | ||||
|             Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0)); | ||||
|  |  | |||
|  | @ -0,0 +1,234 @@ | |||
| /* | ||||
|  * Copyright (c) Contributors, http://opensimulator.org/ | ||||
|  * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions are met: | ||||
|  *     * Redistributions of source code must retain the above copyright | ||||
|  *       notice, this list of conditions and the following disclaimer. | ||||
|  *     * Redistributions in binary form must reproduce the above copyright | ||||
|  *       notice, this list of conditions and the following disclaimer in the | ||||
|  *       documentation and/or other materials provided with the distribution. | ||||
|  *     * Neither the name of the OpenSimulator Project nor the | ||||
|  *       names of its contributors may be used to endorse or promote products | ||||
|  *       derived from this software without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||||
|  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||||
|  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
|  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||||
|  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||||
|  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||||
|  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||||
|  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
|  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||||
|  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  */ | ||||
| 
 | ||||
| using System; | ||||
| using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| using System.Collections.Specialized; | ||||
| using System.Drawing; | ||||
| using System.Drawing.Imaging; | ||||
| using System.Reflection; | ||||
| using System.IO; | ||||
| using System.Web; | ||||
| using log4net; | ||||
| using Nini.Config; | ||||
| using Mono.Addins; | ||||
| using OpenMetaverse; | ||||
| using OpenMetaverse.StructuredData; | ||||
| using OpenMetaverse.Imaging; | ||||
| using OpenSim.Framework; | ||||
| using OpenSim.Framework.Console; | ||||
| using OpenSim.Framework.Servers; | ||||
| using OpenSim.Framework.Servers.HttpServer; | ||||
| using OpenSim.Region.Framework.Interfaces; | ||||
| using OpenSim.Region.Framework.Scenes; | ||||
| using OpenSim.Services.Interfaces; | ||||
| using Caps = OpenSim.Framework.Capabilities.Caps; | ||||
| using OpenSim.Capabilities.Handlers; | ||||
| 
 | ||||
| namespace OpenSim.Region.ClientStack.Linden | ||||
| { | ||||
| 
 | ||||
|     [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RegionConsoleModule")] | ||||
|     public class RegionConsoleModule : INonSharedRegionModule, IRegionConsole | ||||
|     { | ||||
|         private static readonly ILog m_log = | ||||
|             LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
|          | ||||
|         private Scene m_scene; | ||||
|         private IEventQueue m_eventQueue; | ||||
|         private Commands m_commands = new Commands(); | ||||
|         public ICommands Commands { get { return m_commands; } } | ||||
| 
 | ||||
|         public void Initialise(IConfigSource source) | ||||
|         { | ||||
|             m_commands.AddCommand( "Help", false, "help", "help [<item>]", "Display help on a particular command or on a list of commands in a category", Help); | ||||
|         } | ||||
| 
 | ||||
|         public void AddRegion(Scene s) | ||||
|         { | ||||
|             m_scene = s; | ||||
|             m_scene.RegisterModuleInterface<IRegionConsole>(this); | ||||
|         } | ||||
| 
 | ||||
|         public void RemoveRegion(Scene s) | ||||
|         { | ||||
|             m_scene.EventManager.OnRegisterCaps -= RegisterCaps; | ||||
|             m_scene = null; | ||||
|         } | ||||
| 
 | ||||
|         public void RegionLoaded(Scene s) | ||||
|         { | ||||
|             m_scene.EventManager.OnRegisterCaps += RegisterCaps; | ||||
|             m_eventQueue = m_scene.RequestModuleInterface<IEventQueue>(); | ||||
|         } | ||||
| 
 | ||||
|         public void PostInitialise() | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public void Close() { } | ||||
| 
 | ||||
|         public string Name { get { return "RegionConsoleModule"; } } | ||||
| 
 | ||||
|         public Type ReplaceableInterface | ||||
|         { | ||||
|             get { return null; } | ||||
|         } | ||||
| 
 | ||||
|         public void RegisterCaps(UUID agentID, Caps caps) | ||||
|         { | ||||
|             if (!m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(agentID)) | ||||
|                 return; | ||||
| 
 | ||||
|             UUID capID = UUID.Random(); | ||||
| 
 | ||||
|             m_log.DebugFormat("[REGION CONSOLE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); | ||||
|             caps.RegisterHandler( | ||||
|                     "SimConsoleAsync", | ||||
|                     new ConsoleHandler("/CAPS/" + capID + "/", "SimConsoleAsync", agentID, this, m_scene)); | ||||
|         } | ||||
| 
 | ||||
|         public void SendConsoleOutput(UUID agentID, string message) | ||||
|         { | ||||
|             OSD osd = OSD.FromString(message); | ||||
| 
 | ||||
|             m_eventQueue.Enqueue(EventQueueHelper.BuildEvent("SimConsoleResponse", osd), agentID); | ||||
|         } | ||||
| 
 | ||||
|         public bool RunCommand(string command, UUID invokerID) | ||||
|         { | ||||
|             string[] parts = Parser.Parse(command); | ||||
|             Array.Resize(ref parts, parts.Length + 1); | ||||
|             parts[parts.Length - 1] = invokerID.ToString(); | ||||
| 
 | ||||
|             if (m_commands.Resolve(parts).Length == 0) | ||||
|                 return false; | ||||
| 
 | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|         private void Help(string module, string[] cmd) | ||||
|         { | ||||
|             UUID agentID = new UUID(cmd[cmd.Length - 1]); | ||||
|             Array.Resize(ref cmd, cmd.Length - 1); | ||||
| 
 | ||||
|             List<string> help = Commands.GetHelp(cmd); | ||||
| 
 | ||||
|             string reply = String.Empty; | ||||
| 
 | ||||
|             foreach (string s in help) | ||||
|             { | ||||
|                 reply += s + "\n"; | ||||
|             } | ||||
| 
 | ||||
|             SendConsoleOutput(agentID, reply); | ||||
|         } | ||||
|          | ||||
|         public void AddCommand(string module, bool shared, string command, string help, string longhelp, CommandDelegate fn) | ||||
|         { | ||||
|             m_commands.AddCommand(module, shared, command, help, longhelp, fn); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public class ConsoleHandler : BaseStreamHandler | ||||
|     { | ||||
|         private static readonly ILog m_log = | ||||
|             LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
| 
 | ||||
|         private RegionConsoleModule m_consoleModule; | ||||
|         private UUID m_agentID; | ||||
|         private bool m_isGod; | ||||
|         private Scene m_scene; | ||||
|         private bool m_consoleIsOn = false; | ||||
| 
 | ||||
|         public ConsoleHandler(string path, string name, UUID agentID, RegionConsoleModule module, Scene scene) | ||||
|                 :base("POST", path, name, agentID.ToString()) | ||||
|         { | ||||
|             m_agentID = agentID; | ||||
|             m_consoleModule = module; | ||||
|             m_scene = scene; | ||||
| 
 | ||||
|             m_isGod = m_scene.Permissions.IsGod(agentID); | ||||
|         } | ||||
| 
 | ||||
|         public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) | ||||
|         { | ||||
|             StreamReader reader = new StreamReader(request); | ||||
|             string message = reader.ReadToEnd(); | ||||
| 
 | ||||
|             OSD osd = OSDParser.DeserializeLLSDXml(message); | ||||
| 
 | ||||
|             string cmd = osd.AsString(); | ||||
|             if (cmd == "set console on") | ||||
|             { | ||||
|                 if (m_isGod) | ||||
|                 { | ||||
|                     MainConsole.Instance.OnOutput += ConsoleSender; | ||||
|                     m_consoleIsOn = true; | ||||
|                     m_consoleModule.SendConsoleOutput(m_agentID, "Console is now on"); | ||||
|                 } | ||||
|                 return new byte[0]; | ||||
|             } | ||||
|             else if (cmd == "set console off") | ||||
|             { | ||||
|                 MainConsole.Instance.OnOutput -= ConsoleSender; | ||||
|                 m_consoleIsOn = false; | ||||
|                 m_consoleModule.SendConsoleOutput(m_agentID, "Console is now off"); | ||||
|                 return new byte[0]; | ||||
|             } | ||||
| 
 | ||||
|             if (m_consoleIsOn == false && m_consoleModule.RunCommand(osd.AsString().Trim(), m_agentID)) | ||||
|                 return new byte[0]; | ||||
| 
 | ||||
|             if (m_isGod && m_consoleIsOn) | ||||
|             { | ||||
|                 MainConsole.Instance.RunCommand(osd.AsString().Trim()); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 m_consoleModule.SendConsoleOutput(m_agentID, "Unknown command"); | ||||
|             } | ||||
| 
 | ||||
|             return new byte[0]; | ||||
|         } | ||||
| 
 | ||||
|         private void ConsoleSender(string text) | ||||
|         { | ||||
|             m_consoleModule.SendConsoleOutput(m_agentID, text); | ||||
|         } | ||||
| 
 | ||||
|         private void OnMakeChildAgent(ScenePresence presence) | ||||
|         { | ||||
|             if (presence.UUID == m_agentID) | ||||
|             { | ||||
|                 MainConsole.Instance.OnOutput -= ConsoleSender; | ||||
|                 m_consoleIsOn = false; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -487,16 +487,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
| 
 | ||||
|         #region Client Methods | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Close down the client view | ||||
|         /// </summary> | ||||
|         public void Close() | ||||
|         { | ||||
|             Close(false); | ||||
|         } | ||||
| 
 | ||||
|         public void Close(bool force) | ||||
|         { | ||||
|             // We lock here to prevent race conditions between two threads calling close simultaneously (e.g. | ||||
|             // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection. | ||||
|             lock (CloseSyncLock) | ||||
|             { | ||||
|                 if (!IsActive) | ||||
|                 // We still perform a force close inside the sync lock since this is intended to attempt close where | ||||
|                 // there is some unidentified connection problem, not where we have issues due to deadlock | ||||
|                 if (!IsActive && !force) | ||||
|                     return; | ||||
| 
 | ||||
|                 IsActive = false; | ||||
|  | @ -5810,7 +5814,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|                 args.Channel = ch; | ||||
|                 args.From = String.Empty; | ||||
|                 args.Message = Utils.BytesToString(msg); | ||||
|                 args.Type = ChatTypeEnum.Shout; | ||||
|                 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance | ||||
|                 args.Position = new Vector3(); | ||||
|                 args.Scene = Scene; | ||||
|                 args.Sender = this; | ||||
|  | @ -11989,7 +11993,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|         { | ||||
|             Kick(reason); | ||||
|             Thread.Sleep(1000); | ||||
|             Close(); | ||||
|             Disconnect(); | ||||
|         } | ||||
| 
 | ||||
|         public void Disconnect() | ||||
|  |  | |||
|  | @ -458,10 +458,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
| 
 | ||||
|         public void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup so) | ||||
|         { | ||||
|             // As per Linden spec, detach (take) is disabled for temp attachs | ||||
|             if (so.FromItemID == UUID.Zero) | ||||
|                 return; | ||||
| 
 | ||||
|             lock (sp.AttachmentsSyncLock) | ||||
|             { | ||||
|                 // Save avatar attachment information | ||||
|  | @ -976,7 +972,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
|             ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); | ||||
|             SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); | ||||
| 
 | ||||
|             if (sp != null && group != null) | ||||
|             if (sp != null && group != null && group.FromItemID != UUID.Zero) | ||||
|                 DetachSingleAttachmentToInv(sp, group); | ||||
|         } | ||||
| 
 | ||||
|  | @ -994,7 +990,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
|      | ||||
|                     foreach (SceneObjectGroup group in attachments) | ||||
|                     { | ||||
|                         if (group.FromItemID == itemID) | ||||
|                         if (group.FromItemID == itemID && group.FromItemID != UUID.Zero) | ||||
|                         { | ||||
|                             DetachSingleAttachmentToInv(sp, group); | ||||
|                             return; | ||||
|  |  | |||
|  | @ -461,7 +461,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
| 
 | ||||
|             SceneObjectGroup rezzedAtt = presence.GetAttachments()[0]; | ||||
| 
 | ||||
|             scene.IncomingCloseAgent(presence.UUID); | ||||
|             scene.IncomingCloseAgent(presence.UUID, false); | ||||
| 
 | ||||
|             // Check that we can't retrieve this attachment from the scene. | ||||
|             Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null); | ||||
|  |  | |||
|  | @ -644,7 +644,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
|                 // an agent cannot teleport back to this region if it has teleported away. | ||||
|                 Thread.Sleep(2000); | ||||
| 
 | ||||
|                 sp.Scene.IncomingCloseAgent(sp.UUID); | ||||
|                 sp.Scene.IncomingCloseAgent(sp.UUID, false); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|  |  | |||
|  | @ -312,7 +312,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
| //                        "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", | ||||
| //                        s.RegionInfo.RegionName, destination.RegionHandle); | ||||
| 
 | ||||
|                 Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id); }); | ||||
|                 Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id, false); }); | ||||
|                 return true; | ||||
|             } | ||||
| 
 | ||||
|  |  | |||
|  | @ -97,6 +97,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Used to cache lookups for valid groups. | ||||
|         /// </summary> | ||||
|         private IDictionary<UUID, bool> m_validGroupUuids = new Dictionary<UUID, bool>(); | ||||
| 
 | ||||
|         private IGroupsModule m_groupsModule; | ||||
| 
 | ||||
|         public ArchiveReadRequest(Scene scene, string loadPath, bool merge, bool skipAssets, Guid requestId) | ||||
|         { | ||||
|             m_scene = scene; | ||||
|  | @ -120,6 +127,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
| 
 | ||||
|             // Zero can never be a valid user id | ||||
|             m_validUserUuids[UUID.Zero] = false; | ||||
| 
 | ||||
|             m_groupsModule = m_scene.RequestModuleInterface<IGroupsModule>(); | ||||
|         } | ||||
| 
 | ||||
|         public ArchiveReadRequest(Scene scene, Stream loadStream, bool merge, bool skipAssets, Guid requestId) | ||||
|  | @ -132,6 +141,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
| 
 | ||||
|             // Zero can never be a valid user id | ||||
|             m_validUserUuids[UUID.Zero] = false; | ||||
| 
 | ||||
|             m_groupsModule = m_scene.RequestModuleInterface<IGroupsModule>(); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -302,6 +313,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
|                     if (!ResolveUserUuid(part.LastOwnerID)) | ||||
|                         part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | ||||
| 
 | ||||
|                     if (!ResolveGroupUuid(part.GroupID)) | ||||
|                         part.GroupID = UUID.Zero; | ||||
| 
 | ||||
|                     // And zap any troublesome sit target information | ||||
| //                    part.SitTargetOrientation = new Quaternion(0, 0, 0, 1); | ||||
| //                    part.SitTargetPosition    = new Vector3(0, 0, 0); | ||||
|  | @ -318,13 +332,18 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
|                             { | ||||
|                                 kvp.Value.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | ||||
|                             } | ||||
| 
 | ||||
|                             if (kvp.Value.CreatorData == null || kvp.Value.CreatorData == string.Empty) | ||||
|                             { | ||||
|                                 if (!ResolveUserUuid(kvp.Value.CreatorID)) | ||||
|                                     kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; | ||||
|                             } | ||||
| 
 | ||||
|                             if (UserManager != null) | ||||
|                                 UserManager.AddUser(kvp.Value.CreatorID, kvp.Value.CreatorData); | ||||
| 
 | ||||
|                             if (!ResolveGroupUuid(kvp.Value.GroupID)) | ||||
|                                 kvp.Value.GroupID = UUID.Zero; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|  | @ -364,9 +383,27 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
|             foreach (string serialisedParcel in serialisedParcels) | ||||
|             { | ||||
|                 LandData parcel = LandDataSerializer.Deserialize(serialisedParcel); | ||||
|                  | ||||
|                 // Validate User and Group UUID's | ||||
| 
 | ||||
|                 if (!ResolveUserUuid(parcel.OwnerID)) | ||||
|                     parcel.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | ||||
|                  | ||||
| 
 | ||||
|                 if (!ResolveGroupUuid(parcel.GroupID)) | ||||
|                 { | ||||
|                     parcel.GroupID = UUID.Zero; | ||||
|                     parcel.IsGroupOwned = false; | ||||
|                 } | ||||
| 
 | ||||
|                 List<LandAccessEntry> accessList = new List<LandAccessEntry>(); | ||||
|                 foreach (LandAccessEntry entry in parcel.ParcelAccessList) | ||||
|                 { | ||||
|                     if (ResolveUserUuid(entry.AgentID)) | ||||
|                         accessList.Add(entry); | ||||
|                     // else, drop this access rule | ||||
|                 } | ||||
|                 parcel.ParcelAccessList = accessList; | ||||
| 
 | ||||
| //                m_log.DebugFormat( | ||||
| //                    "[ARCHIVER]: Adding parcel {0}, local id {1}, area {2}",  | ||||
| //                    parcel.Name, parcel.LocalID, parcel.Area); | ||||
|  | @ -401,6 +438,30 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Look up the given group id to check whether it's one that is valid for this grid. | ||||
|         /// </summary> | ||||
|         /// <param name="uuid"></param> | ||||
|         /// <returns></returns> | ||||
|         private bool ResolveGroupUuid(UUID uuid) | ||||
|         { | ||||
|             if (uuid == UUID.Zero) | ||||
|                 return true;    // this means the object has no group | ||||
| 
 | ||||
|             if (!m_validGroupUuids.ContainsKey(uuid)) | ||||
|             { | ||||
|                 bool exists; | ||||
|                  | ||||
|                 if (m_groupsModule == null) | ||||
|                     exists = false; | ||||
|                 else | ||||
|                     exists = (m_groupsModule.GetGroupRecord(uuid) != null); | ||||
| 
 | ||||
|                 m_validGroupUuids.Add(uuid, exists); | ||||
|             } | ||||
| 
 | ||||
|             return m_validGroupUuids[uuid]; | ||||
|         } | ||||
| 
 | ||||
|         /// Load an asset | ||||
|         /// </summary> | ||||
|         /// <param name="assetFilename"></param> | ||||
|  |  | |||
|  | @ -0,0 +1,39 @@ | |||
| /* | ||||
|  * Copyright (c) Contributors, http://opensimulator.org/ | ||||
|  * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions are met: | ||||
|  *     * Redistributions of source code must retain the above copyright | ||||
|  *       notice, this list of conditions and the following disclaimer. | ||||
|  *     * Redistributions in binary form must reproduce the above copyright | ||||
|  *       notice, this list of conditions and the following disclaimer in the | ||||
|  *       documentation and/or other materials provided with the distribution. | ||||
|  *     * Neither the name of the OpenSimulator Project nor the | ||||
|  *       names of its contributors may be used to endorse or promote products | ||||
|  *       derived from this software without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||||
|  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||||
|  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
|  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||||
|  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||||
|  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||||
|  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||||
|  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
|  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||||
|  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  */ | ||||
| 
 | ||||
| using OpenMetaverse; | ||||
| using OpenSim.Framework; | ||||
| 
 | ||||
| namespace OpenSim.Region.Framework.Interfaces | ||||
| { | ||||
|     public interface IRegionConsole | ||||
|     { | ||||
|         bool RunCommand(string command, UUID invokerID); | ||||
|         void SendConsoleOutput(UUID agentID, string message); | ||||
|         void AddCommand(string module, bool shared, string command, string help, string longhelp, CommandDelegate fn); | ||||
|     } | ||||
| } | ||||
|  | @ -116,5 +116,10 @@ namespace OpenSim.Region.Framework.Interfaces | |||
|         /// <param name="regionUUID">the region UUID</param> | ||||
|         void RemoveRegionEnvironmentSettings(UUID regionUUID); | ||||
| 
 | ||||
|         void SaveExtra(UUID regionID, string name, string value); | ||||
| 
 | ||||
|         void RemoveExtra(UUID regionID, string name); | ||||
| 
 | ||||
|         Dictionary<string, string> GetExtra(UUID regionID); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -127,6 +127,12 @@ namespace OpenSim.Region.Framework.Interfaces | |||
|         /// <param name="regionUUID">the region UUID</param> | ||||
|         void RemoveRegionEnvironmentSettings(UUID regionUUID); | ||||
| 
 | ||||
|         void SaveExtra(UUID regionID, string name, string val); | ||||
| 
 | ||||
|         void RemoveExtra(UUID regionID, string name); | ||||
| 
 | ||||
|         Dictionary<string, string> GetExtra(UUID regionID); | ||||
| 
 | ||||
|         void Shutdown(); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -213,6 +213,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
|         /// </remarks> | ||||
|         public event NewScript OnNewScript; | ||||
| 
 | ||||
|         public delegate void ExtraSettingChangedDelegate(Scene scene, string name, string value); | ||||
|         public event ExtraSettingChangedDelegate OnExtraSettingChanged; | ||||
| 
 | ||||
|         public virtual void TriggerNewScript(UUID clientID, SceneObjectPart part, UUID itemID) | ||||
|         { | ||||
|             NewScript handlerNewScript = OnNewScript; | ||||
|  | @ -2591,5 +2594,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void TriggerExtraSettingChanged(Scene scene, string name, string val) | ||||
|         { | ||||
|             ExtraSettingChangedDelegate handler = OnExtraSettingChanged; | ||||
| 
 | ||||
|             if (handler != null) | ||||
|             { | ||||
|                 foreach (ExtraSettingChangedDelegate d in handler.GetInvocationList()) | ||||
|                 { | ||||
|                     try | ||||
|                     { | ||||
|                         d(scene, name, val); | ||||
|                     } | ||||
|                     catch (Exception e) | ||||
|                     { | ||||
|                         m_log.ErrorFormat("[EVENT MANAGER]: Delegate for ExtraSettingChanged failed - continuing {0} - {1}", | ||||
|                             e.Message, e.StackTrace); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -103,8 +103,26 @@ namespace OpenSim.Region.Framework.Scenes | |||
|         /// </summary> | ||||
|         public bool CollidablePrims { get; private set; } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Minimum value of the size of a non-physical prim in each axis | ||||
|         /// </summary> | ||||
|         public float m_minNonphys = 0.01f; | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Maximum value of the size of a non-physical prim in each axis | ||||
|         /// </summary> | ||||
|         public float m_maxNonphys = 256; | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Minimum value of the size of a physical prim in each axis | ||||
|         /// </summary> | ||||
|         public float m_minPhys = 0.01f; | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Maximum value of the size of a physical prim in each axis | ||||
|         /// </summary> | ||||
|         public float m_maxPhys = 10; | ||||
| 
 | ||||
|         public bool m_clampPrimSize; | ||||
|         public bool m_trustBinaries; | ||||
|         public bool m_allowScriptCrossings; | ||||
|  | @ -174,6 +192,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
|         protected ICapabilitiesModule m_capsModule; | ||||
|         protected IGroupsModule m_groupsModule; | ||||
| 
 | ||||
|         private Dictionary<string, string> m_extraSettings; | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Current scene frame number | ||||
|         /// </summary> | ||||
|  | @ -635,6 +655,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             // FIXME: It shouldn't be up to the database plugins to create this data - we should do it when a new | ||||
|             // region is set up and avoid these gyrations. | ||||
|             RegionSettings rs = simDataService.LoadRegionSettings(RegionInfo.RegionID); | ||||
|             m_extraSettings = simDataService.GetExtra(RegionInfo.RegionID); | ||||
| 
 | ||||
|             bool updatedTerrainTextures = false; | ||||
|             if (rs.TerrainTexture1 == UUID.Zero) | ||||
|             { | ||||
|  | @ -717,14 +739,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                 PhysicalPrims = startupConfig.GetBoolean("physical_prim", PhysicalPrims); | ||||
|                 CollidablePrims = startupConfig.GetBoolean("collidable_prim", CollidablePrims); | ||||
| 
 | ||||
|                 m_minNonphys = startupConfig.GetFloat("NonphysicalPrimMin", m_minNonphys); | ||||
|                 if (RegionInfo.NonphysPrimMin > 0) | ||||
|                 { | ||||
|                     m_minNonphys = RegionInfo.NonphysPrimMin; | ||||
|                 } | ||||
| 
 | ||||
|                 m_maxNonphys = startupConfig.GetFloat("NonphysicalPrimMax", m_maxNonphys); | ||||
|                 if (RegionInfo.NonphysPrimMax > 0) | ||||
|                 { | ||||
|                     m_maxNonphys = RegionInfo.NonphysPrimMax; | ||||
|                 } | ||||
| 
 | ||||
|                 m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys); | ||||
|                 m_minPhys = startupConfig.GetFloat("PhysicalPrimMin", m_minPhys); | ||||
|                 if (RegionInfo.PhysPrimMin > 0) | ||||
|                 { | ||||
|                     m_minPhys = RegionInfo.PhysPrimMin; | ||||
|                 } | ||||
| 
 | ||||
|                 m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys); | ||||
|                 if (RegionInfo.PhysPrimMax > 0) | ||||
|                 { | ||||
|                     m_maxPhys = RegionInfo.PhysPrimMax; | ||||
|  | @ -4083,16 +4116,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
|         /// <summary> | ||||
|         /// Tell a single agent to disconnect from the region. | ||||
|         /// </summary> | ||||
|         /// <param name="regionHandle"></param> | ||||
|         /// <param name="agentID"></param> | ||||
|         public bool IncomingCloseAgent(UUID agentID) | ||||
|         /// <param name="force"> | ||||
|         /// Force the agent to close even if it might be in the middle of some other operation.  You do not want to | ||||
|         /// force unless you are absolutely sure that the agent is dead and a normal close is not working. | ||||
|         /// </param> | ||||
|         public bool IncomingCloseAgent(UUID agentID, bool force) | ||||
|         { | ||||
|             //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); | ||||
| 
 | ||||
|             ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); | ||||
|             if (presence != null) | ||||
|             { | ||||
|                 presence.ControllingClient.Close(); | ||||
|                 presence.ControllingClient.Close(force); | ||||
|                 return true; | ||||
|             } | ||||
| 
 | ||||
|  | @ -5443,5 +5479,44 @@ namespace OpenSim.Region.Framework.Scenes | |||
| 
 | ||||
|             callback(asset); | ||||
|         } | ||||
| 
 | ||||
|         public string GetExtraSetting(string name) | ||||
|         { | ||||
|             string val; | ||||
| 
 | ||||
|             if (!m_extraSettings.TryGetValue(name, out val)) | ||||
|                 return String.Empty; | ||||
| 
 | ||||
|             return val; | ||||
|         } | ||||
| 
 | ||||
|         public void StoreExtraSetting(string name, string val) | ||||
|         { | ||||
|             string oldVal; | ||||
| 
 | ||||
|             if (m_extraSettings.TryGetValue(name, out oldVal)) | ||||
|             { | ||||
|                 if (oldVal == val) | ||||
|                     return; | ||||
|             } | ||||
| 
 | ||||
|             m_extraSettings[name] = val; | ||||
| 
 | ||||
|             m_SimulationDataService.SaveExtra(RegionInfo.RegionID, name, val); | ||||
| 
 | ||||
|             m_eventManager.TriggerExtraSettingChanged(this, name, val); | ||||
|         } | ||||
| 
 | ||||
|         public void RemoveExtraSetting(string name) | ||||
|         { | ||||
|             if (!m_extraSettings.ContainsKey(name)) | ||||
|                 return; | ||||
| 
 | ||||
|             m_extraSettings.Remove(name); | ||||
| 
 | ||||
|             m_SimulationDataService.RemoveExtra(RegionInfo.RegionID, name); | ||||
| 
 | ||||
|             m_eventManager.TriggerExtraSettingChanged(this, name, String.Empty); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -375,12 +375,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                 { | ||||
|                     Vector3 scale = part.Shape.Scale; | ||||
| 
 | ||||
|                     if (scale.X > m_parentScene.m_maxNonphys) | ||||
|                         scale.X = m_parentScene.m_maxNonphys; | ||||
|                     if (scale.Y > m_parentScene.m_maxNonphys) | ||||
|                         scale.Y = m_parentScene.m_maxNonphys; | ||||
|                     if (scale.Z > m_parentScene.m_maxNonphys) | ||||
|                         scale.Z = m_parentScene.m_maxNonphys; | ||||
|                     scale.X = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.X)); | ||||
|                     scale.Y = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.Y)); | ||||
|                     scale.Z = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.Z)); | ||||
| 
 | ||||
|                     part.Shape.Scale = scale; | ||||
|                 } | ||||
|  |  | |||
|  | @ -2674,17 +2674,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
| 
 | ||||
|             RootPart.StoreUndoState(true); | ||||
| 
 | ||||
|             scale.X = Math.Min(scale.X, Scene.m_maxNonphys); | ||||
|             scale.Y = Math.Min(scale.Y, Scene.m_maxNonphys); | ||||
|             scale.Z = Math.Min(scale.Z, Scene.m_maxNonphys); | ||||
|             scale.X = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.X)); | ||||
|             scale.Y = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Y)); | ||||
|             scale.Z = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Z)); | ||||
| 
 | ||||
|             PhysicsActor pa = m_rootPart.PhysActor; | ||||
| 
 | ||||
|             if (pa != null && pa.IsPhysical) | ||||
|             { | ||||
|                 scale.X = Math.Min(scale.X, Scene.m_maxPhys); | ||||
|                 scale.Y = Math.Min(scale.Y, Scene.m_maxPhys); | ||||
|                 scale.Z = Math.Min(scale.Z, Scene.m_maxPhys); | ||||
|                 scale.X = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.X)); | ||||
|                 scale.Y = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Y)); | ||||
|                 scale.Z = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Z)); | ||||
|             } | ||||
| 
 | ||||
|             float x = (scale.X / RootPart.Scale.X); | ||||
|  | @ -2716,6 +2716,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                                 y *= a; | ||||
|                                 z *= a; | ||||
|                             } | ||||
|                             else if (oldSize.X * x < m_scene.m_minPhys) | ||||
|                             { | ||||
|                                 f = m_scene.m_minPhys / oldSize.X; | ||||
|                                 a = f / x; | ||||
|                                 x *= a; | ||||
|                                 y *= a; | ||||
|                                 z *= a; | ||||
|                             } | ||||
| 
 | ||||
|                             if (oldSize.Y * y > m_scene.m_maxPhys) | ||||
|                             { | ||||
|  | @ -2725,6 +2733,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                                 y *= a; | ||||
|                                 z *= a; | ||||
|                             } | ||||
|                             else if (oldSize.Y * y < m_scene.m_minPhys) | ||||
|                             { | ||||
|                                 f = m_scene.m_minPhys / oldSize.Y; | ||||
|                                 a = f / y; | ||||
|                                 x *= a; | ||||
|                                 y *= a; | ||||
|                                 z *= a; | ||||
|                             } | ||||
| 
 | ||||
|                             if (oldSize.Z * z > m_scene.m_maxPhys) | ||||
|                             { | ||||
|  | @ -2734,6 +2750,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                                 y *= a; | ||||
|                                 z *= a; | ||||
|                             } | ||||
|                             else if (oldSize.Z * z < m_scene.m_minPhys) | ||||
|                             { | ||||
|                                 f = m_scene.m_minPhys / oldSize.Z; | ||||
|                                 a = f / z; | ||||
|                                 x *= a; | ||||
|                                 y *= a; | ||||
|                                 z *= a; | ||||
|                             } | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|  | @ -2745,6 +2769,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                                 y *= a; | ||||
|                                 z *= a; | ||||
|                             } | ||||
|                             else if (oldSize.X * x < m_scene.m_minNonphys) | ||||
|                             { | ||||
|                                 f = m_scene.m_minNonphys / oldSize.X; | ||||
|                                 a = f / x; | ||||
|                                 x *= a; | ||||
|                                 y *= a; | ||||
|                                 z *= a; | ||||
|                             } | ||||
| 
 | ||||
|                             if (oldSize.Y * y > m_scene.m_maxNonphys) | ||||
|                             { | ||||
|  | @ -2754,6 +2786,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                                 y *= a; | ||||
|                                 z *= a; | ||||
|                             } | ||||
|                             else if (oldSize.Y * y < m_scene.m_minNonphys) | ||||
|                             { | ||||
|                                 f = m_scene.m_minNonphys / oldSize.Y; | ||||
|                                 a = f / y; | ||||
|                                 x *= a; | ||||
|                                 y *= a; | ||||
|                                 z *= a; | ||||
|                             } | ||||
| 
 | ||||
|                             if (oldSize.Z * z > m_scene.m_maxNonphys) | ||||
|                             { | ||||
|  | @ -2763,6 +2803,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                                 y *= a; | ||||
|                                 z *= a; | ||||
|                             } | ||||
|                             else if (oldSize.Z * z < m_scene.m_minNonphys) | ||||
|                             { | ||||
|                                 f = m_scene.m_minNonphys / oldSize.Z; | ||||
|                                 a = f / z; | ||||
|                                 x *= a; | ||||
|                                 y *= a; | ||||
|                                 z *= a; | ||||
|                             } | ||||
|                         } | ||||
| 
 | ||||
| //                        obPart.IgnoreUndoUpdate = false; | ||||
|  |  | |||
|  | @ -733,7 +733,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                     } | ||||
|                     catch (Exception e) | ||||
|                     { | ||||
|                         m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message); | ||||
|                         m_log.ErrorFormat("[SCENEOBJECTPART]: GROUP POSITION. {0}", e); | ||||
|                     } | ||||
|                 } | ||||
|                  | ||||
|  | @ -2368,17 +2368,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
|         /// <param name="scale"></param> | ||||
|         public void Resize(Vector3 scale) | ||||
|         { | ||||
|             scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxNonphys); | ||||
|             scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxNonphys); | ||||
|             scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxNonphys); | ||||
|             scale.X = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.X)); | ||||
|             scale.Y = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Y)); | ||||
|             scale.Z = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Z)); | ||||
| 
 | ||||
|             PhysicsActor pa = PhysActor; | ||||
| 
 | ||||
|             if (pa != null && pa.IsPhysical) | ||||
|             { | ||||
|                 scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxPhys); | ||||
|                 scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxPhys); | ||||
|                 scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxPhys); | ||||
|                 scale.X = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.X)); | ||||
|                 scale.Y = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Y)); | ||||
|                 scale.Z = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Z)); | ||||
|             } | ||||
| 
 | ||||
| //            m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale); | ||||
|  | @ -2852,23 +2851,32 @@ namespace OpenSim.Region.Framework.Scenes | |||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Set the color of prim faces | ||||
|         /// Set the color & alpha of prim faces | ||||
|         /// </summary> | ||||
|         /// <param name="color"></param> | ||||
|         /// <param name="face"></param> | ||||
|         public void SetFaceColor(Vector3 color, int face) | ||||
|         /// <param name="color"></param> | ||||
|         /// <param name="alpha"></param> | ||||
|         public void SetFaceColorAlpha(int face, Vector3 color, double ?alpha) | ||||
|         { | ||||
|             Vector3 clippedColor = Util.Clip(color, 0.0f, 1.0f); | ||||
|             float clippedAlpha = alpha.HasValue ? | ||||
|                 Util.Clip((float)alpha.Value, 0.0f, 1.0f) : 0; | ||||
| 
 | ||||
|             // The only way to get a deep copy/ If we don't do this, we can | ||||
|             // mever detect color changes further down. | ||||
|             // never detect color changes further down. | ||||
|             Byte[] buf = Shape.Textures.GetBytes(); | ||||
|             Primitive.TextureEntry tex = new Primitive.TextureEntry(buf, 0, buf.Length); | ||||
|             Color4 texcolor; | ||||
|             if (face >= 0 && face < GetNumberOfSides()) | ||||
|             { | ||||
|                 texcolor = tex.CreateFace((uint)face).RGBA; | ||||
|                 texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); | ||||
|                 texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); | ||||
|                 texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); | ||||
|                 texcolor.R = clippedColor.X; | ||||
|                 texcolor.G = clippedColor.Y; | ||||
|                 texcolor.B = clippedColor.Z; | ||||
|                 if (alpha.HasValue) | ||||
|                 { | ||||
|                     texcolor.A = clippedAlpha; | ||||
|                 } | ||||
|                 tex.FaceTextures[face].RGBA = texcolor; | ||||
|                 UpdateTextureEntry(tex.GetBytes()); | ||||
|                 return; | ||||
|  | @ -2880,15 +2888,23 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                     if (tex.FaceTextures[i] != null) | ||||
|                     { | ||||
|                         texcolor = tex.FaceTextures[i].RGBA; | ||||
|                         texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); | ||||
|                         texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); | ||||
|                         texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); | ||||
|                         texcolor.R = clippedColor.X; | ||||
|                         texcolor.G = clippedColor.Y; | ||||
|                         texcolor.B = clippedColor.Z; | ||||
|                         if (alpha.HasValue) | ||||
|                         { | ||||
|                             texcolor.A = clippedAlpha; | ||||
|                         } | ||||
|                         tex.FaceTextures[i].RGBA = texcolor; | ||||
|                     } | ||||
|                     texcolor = tex.DefaultTexture.RGBA; | ||||
|                     texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); | ||||
|                     texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); | ||||
|                     texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); | ||||
|                     texcolor.R = clippedColor.X; | ||||
|                     texcolor.G = clippedColor.Y; | ||||
|                     texcolor.B = clippedColor.Z; | ||||
|                     if (alpha.HasValue) | ||||
|                     { | ||||
|                         texcolor.A = clippedAlpha; | ||||
|                     } | ||||
|                     tex.DefaultTexture.RGBA = texcolor; | ||||
|                 } | ||||
|                 UpdateTextureEntry(tex.GetBytes()); | ||||
|  | @ -4237,6 +4253,57 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             ScheduleFullUpdate(); | ||||
|         } | ||||
| 
 | ||||
|         public void UpdateSlice(float begin, float end) | ||||
|         { | ||||
|             if (end < begin) | ||||
|             { | ||||
|                 float temp = begin; | ||||
|                 begin = end; | ||||
|                 end = temp; | ||||
|             } | ||||
|             end = Math.Min(1f, Math.Max(0f, end)); | ||||
|             begin = Math.Min(Math.Min(1f, Math.Max(0f, begin)), end - 0.02f); | ||||
|             if (begin < 0.02f && end < 0.02f) | ||||
|             { | ||||
|                 begin = 0f; | ||||
|                 end = 0.02f; | ||||
|             } | ||||
| 
 | ||||
|             ushort uBegin = (ushort)(50000.0 * begin); | ||||
|             ushort uEnd = (ushort)(50000.0 * (1f - end)); | ||||
|             bool updatePossiblyNeeded = false; | ||||
|             PrimType primType = GetPrimType(); | ||||
|             if (primType == PrimType.SPHERE || primType == PrimType.TORUS || primType == PrimType.TUBE || primType == PrimType.RING) | ||||
|             { | ||||
|                 if (m_shape.ProfileBegin != uBegin || m_shape.ProfileEnd != uEnd) | ||||
|                 { | ||||
|                     m_shape.ProfileBegin = uBegin; | ||||
|                     m_shape.ProfileEnd = uEnd; | ||||
|                     updatePossiblyNeeded = true; | ||||
|                 } | ||||
|             } | ||||
|             else if (m_shape.PathBegin != uBegin || m_shape.PathEnd != uEnd) | ||||
|             { | ||||
|                 m_shape.PathBegin = uBegin; | ||||
|                 m_shape.PathEnd = uEnd; | ||||
|                 updatePossiblyNeeded = true; | ||||
|             } | ||||
| 
 | ||||
|             if (updatePossiblyNeeded && ParentGroup != null) | ||||
|             { | ||||
|                 ParentGroup.HasGroupChanged = true; | ||||
|             } | ||||
|             if (updatePossiblyNeeded && PhysActor != null) | ||||
|             { | ||||
|                 PhysActor.Shape = m_shape; | ||||
|                 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); | ||||
|             } | ||||
|             if (updatePossiblyNeeded) | ||||
|             { | ||||
|                 ScheduleFullUpdate(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// If the part is a sculpt/mesh, retrieve the mesh data and reinsert it into the shape so that the physics | ||||
|         /// engine can use it. | ||||
|  |  | |||
|  | @ -1385,17 +1385,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                 bool DCFlagKeyPressed = false; | ||||
|                 Vector3 agent_control_v3 = Vector3.Zero; | ||||
| 
 | ||||
|                 bool oldflying = Flying; | ||||
|                 bool newFlying = actor.Flying; | ||||
| 
 | ||||
|                 if (ForceFly) | ||||
|                     actor.Flying = true; | ||||
|                     newFlying = true; | ||||
|                 else if (FlyDisabled) | ||||
|                     actor.Flying = false; | ||||
|                     newFlying = false; | ||||
|                 else | ||||
|                     actor.Flying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); | ||||
|                     newFlying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); | ||||
| 
 | ||||
|                 if (actor.Flying != oldflying) | ||||
|                 if (actor.Flying != newFlying) | ||||
|                 { | ||||
|                     // Note: ScenePresence.Flying is actually fetched from the physical actor | ||||
|                     //     so setting PhysActor.Flying here also sets the ScenePresence's value. | ||||
|                     actor.Flying = newFlying; | ||||
|                     update_movementflag = true; | ||||
|                 } | ||||
| 
 | ||||
|                 if (ParentID == 0) | ||||
|                 { | ||||
|  |  | |||
|  | @ -141,7 +141,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
|             TestScene scene = new SceneHelpers().SetupScene(); | ||||
|             ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); | ||||
| 
 | ||||
|             scene.IncomingCloseAgent(sp.UUID); | ||||
|             scene.IncomingCloseAgent(sp.UUID, false); | ||||
| 
 | ||||
|             Assert.That(scene.GetScenePresence(sp.UUID), Is.Null); | ||||
|             Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Null); | ||||
|  |  | |||
|  | @ -885,6 +885,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
|         } | ||||
| 
 | ||||
|         public void Close() | ||||
|         { | ||||
|             Close(false); | ||||
|         } | ||||
| 
 | ||||
|         public void Close(bool force) | ||||
|         { | ||||
|             Disconnect(); | ||||
|         } | ||||
|  |  | |||
|  | @ -43,15 +43,13 @@ using OpenSim.Region.Framework.Scenes; | |||
| 
 | ||||
| namespace OpenSim.Region.OptionalModules.Avatar.Attachments | ||||
| { | ||||
|     /// <summary> | ||||
|     /// A module that just holds commands for inspecting avatar appearance. | ||||
|     /// </summary> | ||||
|     [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "TempAttachmentsModule")] | ||||
|     public class TempAttachmentsModule : INonSharedRegionModule | ||||
|     { | ||||
|         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
| 
 | ||||
|         private Scene m_scene; | ||||
|         private IRegionConsole m_console; | ||||
| 
 | ||||
|         public void Initialise(IConfigSource configSource) | ||||
|         { | ||||
|  | @ -74,6 +72,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments | |||
|             { | ||||
|                 comms.RegisterScriptInvocation( this, "llAttachToAvatarTemp"); | ||||
|                 m_log.DebugFormat("[TEMP ATTACHS]: Registered script functions"); | ||||
|                 m_console = scene.RequestModuleInterface<IRegionConsole>(); | ||||
| 
 | ||||
|                 if (m_console != null) | ||||
|                 { | ||||
|                     m_console.AddCommand("TempATtachModule", false, "set auto_grant_attach_perms", "set auto_grant_attach_perms true|false", "Allow objects owned by the region owner os estate managers to obtain attach permissions without asking the user", SetAutoGrantAttachPerms); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|  | @ -95,6 +99,37 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments | |||
|             get { return "TempAttachmentsModule"; } | ||||
|         } | ||||
| 
 | ||||
|         private void SendConsoleOutput(UUID agentID, string text) | ||||
|         { | ||||
|             if (m_console == null) | ||||
|                 return; | ||||
| 
 | ||||
|             m_console.SendConsoleOutput(agentID, text); | ||||
|         } | ||||
| 
 | ||||
|         private void SetAutoGrantAttachPerms(string module, string[] parms) | ||||
|         { | ||||
|             UUID agentID = new UUID(parms[parms.Length - 1]); | ||||
|             Array.Resize(ref parms, parms.Length - 1); | ||||
| 
 | ||||
|             if (parms.Length != 3) | ||||
|             { | ||||
|                 SendConsoleOutput(agentID, "Command parameter error"); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             string val = parms[2]; | ||||
|             if (val != "true" && val != "false") | ||||
|             { | ||||
|                 SendConsoleOutput(agentID, "Command parameter error"); | ||||
|                 return; | ||||
|             } | ||||
|               | ||||
|             m_scene.StoreExtraSetting("auto_grant_attach_perms", val); | ||||
| 
 | ||||
|             SendConsoleOutput(agentID, String.Format("auto_grant_attach_perms set to {0}", val)); | ||||
|         } | ||||
| 
 | ||||
|         private void llAttachToAvatarTemp(UUID host, UUID script, int attachmentPoint) | ||||
|         { | ||||
|             SceneObjectPart hostPart = m_scene.GetSceneObjectPart(host); | ||||
|  |  | |||
|  | @ -900,6 +900,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
|         } | ||||
| 
 | ||||
|         public void Close() | ||||
|         { | ||||
|             Close(false); | ||||
|         } | ||||
| 
 | ||||
|         public void Close(bool force) | ||||
|         { | ||||
|             // Remove ourselves from the scene | ||||
|             m_scene.RemoveClient(AgentId, false); | ||||
|  |  | |||
|  | @ -37,7 +37,8 @@ public class BS6DofConstraint : BSConstraint | |||
|     // Create a btGeneric6DofConstraint | ||||
|     public BS6DofConstraint(BulletSim world, BulletBody obj1, BulletBody obj2, | ||||
|                     Vector3 frame1, Quaternion frame1rot, | ||||
|                     Vector3 frame2, Quaternion frame2rot ) | ||||
|                     Vector3 frame2, Quaternion frame2rot, | ||||
|                     bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) | ||||
|     { | ||||
|         m_world = world; | ||||
|         m_body1 = obj1; | ||||
|  | @ -46,16 +47,45 @@ public class BS6DofConstraint : BSConstraint | |||
|                             BulletSimAPI.Create6DofConstraint2(m_world.Ptr, m_body1.Ptr, m_body2.Ptr, | ||||
|                                 frame1, frame1rot, | ||||
|                                 frame2, frame2rot, | ||||
|                                 true /*useLinearReferenceFrameA*/, true /*disableCollisionsBetweenLinkedBodies*/)); | ||||
|                                 useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); | ||||
|         m_enabled = true; | ||||
|     } | ||||
| 
 | ||||
|     public BS6DofConstraint(BulletSim world, BulletBody obj1, BulletBody obj2, | ||||
|                     Vector3 joinPoint, | ||||
|                     bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) | ||||
|     { | ||||
|         m_world = world; | ||||
|         m_body1 = obj1; | ||||
|         m_body2 = obj2; | ||||
|         m_constraint = new BulletConstraint( | ||||
|                             BulletSimAPI.Create6DofConstraintToPoint2(m_world.Ptr, m_body1.Ptr, m_body2.Ptr, | ||||
|                                 joinPoint, | ||||
|                                 useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); | ||||
|         m_enabled = true; | ||||
|     } | ||||
| 
 | ||||
|     public bool SetFrames(Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot) | ||||
|     { | ||||
|         bool ret = false; | ||||
|         if (m_enabled) | ||||
|         { | ||||
|             BulletSimAPI.SetFrames2(m_constraint.Ptr, frameA, frameArot, frameB, frameBrot); | ||||
|             ret = true; | ||||
|         } | ||||
|         return ret; | ||||
|     } | ||||
| 
 | ||||
|     public bool SetCFMAndERP(float cfm, float erp) | ||||
|     { | ||||
|         bool ret = true; | ||||
|         BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL); | ||||
|         BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_STOP_ERP, erp, ConstraintParamAxis.AXIS_ALL); | ||||
|         BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_CFM, cfm, ConstraintParamAxis.AXIS_ALL); | ||||
|         bool ret = false; | ||||
|         if (m_enabled) | ||||
|         { | ||||
|             BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL); | ||||
|             BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_STOP_ERP, erp, ConstraintParamAxis.AXIS_ALL); | ||||
|             BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_CFM, cfm, ConstraintParamAxis.AXIS_ALL); | ||||
|             ret = true; | ||||
|         } | ||||
|         return ret; | ||||
|     } | ||||
| 
 | ||||
|  | @ -76,5 +106,13 @@ public class BS6DofConstraint : BSConstraint | |||
|             ret = BulletSimAPI.TranslationalLimitMotor2(m_constraint.Ptr, onOff, targetVelocity, maxMotorForce); | ||||
|         return ret; | ||||
|     } | ||||
| 
 | ||||
|     public bool SetBreakingImpulseThreshold(float threshold) | ||||
|     { | ||||
|         bool ret = false; | ||||
|         if (m_enabled) | ||||
|             ret = BulletSimAPI.SetBreakingImpulseThreshold2(m_constraint.Ptr, threshold); | ||||
|         return ret; | ||||
|     } | ||||
| } | ||||
| } | ||||
|  |  | |||
|  | @ -124,10 +124,14 @@ public class BSCharacter : PhysicsActor | |||
|         // do actual create at taint time | ||||
|         _scene.TaintedObject("BSCharacter.create", delegate() | ||||
|         { | ||||
|             DetailLog("{0},BSCharacter.create", _localID); | ||||
|             BulletSimAPI.CreateObject(parent_scene.WorldID, shapeData); | ||||
| 
 | ||||
|             // Set the buoyancy for flying. This will be refactored when all the settings happen in C# | ||||
|             BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy); | ||||
| 
 | ||||
|             m_body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID)); | ||||
|             // avatars get all collisions no matter what | ||||
|             // avatars get all collisions no matter what (makes walking on ground and such work) | ||||
|             BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); | ||||
|         }); | ||||
|              | ||||
|  | @ -137,7 +141,7 @@ public class BSCharacter : PhysicsActor | |||
|     // called when this character is being destroyed and the resources should be released | ||||
|     public void Destroy() | ||||
|     { | ||||
|         // DetailLog("{0},Destroy", LocalID); | ||||
|         DetailLog("{0},BSCharacter.Destroy", LocalID); | ||||
|         _scene.TaintedObject("BSCharacter.destroy", delegate() | ||||
|         { | ||||
|             BulletSimAPI.DestroyObject(_scene.WorldID, _localID); | ||||
|  | @ -209,7 +213,7 @@ public class BSCharacter : PhysicsActor | |||
| 
 | ||||
|             _scene.TaintedObject("BSCharacter.setPosition", delegate() | ||||
|             { | ||||
|                 DetailLog("{0},SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); | ||||
|                 DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); | ||||
|                 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); | ||||
|             }); | ||||
|         }  | ||||
|  | @ -226,7 +230,7 @@ public class BSCharacter : PhysicsActor | |||
|         float terrainHeight = Scene.GetTerrainHeightAtXYZ(_position); | ||||
|         if (_position.Z < terrainHeight) | ||||
|         { | ||||
|             DetailLog("{0},PositionAdjustUnderGround,call,pos={1},orient={2}", LocalID, _position, _orientation); | ||||
|             DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},orient={2}", LocalID, _position, _orientation); | ||||
|             _position.Z = terrainHeight + 2.0f; | ||||
|             ret = true; | ||||
|         } | ||||
|  | @ -319,14 +323,13 @@ public class BSCharacter : PhysicsActor | |||
|     public override bool Flying {  | ||||
|         get { return _flying; }  | ||||
|         set { | ||||
|             if (_flying != value) | ||||
|             { | ||||
|                 _flying = value; | ||||
|                 // simulate flying by changing the effect of gravity | ||||
|                 this.Buoyancy = ComputeBuoyancyFromFlying(_flying); | ||||
|             } | ||||
|             _flying = value; | ||||
|             // simulate flying by changing the effect of gravity | ||||
|             this.Buoyancy = ComputeBuoyancyFromFlying(_flying); | ||||
|         }  | ||||
|     } | ||||
|     // Flying is implimented by changing the avatar's buoyancy. | ||||
|     // Would this be done better with a vehicle type? | ||||
|     private float ComputeBuoyancyFromFlying(bool ifFlying) { | ||||
|         return ifFlying ? 1f : 0f; | ||||
|     } | ||||
|  | @ -368,7 +371,7 @@ public class BSCharacter : PhysicsActor | |||
|         set { _buoyancy = value;  | ||||
|             _scene.TaintedObject("BSCharacter.setBuoyancy", delegate() | ||||
|             { | ||||
|                 DetailLog("{0},setBuoyancy,taint,buoy={1}", LocalID, _buoyancy); | ||||
|                 DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy); | ||||
|                 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy); | ||||
|             }); | ||||
|         }  | ||||
|  | @ -415,7 +418,7 @@ public class BSCharacter : PhysicsActor | |||
|             // m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force); | ||||
|             _scene.TaintedObject("BSCharacter.AddForce", delegate() | ||||
|             { | ||||
|                 DetailLog("{0},setAddForce,taint,addedForce={1}", LocalID, _force); | ||||
|                 DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force); | ||||
|                 BulletSimAPI.AddObjectForce2(Body.Ptr, _force); | ||||
|             }); | ||||
|         } | ||||
|  | @ -507,6 +510,7 @@ public class BSCharacter : PhysicsActor | |||
|         { | ||||
|             _collidingGroundStep = _scene.SimulationStep; | ||||
|         } | ||||
|         // DetailLog("{0},BSCharacter.Collison,call,with={1}", LocalID, collidingWith); | ||||
| 
 | ||||
|         // throttle collisions to the rate specified in the subscription | ||||
|         if (_subscribedEventsMs != 0) { | ||||
|  | @ -535,7 +539,10 @@ public class BSCharacter : PhysicsActor | |||
|         if (collisionCollection == null) | ||||
|             collisionCollection = new CollisionEventUpdate(); | ||||
|         base.SendCollisionUpdate(collisionCollection); | ||||
|         collisionCollection.Clear(); | ||||
|         // If there were any collisions in the collection, make sure we don't use the | ||||
|         //    same instance next time. | ||||
|         if (collisionCollection.Count > 0) | ||||
|             collisionCollection = null; | ||||
|         // End kludge | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -80,10 +80,33 @@ public abstract class BSConstraint : IDisposable | |||
|         bool ret = false; | ||||
|         if (m_enabled) | ||||
|         { | ||||
|             // Recompute the internal transforms | ||||
|             BulletSimAPI.CalculateTransforms2(m_constraint.Ptr); | ||||
|             ret = true; | ||||
|         } | ||||
|         return ret; | ||||
|     } | ||||
| 
 | ||||
|     // Reset this constraint making sure it has all its internal structures | ||||
|     //    recomputed and is enabled and ready to go. | ||||
|     public virtual bool RecomputeConstraintVariables(float mass) | ||||
|     { | ||||
|         bool ret = false; | ||||
|         if (m_enabled) | ||||
|         { | ||||
|             ret = CalculateTransforms(); | ||||
|             if (ret) | ||||
|             { | ||||
|                 // m_world.scene.PhysicsLogging.Write("{0},BSConstraint.RecomputeConstraintVariables,taint,enabling,A={1},B={2}", | ||||
|                 //                 BSScene.DetailLogZero, Body1.ID, Body2.ID); | ||||
|                 BulletSimAPI.SetConstraintEnable2(m_constraint.Ptr, m_world.scene.NumericBool(true)); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 m_world.scene.Logger.ErrorFormat("[BULLETSIM CONSTRAINT] CalculateTransforms failed. A={0}, B={1}", Body1.ID, Body2.ID); | ||||
|             } | ||||
|         } | ||||
|         return ret; | ||||
|     } | ||||
| } | ||||
| } | ||||
|  |  | |||
|  | @ -56,21 +56,25 @@ public class BSConstraintCollection : IDisposable | |||
| 
 | ||||
|     public void Clear() | ||||
|     { | ||||
|         foreach (BSConstraint cons in m_constraints) | ||||
|         lock (m_constraints) | ||||
|         { | ||||
|             cons.Dispose(); | ||||
|             foreach (BSConstraint cons in m_constraints) | ||||
|             { | ||||
|                 cons.Dispose(); | ||||
|             } | ||||
|             m_constraints.Clear(); | ||||
|         } | ||||
|         m_constraints.Clear(); | ||||
|     } | ||||
| 
 | ||||
|     public bool AddConstraint(BSConstraint cons) | ||||
|     { | ||||
|         // There is only one constraint between any bodies. Remove any old just to make sure. | ||||
|         RemoveAndDestroyConstraint(cons.Body1, cons.Body2); | ||||
|         lock (m_constraints) | ||||
|         { | ||||
|             // There is only one constraint between any bodies. Remove any old just to make sure. | ||||
|             RemoveAndDestroyConstraint(cons.Body1, cons.Body2); | ||||
| 
 | ||||
|         m_world.scene.DetailLog("{0},BSConstraintCollection.AddConstraint,call,body1={1},body2={2}", BSScene.DetailLogZero, cons.Body1.ID, cons.Body2.ID); | ||||
| 
 | ||||
|         m_constraints.Add(cons); | ||||
|             m_constraints.Add(cons); | ||||
|         } | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
|  | @ -84,16 +88,19 @@ public class BSConstraintCollection : IDisposable | |||
| 
 | ||||
|         uint lookingID1 = body1.ID; | ||||
|         uint lookingID2 = body2.ID; | ||||
|         ForEachConstraint(delegate(BSConstraint constrain) | ||||
|         lock (m_constraints) | ||||
|         { | ||||
|             if ((constrain.Body1.ID == lookingID1 && constrain.Body2.ID == lookingID2) | ||||
|                 || (constrain.Body1.ID == lookingID2 && constrain.Body2.ID == lookingID1)) | ||||
|             foreach (BSConstraint constrain in m_constraints) | ||||
|             { | ||||
|                 foundConstraint = constrain; | ||||
|                 found = true; | ||||
|                 if ((constrain.Body1.ID == lookingID1 && constrain.Body2.ID == lookingID2) | ||||
|                     || (constrain.Body1.ID == lookingID2 && constrain.Body2.ID == lookingID1)) | ||||
|                 { | ||||
|                     foundConstraint = constrain; | ||||
|                     found = true; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|             return found; | ||||
|         }); | ||||
|         } | ||||
|         returnConstraint = foundConstraint; | ||||
|         return found; | ||||
|     } | ||||
|  | @ -103,25 +110,35 @@ public class BSConstraintCollection : IDisposable | |||
|     // Return 'true' if a constraint was found and destroyed. | ||||
|     public bool RemoveAndDestroyConstraint(BulletBody body1, BulletBody body2) | ||||
|     { | ||||
|         // return BulletSimAPI.RemoveConstraint(m_world.ID, obj1.ID, obj2.ID); | ||||
| 
 | ||||
|         bool ret = false; | ||||
|         BSConstraint constrain; | ||||
| 
 | ||||
|         if (this.TryGetConstraint(body1, body2, out constrain)) | ||||
|         lock (m_constraints) | ||||
|         { | ||||
|             m_world.scene.DetailLog("{0},BSConstraintCollection.RemoveAndDestroyConstraint,taint,body1={1},body2={2}", BSScene.DetailLogZero, body1.ID, body2.ID); | ||||
|             // remove the constraint from our collection | ||||
|             m_constraints.Remove(constrain); | ||||
|             // tell the engine that all its structures need to be freed | ||||
|             constrain.Dispose(); | ||||
|             // we destroyed something | ||||
|             ret = true; | ||||
|             BSConstraint constrain; | ||||
|             if (this.TryGetConstraint(body1, body2, out constrain)) | ||||
|             { | ||||
|                 // remove the constraint from our collection | ||||
|                 RemoveAndDestroyConstraint(constrain); | ||||
|                 ret = true; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return ret; | ||||
|     } | ||||
| 
 | ||||
|     // The constraint MUST exist in the collection | ||||
|     public bool RemoveAndDestroyConstraint(BSConstraint constrain) | ||||
|     { | ||||
|         lock (m_constraints) | ||||
|         { | ||||
|             // remove the constraint from our collection | ||||
|             m_constraints.Remove(constrain); | ||||
|         } | ||||
|         // tell the engine that all its structures need to be freed | ||||
|         constrain.Dispose(); | ||||
|         // we destroyed something | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     // Remove all constraints that reference the passed body. | ||||
|     // Return 'true' if any constraints were destroyed. | ||||
|     public bool RemoveAndDestroyConstraint(BulletBody body1) | ||||
|  | @ -130,16 +147,15 @@ public class BSConstraintCollection : IDisposable | |||
| 
 | ||||
|         List<BSConstraint> toRemove = new List<BSConstraint>(); | ||||
|         uint lookingID = body1.ID; | ||||
|         ForEachConstraint(delegate(BSConstraint constrain) | ||||
|         { | ||||
|             if (constrain.Body1.ID == lookingID || constrain.Body2.ID == lookingID) | ||||
|             { | ||||
|                 toRemove.Add(constrain); | ||||
|             } | ||||
|             return false; | ||||
|         }); | ||||
|         lock (m_constraints) | ||||
|         { | ||||
|             foreach (BSConstraint constrain in m_constraints) | ||||
|             { | ||||
|                 if (constrain.Body1.ID == lookingID || constrain.Body2.ID == lookingID) | ||||
|                 { | ||||
|                     toRemove.Add(constrain); | ||||
|                 } | ||||
|             } | ||||
|             foreach (BSConstraint constrain in toRemove) | ||||
|             { | ||||
|                 m_constraints.Remove(constrain); | ||||
|  | @ -151,28 +167,16 @@ public class BSConstraintCollection : IDisposable | |||
| 
 | ||||
|     public bool RecalculateAllConstraints() | ||||
|     { | ||||
|         ForEachConstraint(delegate(BSConstraint constrain) | ||||
|         { | ||||
|             constrain.CalculateTransforms(); | ||||
|             return false; | ||||
|         }); | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     // Lock the constraint list and loop through it. | ||||
|     // The constraint action returns 'true' if it wants the loop aborted. | ||||
|     private void ForEachConstraint(ConstraintAction action) | ||||
|     { | ||||
|         bool ret = false; | ||||
|         lock (m_constraints) | ||||
|         { | ||||
|             foreach (BSConstraint constrain in m_constraints) | ||||
|             { | ||||
|                 if (action(constrain)) | ||||
|                     break; | ||||
|                 constrain.CalculateTransforms(); | ||||
|                 ret = true; | ||||
|             } | ||||
|         } | ||||
|         return ret; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| } | ||||
|  |  | |||
|  | @ -57,6 +57,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
|         private int frcount = 0;                                        // Used to limit dynamics debug output to | ||||
|                                                                         // every 100th frame | ||||
| 
 | ||||
|         private BSScene m_physicsScene; | ||||
|         private BSPrim m_prim;      // the prim this dynamic controller belongs to | ||||
| 
 | ||||
|         // Vehicle properties | ||||
|  | @ -74,7 +75,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
|                                                                         // HOVER_UP_ONLY | ||||
|                                                                         // LIMIT_MOTOR_UP | ||||
|                                                                         // LIMIT_ROLL_ONLY | ||||
|         private VehicleFlag m_Hoverflags = (VehicleFlag)0; | ||||
|         private Vector3 m_BlockingEndPoint = Vector3.Zero; | ||||
|         private Quaternion m_RollreferenceFrame = Quaternion.Identity; | ||||
|         // Linear properties | ||||
|  | @ -124,15 +124,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
|         private float m_verticalAttractionEfficiency = 1.0f;        // damped | ||||
|         private float m_verticalAttractionTimescale = 500f;         // Timescale > 300  means no vert attractor. | ||||
| 
 | ||||
|         public BSDynamics(BSPrim myPrim) | ||||
|         public BSDynamics(BSScene myScene, BSPrim myPrim) | ||||
|         { | ||||
|             m_physicsScene = myScene; | ||||
|             m_prim = myPrim; | ||||
|             m_type = Vehicle.TYPE_NONE; | ||||
|         } | ||||
| 
 | ||||
|         internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue, float timestep) | ||||
|         { | ||||
|             DetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); | ||||
|             VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); | ||||
|             switch (pParam) | ||||
|             { | ||||
|                 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: | ||||
|  | @ -231,7 +232,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
| 
 | ||||
|         internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue, float timestep) | ||||
|         { | ||||
|             DetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); | ||||
|             VDetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); | ||||
|             switch (pParam) | ||||
|             { | ||||
|                 case Vehicle.ANGULAR_FRICTION_TIMESCALE: | ||||
|  | @ -266,7 +267,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
| 
 | ||||
|         internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) | ||||
|         { | ||||
|             DetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); | ||||
|             VDetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); | ||||
|             switch (pParam) | ||||
|             { | ||||
|                 case Vehicle.REFERENCE_FRAME: | ||||
|  | @ -280,164 +281,27 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
| 
 | ||||
|         internal void ProcessVehicleFlags(int pParam, bool remove) | ||||
|         { | ||||
|             DetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", m_prim.LocalID, pParam, remove); | ||||
|             VDetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", m_prim.LocalID, pParam, remove); | ||||
|             VehicleFlag parm = (VehicleFlag)pParam; | ||||
|             if (remove) | ||||
|             { | ||||
|                 if (pParam == -1) | ||||
|                 { | ||||
|                     m_flags = (VehicleFlag)0; | ||||
|                     m_Hoverflags = (VehicleFlag)0; | ||||
|                     return; | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) | ||||
|                 else | ||||
|                 { | ||||
|                     if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != (VehicleFlag)0) | ||||
|                         m_Hoverflags &= ~(VehicleFlag.HOVER_GLOBAL_HEIGHT); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.HOVER_TERRAIN_ONLY) == (int)VehicleFlag.HOVER_TERRAIN_ONLY) | ||||
|                 { | ||||
|                     if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != (VehicleFlag)0) | ||||
|                         m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.HOVER_UP_ONLY) == (int)VehicleFlag.HOVER_UP_ONLY) | ||||
|                 { | ||||
|                     if ((m_Hoverflags & VehicleFlag.HOVER_UP_ONLY) != (VehicleFlag)0) | ||||
|                         m_Hoverflags &= ~(VehicleFlag.HOVER_UP_ONLY); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.HOVER_WATER_ONLY) == (int)VehicleFlag.HOVER_WATER_ONLY) | ||||
|                 { | ||||
|                     if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != (VehicleFlag)0) | ||||
|                         m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.LIMIT_MOTOR_UP) == (int)VehicleFlag.LIMIT_MOTOR_UP) | ||||
|                 { | ||||
|                     if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != (VehicleFlag)0) | ||||
|                         m_flags &= ~(VehicleFlag.LIMIT_MOTOR_UP); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.LIMIT_ROLL_ONLY) == (int)VehicleFlag.LIMIT_ROLL_ONLY) | ||||
|                 { | ||||
|                     if ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) != (VehicleFlag)0) | ||||
|                         m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.MOUSELOOK_BANK) == (int)VehicleFlag.MOUSELOOK_BANK) | ||||
|                 { | ||||
|                     if ((m_flags & VehicleFlag.MOUSELOOK_BANK) != (VehicleFlag)0) | ||||
|                         m_flags &= ~(VehicleFlag.MOUSELOOK_BANK); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.MOUSELOOK_STEER) == (int)VehicleFlag.MOUSELOOK_STEER) | ||||
|                 { | ||||
|                     if ((m_flags & VehicleFlag.MOUSELOOK_STEER) != (VehicleFlag)0) | ||||
|                         m_flags &= ~(VehicleFlag.MOUSELOOK_STEER); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.NO_DEFLECTION_UP) == (int)VehicleFlag.NO_DEFLECTION_UP) | ||||
|                 { | ||||
|                     if ((m_flags & VehicleFlag.NO_DEFLECTION_UP) != (VehicleFlag)0) | ||||
|                         m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.CAMERA_DECOUPLED) == (int)VehicleFlag.CAMERA_DECOUPLED) | ||||
|                 { | ||||
|                     if ((m_flags & VehicleFlag.CAMERA_DECOUPLED) != (VehicleFlag)0) | ||||
|                         m_flags &= ~(VehicleFlag.CAMERA_DECOUPLED); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.NO_X) == (int)VehicleFlag.NO_X) | ||||
|                 { | ||||
|                     if ((m_flags & VehicleFlag.NO_X) != (VehicleFlag)0) | ||||
|                         m_flags &= ~(VehicleFlag.NO_X); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.NO_Y) == (int)VehicleFlag.NO_Y) | ||||
|                 { | ||||
|                     if ((m_flags & VehicleFlag.NO_Y) != (VehicleFlag)0) | ||||
|                         m_flags &= ~(VehicleFlag.NO_Y); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.NO_Z) == (int)VehicleFlag.NO_Z) | ||||
|                 { | ||||
|                     if ((m_flags & VehicleFlag.NO_Z) != (VehicleFlag)0) | ||||
|                         m_flags &= ~(VehicleFlag.NO_Z); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.LOCK_HOVER_HEIGHT) == (int)VehicleFlag.LOCK_HOVER_HEIGHT) | ||||
|                 { | ||||
|                     if ((m_Hoverflags & VehicleFlag.LOCK_HOVER_HEIGHT) != (VehicleFlag)0) | ||||
|                         m_Hoverflags &= ~(VehicleFlag.LOCK_HOVER_HEIGHT); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.NO_DEFLECTION) == (int)VehicleFlag.NO_DEFLECTION) | ||||
|                 { | ||||
|                     if ((m_flags & VehicleFlag.NO_DEFLECTION) != (VehicleFlag)0) | ||||
|                         m_flags &= ~(VehicleFlag.NO_DEFLECTION); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.LOCK_ROTATION) == (int)VehicleFlag.LOCK_ROTATION) | ||||
|                 { | ||||
|                     if ((m_flags & VehicleFlag.LOCK_ROTATION) != (VehicleFlag)0) | ||||
|                         m_flags &= ~(VehicleFlag.LOCK_ROTATION); | ||||
|                     m_flags &= ~parm; | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) | ||||
|                 { | ||||
|                     m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT | m_flags); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.HOVER_TERRAIN_ONLY) == (int)VehicleFlag.HOVER_TERRAIN_ONLY) | ||||
|                 { | ||||
|                     m_Hoverflags |= (VehicleFlag.HOVER_TERRAIN_ONLY | m_flags); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.HOVER_UP_ONLY) == (int)VehicleFlag.HOVER_UP_ONLY) | ||||
|                 { | ||||
|                     m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY | m_flags); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.HOVER_WATER_ONLY) == (int)VehicleFlag.HOVER_WATER_ONLY) | ||||
|                 { | ||||
|                     m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY | m_flags); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.LIMIT_MOTOR_UP) == (int)VehicleFlag.LIMIT_MOTOR_UP) | ||||
|                 { | ||||
|                     m_flags |= (VehicleFlag.LIMIT_MOTOR_UP | m_flags); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.MOUSELOOK_BANK) == (int)VehicleFlag.MOUSELOOK_BANK) | ||||
|                 { | ||||
|                     m_flags |= (VehicleFlag.MOUSELOOK_BANK | m_flags); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.MOUSELOOK_STEER) == (int)VehicleFlag.MOUSELOOK_STEER) | ||||
|                 { | ||||
|                     m_flags |= (VehicleFlag.MOUSELOOK_STEER | m_flags); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.NO_DEFLECTION_UP) == (int)VehicleFlag.NO_DEFLECTION_UP) | ||||
|                 { | ||||
|                     m_flags |= (VehicleFlag.NO_DEFLECTION_UP | m_flags); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.CAMERA_DECOUPLED) == (int)VehicleFlag.CAMERA_DECOUPLED) | ||||
|                 { | ||||
|                     m_flags |= (VehicleFlag.CAMERA_DECOUPLED | m_flags); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.NO_X) == (int)VehicleFlag.NO_X) | ||||
|                 { | ||||
|                     m_flags |= (VehicleFlag.NO_X); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.NO_Y) == (int)VehicleFlag.NO_Y) | ||||
|                 { | ||||
|                     m_flags |= (VehicleFlag.NO_Y); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.NO_Z) == (int)VehicleFlag.NO_Z) | ||||
|                 { | ||||
|                     m_flags |= (VehicleFlag.NO_Z); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.LOCK_HOVER_HEIGHT) == (int)VehicleFlag.LOCK_HOVER_HEIGHT) | ||||
|                 { | ||||
|                     m_Hoverflags |= (VehicleFlag.LOCK_HOVER_HEIGHT); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.NO_DEFLECTION) == (int)VehicleFlag.NO_DEFLECTION) | ||||
|                 { | ||||
|                     m_flags |= (VehicleFlag.NO_DEFLECTION); | ||||
|                 } | ||||
|                 if ((pParam & (int)VehicleFlag.LOCK_ROTATION) == (int)VehicleFlag.LOCK_ROTATION) | ||||
|                 { | ||||
|                     m_flags |= (VehicleFlag.LOCK_ROTATION); | ||||
|                 } | ||||
|             else { | ||||
|                 m_flags |= parm; | ||||
|             } | ||||
|         }//end ProcessVehicleFlags | ||||
| 
 | ||||
|         internal void ProcessTypeChange(Vehicle pType) | ||||
|         internal void ProcessTypeChange(Vehicle pType, float stepSize) | ||||
|         { | ||||
|             DetailLog("{0},ProcessTypeChange,type={1}", m_prim.LocalID, pType); | ||||
|             VDetailLog("{0},ProcessTypeChange,type={1}", m_prim.LocalID, pType); | ||||
|             // Set Defaults For Type | ||||
|             m_type = pType; | ||||
|             switch (pType) | ||||
|  | @ -478,10 +342,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
|                     // m_bankingMix = 1; | ||||
|                     // m_bankingTimescale = 10; | ||||
|                     // m_referenceFrame = Quaternion.Identity; | ||||
|                     m_Hoverflags &= | ||||
|                     m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP); | ||||
|                     m_flags &= | ||||
|                          ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | | ||||
|                            VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); | ||||
|                     m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP); | ||||
|                     break; | ||||
|                 case Vehicle.TYPE_CAR: | ||||
|                     m_linearFrictionTimescale = new Vector3(100, 2, 1000); | ||||
|  | @ -506,10 +370,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
|                     // m_bankingMix = 1; | ||||
|                     // m_bankingTimescale = 1; | ||||
|                     // m_referenceFrame = Quaternion.Identity; | ||||
|                     m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT); | ||||
|                     m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | | ||||
|                                 VehicleFlag.LIMIT_MOTOR_UP); | ||||
|                     m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY); | ||||
|                     m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT); | ||||
|                     m_flags |= (VehicleFlag.HOVER_UP_ONLY); | ||||
|                     break; | ||||
|                 case Vehicle.TYPE_BOAT: | ||||
|                     m_linearFrictionTimescale = new Vector3(10, 3, 2); | ||||
|  | @ -534,12 +398,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
|                     // m_bankingMix = 0.8f; | ||||
|                     // m_bankingTimescale = 1; | ||||
|                     // m_referenceFrame = Quaternion.Identity; | ||||
|                     m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | | ||||
|                     m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | | ||||
|                             VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); | ||||
|                     m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY); | ||||
|                     m_flags |= (VehicleFlag.NO_DEFLECTION_UP | | ||||
|                                 VehicleFlag.LIMIT_MOTOR_UP); | ||||
|                     m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY); | ||||
|                     m_flags |= (VehicleFlag.HOVER_WATER_ONLY); | ||||
|                     break; | ||||
|                 case Vehicle.TYPE_AIRPLANE: | ||||
|                     m_linearFrictionTimescale = new Vector3(200, 10, 5); | ||||
|  | @ -564,7 +428,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
|                     // m_bankingMix = 0.7f; | ||||
|                     // m_bankingTimescale = 2; | ||||
|                     // m_referenceFrame = Quaternion.Identity; | ||||
|                     m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | | ||||
|                     m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | | ||||
|                         VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); | ||||
|                     m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP); | ||||
|                     m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); | ||||
|  | @ -592,11 +456,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
|                     // m_bankingMix = 0.7f; | ||||
|                     // m_bankingTimescale = 5; | ||||
|                     // m_referenceFrame = Quaternion.Identity; | ||||
|                     m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | | ||||
|                     m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | | ||||
|                         VehicleFlag.HOVER_UP_ONLY); | ||||
|                     m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP); | ||||
|                     m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); | ||||
|                     m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT); | ||||
|                     m_flags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT); | ||||
|                     break; | ||||
|             } | ||||
|         }//end SetDefaultsForType | ||||
|  | @ -613,7 +477,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
|             MoveAngular(pTimestep); | ||||
|             LimitRotation(pTimestep); | ||||
| 
 | ||||
|             DetailLog("{0},Dynamics,done,pos={1},force={2},velocity={3},angvel={4}",  | ||||
|             VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}",  | ||||
|                     m_prim.LocalID, m_prim.Position, m_prim.Force, m_prim.Velocity, m_prim.RotationalVelocity); | ||||
|         }// end Step | ||||
| 
 | ||||
|  | @ -657,7 +521,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
| 
 | ||||
|                  */ | ||||
| 
 | ||||
|                 DetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},decay={4},dir={5},vel={6}", | ||||
|                 VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},decay={4},dir={5},vel={6}", | ||||
|                     m_prim.LocalID, origDir, origVel, addAmount, decayfraction, m_linearMotorDirection, m_lastLinearVelocityVector); | ||||
|             } | ||||
|             else | ||||
|  | @ -669,7 +533,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
|                 m_lastLinearVelocityVector = Vector3.Zero; | ||||
|             } | ||||
| 
 | ||||
|             // convert requested object velocity to world-referenced vector | ||||
|             // convert requested object velocity to object relative vector | ||||
|             Quaternion rotq = m_prim.Orientation; | ||||
|             m_dir = m_lastLinearVelocityVector * rotq; | ||||
| 
 | ||||
|  | @ -722,7 +586,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
|                 if (changed) | ||||
|                 { | ||||
|                     m_prim.Position = pos; | ||||
|                     DetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}", | ||||
|                     VDetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}", | ||||
|                                 m_prim.LocalID, m_BlockingEndPoint, posChange, pos); | ||||
|                 } | ||||
|             } | ||||
|  | @ -732,32 +596,32 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
|             { | ||||
|                 pos.Z = m_prim.Scene.GetTerrainHeightAtXYZ(pos) + 2; | ||||
|                 m_prim.Position = pos; | ||||
|                 DetailLog("{0},MoveLinear,terrainHeight,pos={1}", m_prim.LocalID, pos); | ||||
|                 VDetailLog("{0},MoveLinear,terrainHeight,pos={1}", m_prim.LocalID, pos); | ||||
|             } | ||||
| 
 | ||||
|             // Check if hovering | ||||
|             if ((m_Hoverflags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) | ||||
|             if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) | ||||
|             { | ||||
|                 // We should hover, get the target height | ||||
|                 if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != 0) | ||||
|                 if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0) | ||||
|                 { | ||||
|                     m_VhoverTargetHeight = m_prim.Scene.GetWaterLevel() + m_VhoverHeight; | ||||
|                 } | ||||
|                 if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) | ||||
|                 if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) | ||||
|                 { | ||||
|                     m_VhoverTargetHeight = m_prim.Scene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight; | ||||
|                 } | ||||
|                 if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0) | ||||
|                 if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0) | ||||
|                 { | ||||
|                     m_VhoverTargetHeight = m_VhoverHeight; | ||||
|                 } | ||||
| 
 | ||||
|                 if ((m_Hoverflags & VehicleFlag.HOVER_UP_ONLY) != 0) | ||||
|                 if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0) | ||||
|                 { | ||||
|                     // If body is aready heigher, use its height as target height | ||||
|                     if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z; | ||||
|                 } | ||||
|                 if ((m_Hoverflags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) | ||||
|                 if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) | ||||
|                 { | ||||
|                     if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2) | ||||
|                     { | ||||
|  | @ -779,7 +643,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 DetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_dir, m_VhoverHeight, m_VhoverTargetHeight); | ||||
|                 VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_dir, m_VhoverHeight, m_VhoverTargetHeight); | ||||
| 
 | ||||
| //                m_VhoverEfficiency = 0f;    // 0=boucy, 1=Crit.damped | ||||
| //                m_VhoverTimescale = 0f;        // time to acheive height | ||||
|  | @ -815,7 +679,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
|                 { | ||||
|                     grav.Z = (float)(grav.Z * 1.037125); | ||||
|                 } | ||||
|                 DetailLog("{0},MoveLinear,limitMotorUp,grav={1}", m_prim.LocalID, grav); | ||||
|                 VDetailLog("{0},MoveLinear,limitMotorUp,grav={1}", m_prim.LocalID, grav); | ||||
|                 //End Experimental Values | ||||
|             } | ||||
|             if ((m_flags & (VehicleFlag.NO_X)) != 0) | ||||
|  | @ -844,7 +708,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
|             Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep); | ||||
|             m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount; | ||||
| 
 | ||||
|             DetailLog("{0},MoveLinear,done,pos={1},vel={2},force={3},decay={4}",  | ||||
|             VDetailLog("{0},MoveLinear,done,pos={1},vel={2},force={3},decay={4}",  | ||||
|                         m_prim.LocalID, m_lastPositionVector, m_dir, grav, decayamount); | ||||
| 
 | ||||
|         } // end MoveLinear() | ||||
|  | @ -870,13 +734,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
|                 // There are m_angularMotorApply steps. | ||||
|                 Vector3 origAngularVelocity = m_angularMotorVelocity; | ||||
|                 // ramp up to new value | ||||
|                 //   current velocity  +=                         error                       /    (time to get there / step interval) | ||||
|                 //   current velocity  +=                         error                            /    (time to get there / step interval) | ||||
|                 //                               requested speed            -  last motor speed | ||||
|                 m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) /  (m_angularMotorTimescale / pTimestep); | ||||
|                 m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) /  (m_angularMotorTimescale / pTimestep); | ||||
|                 m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) /  (m_angularMotorTimescale / pTimestep); | ||||
| 
 | ||||
|                 DetailLog("{0},MoveAngular,angularMotorApply,apply={1},origvel={2},dir={3},vel={4}",  | ||||
|                 VDetailLog("{0},MoveAngular,angularMotorApply,apply={1},origvel={2},dir={3},vel={4}",  | ||||
|                         m_prim.LocalID,m_angularMotorApply,origAngularVelocity, m_angularMotorDirection, m_angularMotorVelocity); | ||||
| 
 | ||||
|                 m_angularMotorApply--;        // This is done so that if script request rate is less than phys frame rate the expected | ||||
|  | @ -887,6 +751,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
|                 // No motor recently applied, keep the body velocity | ||||
|                 // and decay the velocity | ||||
|                 m_angularMotorVelocity -= m_angularMotorVelocity /  (m_angularMotorDecayTimescale / pTimestep); | ||||
|                 if (m_angularMotorVelocity.LengthSquared() < 0.00001) | ||||
|                     m_angularMotorVelocity = Vector3.Zero; | ||||
|             } // end motor section | ||||
| 
 | ||||
|             // Vertical attractor section | ||||
|  | @ -924,7 +790,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
|                 vertattr.X += bounce * angularVelocity.X; | ||||
|                 vertattr.Y += bounce * angularVelocity.Y; | ||||
| 
 | ||||
|                 DetailLog("{0},MoveAngular,verticalAttraction,verterr={1},bounce={2},vertattr={3}",  | ||||
|                 VDetailLog("{0},MoveAngular,verticalAttraction,verterr={1},bounce={2},vertattr={3}",  | ||||
|                             m_prim.LocalID, verterr, bounce, vertattr); | ||||
| 
 | ||||
|             } // else vertical attractor is off | ||||
|  | @ -942,13 +808,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
|             { | ||||
|                 m_lastAngularVelocity.X = 0; | ||||
|                 m_lastAngularVelocity.Y = 0; | ||||
|                 DetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity); | ||||
|                 VDetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity); | ||||
|             } | ||||
| 
 | ||||
|             if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) | ||||
|             { | ||||
|                 m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. | ||||
|                 DetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity); | ||||
|                 VDetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity); | ||||
|             } | ||||
| 
 | ||||
|              // apply friction | ||||
|  | @ -958,7 +824,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
|             // Apply to the body | ||||
|             m_prim.RotationalVelocity = m_lastAngularVelocity; | ||||
| 
 | ||||
|             DetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", m_prim.LocalID, decayamount, m_lastAngularVelocity); | ||||
|             VDetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", m_prim.LocalID, decayamount, m_lastAngularVelocity); | ||||
|         } //end MoveAngular | ||||
| 
 | ||||
|         internal void LimitRotation(float timestep) | ||||
|  | @ -1005,11 +871,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
|             if (changed) | ||||
|                 m_prim.Orientation = m_rot; | ||||
| 
 | ||||
|             DetailLog("{0},LimitRotation,done,changed={1},orig={2},new={3}", m_prim.LocalID, changed, rotq, m_rot); | ||||
|             VDetailLog("{0},LimitRotation,done,changed={1},orig={2},new={3}", m_prim.LocalID, changed, rotq, m_rot); | ||||
|         } | ||||
| 
 | ||||
|         // Invoke the detailed logger and output something if it's enabled. | ||||
|         private void DetailLog(string msg, params Object[] args) | ||||
|         private void VDetailLog(string msg, params Object[] args) | ||||
|         { | ||||
|             if (m_prim.Scene.VehicleLoggingEnabled) | ||||
|                 m_prim.Scene.PhysicsLogging.Write(msg, args); | ||||
|  |  | |||
|  | @ -0,0 +1,55 @@ | |||
| /* | ||||
|  * Copyright (c) Contributors, http://opensimulator.org/ | ||||
|  * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions are met: | ||||
|  *     * Redistributions of source code must retain the above copyright | ||||
|  *       notice, this list of conditions and the following disclaimer. | ||||
|  *     * Redistributions in binary form must reproduce the above copyrightD | ||||
|  *       notice, this list of conditions and the following disclaimer in the | ||||
|  *       documentation and/or other materials provided with the distribution. | ||||
|  *     * Neither the name of the OpenSimulator Project nor the | ||||
|  *       names of its contributors may be used to endorse or promote products | ||||
|  *       derived from this software without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||||
|  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||||
|  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
|  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||||
|  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||||
|  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||||
|  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||||
|  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
|  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||||
|  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  */ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Text; | ||||
| using OpenMetaverse; | ||||
| 
 | ||||
| namespace OpenSim.Region.Physics.BulletSPlugin | ||||
| { | ||||
| 
 | ||||
| class BSHingeConstraint : BSConstraint | ||||
| { | ||||
|     public BSHingeConstraint(BulletSim world, BulletBody obj1, BulletBody obj2, | ||||
|                     Vector3 pivotInA, Vector3 pivotInB, | ||||
|                     Vector3 axisInA, Vector3 axisInB, | ||||
|                     bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) | ||||
|     { | ||||
|         m_world = world; | ||||
|         m_body1 = obj1; | ||||
|         m_body2 = obj2; | ||||
|         m_constraint = new BulletConstraint( | ||||
|                             BulletSimAPI.CreateHingeConstraint2(m_world.Ptr, m_body1.Ptr, m_body2.Ptr, | ||||
|                                 pivotInA, pivotInB, | ||||
|                                 axisInA, axisInB, | ||||
|                                 useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); | ||||
|         m_enabled = true; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  | @ -37,11 +37,15 @@ public class BSLinkset | |||
|     private static string LogHeader = "[BULLETSIM LINKSET]"; | ||||
| 
 | ||||
|     private BSPrim m_linksetRoot; | ||||
|     public BSPrim Root { get { return m_linksetRoot; } } | ||||
|     public BSPrim LinksetRoot { get { return m_linksetRoot; } } | ||||
| 
 | ||||
|     private BSScene m_scene; | ||||
|     public BSScene Scene { get { return m_scene; } } | ||||
|     private BSScene m_physicsScene; | ||||
|     public BSScene PhysicsScene { get { return m_physicsScene; } } | ||||
| 
 | ||||
|     static int m_nextLinksetID = 1; | ||||
|     public int LinksetID { get; private set; } | ||||
| 
 | ||||
|     // The children under the root in this linkset | ||||
|     private List<BSPrim> m_children; | ||||
| 
 | ||||
|     // We lock the diddling of linkset classes to prevent any badness. | ||||
|  | @ -73,7 +77,11 @@ public class BSLinkset | |||
|     public BSLinkset(BSScene scene, BSPrim parent) | ||||
|     { | ||||
|         // A simple linkset of one (no children) | ||||
|         m_scene = scene; | ||||
|         LinksetID = m_nextLinksetID++; | ||||
|         // We create LOTS of linksets. | ||||
|         if (m_nextLinksetID < 0)  | ||||
|             m_nextLinksetID = 1; | ||||
|         m_physicsScene = scene; | ||||
|         m_linksetRoot = parent; | ||||
|         m_children = new List<BSPrim>(); | ||||
|         m_mass = parent.MassRaw; | ||||
|  | @ -91,6 +99,9 @@ public class BSLinkset | |||
|         return this; | ||||
|     } | ||||
| 
 | ||||
|     // Remove a child from a linkset. | ||||
|     // Returns a new linkset for the child which is a linkset of one (just the | ||||
|     //    orphened child). | ||||
|     public BSLinkset RemoveMeFromLinkset(BSPrim child) | ||||
|     { | ||||
|         lock (m_linksetActivityLock) | ||||
|  | @ -114,60 +125,9 @@ public class BSLinkset | |||
|         } | ||||
| 
 | ||||
|         // The child is down to a linkset of just itself | ||||
|         return new BSLinkset(Scene, child); | ||||
|         return new BSLinkset(PhysicsScene, child); | ||||
|     } | ||||
| 
 | ||||
|     /* DEPRECATED: this is really bad in that it trys to unlink other prims. | ||||
|     // An existing linkset had one of its members rebuilt or something. | ||||
|     // Go through the linkset and rebuild the pointers to the bodies of the linkset members. | ||||
|     public BSLinkset RefreshLinkset(BSPrim requestor) | ||||
|     { | ||||
|         BSLinkset ret = requestor.Linkset; | ||||
| 
 | ||||
|         lock (m_linksetActivityLock) | ||||
|         { | ||||
|             // The body pointer is refetched in case anything has moved. | ||||
|             System.IntPtr aPtr = BulletSimAPI.GetBodyHandle2(m_scene.World.Ptr, m_linksetRoot.LocalID); | ||||
|             if (aPtr == System.IntPtr.Zero) | ||||
|             { | ||||
|                 // That's odd. We can't find the root of the linkset. | ||||
|                 // The linkset is somehow dead.  The requestor is now a member of a linkset of one. | ||||
|                 DetailLog("{0},RefreshLinkset.RemoveRoot,child={1}", m_linksetRoot.LocalID, m_linksetRoot.LocalID); | ||||
|                 ret = RemoveMeFromLinkset(m_linksetRoot); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 // Reconstruct the pointer to the body of the linkset root. | ||||
|                 DetailLog("{0},RefreshLinkset.RebuildRoot,rootID={1},ptr={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, aPtr); | ||||
|                 m_linksetRoot.Body = new BulletBody(m_linksetRoot.LocalID, aPtr); | ||||
| 
 | ||||
|                 List<BSPrim> toRemove = new List<BSPrim>(); | ||||
|                 foreach (BSPrim bsp in m_children) | ||||
|                 { | ||||
|                     aPtr = BulletSimAPI.GetBodyHandle2(m_scene.World.Ptr, bsp.LocalID); | ||||
|                     if (aPtr == System.IntPtr.Zero) | ||||
|                     { | ||||
|                         toRemove.Add(bsp); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         // Reconstruct the pointer to the body of the linkset root. | ||||
|                         DetailLog("{0},RefreshLinkset.RebuildChild,rootID={1},ptr={2}", bsp.LocalID, m_linksetRoot.LocalID, aPtr); | ||||
|                         bsp.Body = new BulletBody(bsp.LocalID, aPtr); | ||||
|                     } | ||||
|                 } | ||||
|                 foreach (BSPrim bsp in toRemove) | ||||
|                 { | ||||
|                     RemoveChildFromOtherLinkset(bsp); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return ret; | ||||
|     } | ||||
|      */ | ||||
| 
 | ||||
| 
 | ||||
|     // Return 'true' if the passed object is the root object of this linkset | ||||
|     public bool IsRoot(BSPrim requestor) | ||||
|     { | ||||
|  | @ -183,12 +143,15 @@ public class BSLinkset | |||
|     public bool HasChild(BSPrim child) | ||||
|     { | ||||
|         bool ret = false; | ||||
|         foreach (BSPrim bp in m_children) | ||||
|         lock (m_linksetActivityLock) | ||||
|         { | ||||
|             if (child.LocalID == bp.LocalID) | ||||
|             foreach (BSPrim bp in m_children) | ||||
|             { | ||||
|                 ret = true; | ||||
|                 break; | ||||
|                 if (child.LocalID == bp.LocalID) | ||||
|                 { | ||||
|                     ret = true; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return ret; | ||||
|  | @ -209,13 +172,16 @@ public class BSLinkset | |||
|         OMV.Vector3 com = m_linksetRoot.Position * m_linksetRoot.MassRaw; | ||||
|         float totalMass = m_linksetRoot.MassRaw; | ||||
| 
 | ||||
|         foreach (BSPrim bp in m_children) | ||||
|         lock (m_linksetActivityLock) | ||||
|         { | ||||
|             com += bp.Position * bp.MassRaw; | ||||
|             totalMass += bp.MassRaw; | ||||
|             foreach (BSPrim bp in m_children) | ||||
|             { | ||||
|                 com += bp.Position * bp.MassRaw; | ||||
|                 totalMass += bp.MassRaw; | ||||
|             } | ||||
|             if (totalMass != 0f) | ||||
|                 com /= totalMass; | ||||
|         } | ||||
|         if (totalMass != 0f) | ||||
|             com /= totalMass; | ||||
| 
 | ||||
|         return com; | ||||
|     } | ||||
|  | @ -224,29 +190,83 @@ public class BSLinkset | |||
|     { | ||||
|         OMV.Vector3 com = m_linksetRoot.Position; | ||||
| 
 | ||||
|         foreach (BSPrim bp in m_children) | ||||
|         lock (m_linksetActivityLock) | ||||
|         { | ||||
|             com += bp.Position * bp.MassRaw; | ||||
|             foreach (BSPrim bp in m_children) | ||||
|             { | ||||
|                 com += bp.Position * bp.MassRaw; | ||||
|             } | ||||
|             com /= (m_children.Count + 1); | ||||
|         } | ||||
|         com /= (m_children.Count + 1); | ||||
| 
 | ||||
|         return com; | ||||
|     } | ||||
| 
 | ||||
|     // When physical properties are changed the linkset needs to recalculate | ||||
|     //   its internal properties. | ||||
|     public void Refresh(BSPrim requestor) | ||||
|     { | ||||
|         // If there are no children, there aren't any constraints to recompute | ||||
|         if (!HasAnyChildren) | ||||
|             return; | ||||
| 
 | ||||
|         // Only the root does the recomputation | ||||
|         if (IsRoot(requestor)) | ||||
|         { | ||||
|             PhysicsScene.TaintedObject("BSLinkSet.Refresh", delegate() | ||||
|             { | ||||
|                 RecomputeLinksetConstraintVariables(); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // Call each of the constraints that make up this linkset and recompute the | ||||
|     //    various transforms and variables. Used when objects are added or removed | ||||
|     //    from a linkset to make sure the constraints know about the new mass and | ||||
|     //    geometry. | ||||
|     // Must only be called at taint time!! | ||||
|     private bool RecomputeLinksetConstraintVariables() | ||||
|     { | ||||
|         float linksetMass = LinksetMass; | ||||
|         lock (m_linksetActivityLock) | ||||
|         { | ||||
|             foreach (BSPrim child in m_children) | ||||
|             { | ||||
|                 BSConstraint constrain; | ||||
|                 if (m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.Body, child.Body, out constrain)) | ||||
|                 { | ||||
|                     // DetailLog("{0},BSLinkset.RecomputeLinksetConstraintVariables,taint,child={1},mass={2},A={3},B={4}",  | ||||
|                     //         LinksetRoot.LocalID, child.LocalID, linksetMass, constrain.Body1.ID, constrain.Body2.ID); | ||||
|                     constrain.RecomputeConstraintVariables(linksetMass); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     // Non-fatal error that can happen when children are being added to the linkset but | ||||
|                     //    their constraints have not been created yet. | ||||
|                     // Caused by the fact that m_children is built at run time but building constraints | ||||
|                     //    happens at taint time. | ||||
|                     // m_physicsScene.Logger.ErrorFormat("[BULLETSIM LINKSET] RecomputeLinksetConstraintVariables: constraint not found for root={0}, child={1}", | ||||
|                     //                                 m_linksetRoot.Body.ID, child.Body.ID); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     // I am the root of a linkset and a new child is being added | ||||
|     // Called while LinkActivity is locked. | ||||
|     public void AddChildToLinkset(BSPrim child) | ||||
|     private void AddChildToLinkset(BSPrim child) | ||||
|     { | ||||
|         if (!HasChild(child)) | ||||
|         { | ||||
|             m_children.Add(child); | ||||
| 
 | ||||
|             BSPrim root = Root; // capture the root as of now | ||||
|             m_scene.TaintedObject("AddChildToLinkset", delegate() | ||||
|             BSPrim rootx = LinksetRoot; // capture the root as of now | ||||
|             BSPrim childx = child; | ||||
|             m_physicsScene.TaintedObject("AddChildToLinkset", delegate() | ||||
|             { | ||||
|                 DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, m_linksetRoot.LocalID); | ||||
|                 DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID); | ||||
|                 PhysicallyLinkAChildToRoot(root, child);     // build the physical binding between me and the child | ||||
|                 PhysicallyLinkAChildToRoot(rootx, childx);     // build the physical binding between me and the child | ||||
|             }); | ||||
|         } | ||||
|         return; | ||||
|  | @ -257,31 +277,33 @@ public class BSLinkset | |||
|     //    it's still connected to the linkset. | ||||
|     // Normal OpenSimulator operation will never do this because other SceneObjectPart information | ||||
|     //    has to be updated also (like pointer to prim's parent). | ||||
|     public void RemoveChildFromOtherLinkset(BSPrim pchild) | ||||
|     private void RemoveChildFromOtherLinkset(BSPrim pchild) | ||||
|     { | ||||
|         pchild.Linkset = new BSLinkset(m_scene, pchild); | ||||
|         pchild.Linkset = new BSLinkset(m_physicsScene, pchild); | ||||
|         RemoveChildFromLinkset(pchild); | ||||
|     } | ||||
| 
 | ||||
|     // I am the root of a linkset and one of my children is being removed. | ||||
|     // Safe to call even if the child is not really in my linkset. | ||||
|     public void RemoveChildFromLinkset(BSPrim child) | ||||
|     private void RemoveChildFromLinkset(BSPrim child) | ||||
|     { | ||||
|         if (m_children.Remove(child)) | ||||
|         { | ||||
|             BSPrim root = Root; // capture the root as of now | ||||
|             m_scene.TaintedObject("RemoveChildFromLinkset", delegate() | ||||
|             BSPrim rootx = LinksetRoot; // capture the root as of now | ||||
|             BSPrim childx = child; | ||||
|             m_physicsScene.TaintedObject("RemoveChildFromLinkset", delegate() | ||||
|             { | ||||
|                 DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID); | ||||
|                 DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID); | ||||
| 
 | ||||
|                 PhysicallyUnlinkAChildFromRoot(root, child); | ||||
|                 PhysicallyUnlinkAChildFromRoot(rootx, childx); | ||||
|             }); | ||||
| 
 | ||||
|             RecomputeLinksetConstraintVariables(); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             // This will happen if we remove the root of the linkset first. Non-fatal occurance. | ||||
|             // m_scene.Logger.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset", LogHeader); | ||||
|             // PhysicsScene.Logger.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset", LogHeader); | ||||
|         } | ||||
|         return; | ||||
|     } | ||||
|  | @ -293,48 +315,81 @@ public class BSLinkset | |||
|         // Zero motion for children so they don't interpolate | ||||
|         childPrim.ZeroMotion(); | ||||
| 
 | ||||
|         // Relative position normalized to the root prim | ||||
|         // Essentually a vector pointing from center of rootPrim to center of childPrim | ||||
|         OMV.Vector3 childRelativePosition = childPrim.Position - rootPrim.Position; | ||||
| 
 | ||||
|         // real world coordinate of midpoint between the two objects | ||||
|         OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2); | ||||
| 
 | ||||
|         // create a constraint that allows no freedom of movement between the two objects | ||||
|         // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 | ||||
|         DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2},rLoc={3},cLoc={4},midLoc={5}",  | ||||
|             rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID, rootPrim.Position, childPrim.Position, midPoint); | ||||
|         BS6DofConstraint constrain = new BS6DofConstraint( | ||||
|                         m_physicsScene.World, rootPrim.Body, childPrim.Body, | ||||
|                         midPoint, | ||||
|                         true, | ||||
|                         true | ||||
|                         ); | ||||
|         /* NOTE: below is an attempt to build constraint with full frame computation, etc. | ||||
|          *     Using the midpoint is easier since it lets the Bullet code use the transforms | ||||
|          *     of the objects. | ||||
|          * Code left as a warning to future programmers. | ||||
|         // ================================================================================== | ||||
|         // relative position normalized to the root prim | ||||
|         OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation); | ||||
|         OMV.Vector3 childRelativePosition = (childPrim.Position - rootPrim.Position) * invThisOrientation; | ||||
| 
 | ||||
|         // relative rotation of the child to the parent | ||||
|         OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation; | ||||
|         OMV.Quaternion inverseChildRelativeRotation = OMV.Quaternion.Inverse(childRelativeRotation); | ||||
| 
 | ||||
|         // create a constraint that allows no freedom of movement between the two objects | ||||
|         // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 | ||||
|         // DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID); | ||||
|         DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); | ||||
|         BS6DofConstraint constrain = new BS6DofConstraint( | ||||
|                         m_scene.World, rootPrim.Body, childPrim.Body, | ||||
|                         childRelativePosition, | ||||
|                         childRelativeRotation, | ||||
|                         PhysicsScene.World, rootPrim.Body, childPrim.Body, | ||||
|                         OMV.Vector3.Zero, | ||||
|                         -childRelativeRotation | ||||
|                         OMV.Quaternion.Inverse(rootPrim.Orientation), | ||||
|                         OMV.Vector3.Zero, | ||||
|                         OMV.Quaternion.Inverse(childPrim.Orientation), | ||||
|                         // A point half way between the parent and child | ||||
|                         // childRelativePosition/2, | ||||
|                         // childRelativeRotation, | ||||
|                         // childRelativePosition/2, | ||||
|                         // inverseChildRelativeRotation, | ||||
|                         true, | ||||
|                         true | ||||
|                         ); | ||||
|         m_scene.Constraints.AddConstraint(constrain); | ||||
|         // ================================================================================== | ||||
|         */ | ||||
| 
 | ||||
|         m_physicsScene.Constraints.AddConstraint(constrain); | ||||
| 
 | ||||
|         // zero linear and angular limits makes the objects unable to move in relation to each other | ||||
|         constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); | ||||
|         constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); | ||||
| 
 | ||||
|         // tweek the constraint to increase stability | ||||
|         constrain.UseFrameOffset(m_scene.BoolNumeric(m_scene.Params.linkConstraintUseFrameOffset)); | ||||
|         constrain.TranslationalLimitMotor(m_scene.BoolNumeric(m_scene.Params.linkConstraintEnableTransMotor), | ||||
|                         m_scene.Params.linkConstraintTransMotorMaxVel, | ||||
|                         m_scene.Params.linkConstraintTransMotorMaxForce); | ||||
|         constrain.SetCFMAndERP(m_scene.Params.linkConstraintCFM, m_scene.Params.linkConstraintERP); | ||||
|         constrain.UseFrameOffset(PhysicsScene.BoolNumeric(PhysicsScene.Params.linkConstraintUseFrameOffset)); | ||||
|         constrain.TranslationalLimitMotor(PhysicsScene.BoolNumeric(PhysicsScene.Params.linkConstraintEnableTransMotor), | ||||
|                         PhysicsScene.Params.linkConstraintTransMotorMaxVel, | ||||
|                         PhysicsScene.Params.linkConstraintTransMotorMaxForce); | ||||
|         constrain.SetCFMAndERP(PhysicsScene.Params.linkConstraintCFM, PhysicsScene.Params.linkConstraintERP); | ||||
| 
 | ||||
|         RecomputeLinksetConstraintVariables(); | ||||
|     } | ||||
| 
 | ||||
|     // Remove linkage between myself and a particular child | ||||
|     // Called at taint time! | ||||
|     private void PhysicallyUnlinkAChildFromRoot(BSPrim rootPrim, BSPrim childPrim) | ||||
|     { | ||||
|         // DebugLog("{0}: PhysicallyUnlinkAChildFromRoot: RemoveConstraint between root prim {1} and child prim {2}",  | ||||
|         //             LogHeader, rootPrim.LocalID, childPrim.LocalID); | ||||
|         DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); | ||||
| 
 | ||||
|         m_scene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body, childPrim.Body); | ||||
|         // Find the constraint for this link and get rid of it from the overall collection and from my list | ||||
|         m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body, childPrim.Body); | ||||
| 
 | ||||
|         // Make the child refresh its location | ||||
|         BulletSimAPI.PushUpdate2(childPrim.Body.Ptr); | ||||
|     } | ||||
|  | @ -343,23 +398,15 @@ public class BSLinkset | |||
|     // Called at taint time! | ||||
|     private void PhysicallyUnlinkAllChildrenFromRoot(BSPrim rootPrim) | ||||
|     { | ||||
|         // DebugLog("{0}: PhysicallyUnlinkAllChildren:", LogHeader); | ||||
|         DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); | ||||
| 
 | ||||
|         m_scene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body); | ||||
|     } | ||||
| 
 | ||||
|     // Invoke the detailed logger and output something if it's enabled. | ||||
|     private void DebugLog(string msg, params Object[] args) | ||||
|     { | ||||
|         if (m_scene.ShouldDebugLog) | ||||
|             m_scene.Logger.DebugFormat(msg, args); | ||||
|         m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body); | ||||
|     } | ||||
| 
 | ||||
|     // Invoke the detailed logger and output something if it's enabled. | ||||
|     private void DetailLog(string msg, params Object[] args) | ||||
|     { | ||||
|         m_scene.PhysicsLogging.Write(msg, args); | ||||
|         m_physicsScene.PhysicsLogging.Write(msg, args); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -42,8 +42,6 @@ public sealed class BSPrim : PhysicsActor | |||
|     private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
|     private static readonly string LogHeader = "[BULLETS PRIM]"; | ||||
| 
 | ||||
|     private void DebugLog(string mm, params Object[] xx) { if (_scene.ShouldDebugLog) m_log.DebugFormat(mm, xx); } | ||||
| 
 | ||||
|     private IMesh _mesh; | ||||
|     private PrimitiveBaseShape _pbs; | ||||
|     private ShapeData.PhysicsShapeType _shapeType; | ||||
|  | @ -141,8 +139,8 @@ public sealed class BSPrim : PhysicsActor | |||
|         _friction = _scene.Params.defaultFriction;  // TODO: compute based on object material | ||||
|         _density = _scene.Params.defaultDensity;    // TODO: compute based on object material | ||||
|         _restitution = _scene.Params.defaultRestitution; | ||||
|         _linkset = new BSLinkset(_scene, this);     // a linkset of one | ||||
|         _vehicle = new BSDynamics(this);            // add vehicleness | ||||
|         _linkset = new BSLinkset(Scene, this);     // a linkset of one | ||||
|         _vehicle = new BSDynamics(Scene, this);            // add vehicleness | ||||
|         _mass = CalculateMass(); | ||||
|         // do the actual object creation at taint time | ||||
|         DetailLog("{0},BSPrim.constructor,call", LocalID); | ||||
|  | @ -163,13 +161,13 @@ public sealed class BSPrim : PhysicsActor | |||
|         // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); | ||||
| 
 | ||||
|         // Undo any links between me and any other object | ||||
|         BSPrim parentBefore = _linkset.Root; | ||||
|         BSPrim parentBefore = _linkset.LinksetRoot; | ||||
|         int childrenBefore = _linkset.NumberOfChildren; | ||||
| 
 | ||||
|         _linkset = _linkset.RemoveMeFromLinkset(this); | ||||
| 
 | ||||
|         DetailLog("{0},BSPrim.Destroy,call,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}", | ||||
|             LocalID, parentBefore.LocalID, childrenBefore, _linkset.Root.LocalID, _linkset.NumberOfChildren); | ||||
|             LocalID, parentBefore.LocalID, childrenBefore, _linkset.LinksetRoot.LocalID, _linkset.NumberOfChildren); | ||||
| 
 | ||||
|         // Undo any vehicle properties | ||||
|         this.VehicleType = (int)Vehicle.TYPE_NONE; | ||||
|  | @ -193,7 +191,7 @@ public sealed class BSPrim : PhysicsActor | |||
|             { | ||||
|                 _mass = CalculateMass();   // changing size changes the mass | ||||
|                 BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical); | ||||
|                 // DetailLog("{0}: BSPrim.setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical); | ||||
|                 DetailLog("{0}: BSPrim.setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical); | ||||
|                 RecreateGeomAndObject(); | ||||
|             }); | ||||
|         }  | ||||
|  | @ -232,14 +230,13 @@ public sealed class BSPrim : PhysicsActor | |||
|         BSPrim parent = obj as BSPrim; | ||||
|         if (parent != null) | ||||
|         { | ||||
|             DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, parent.LocalID); | ||||
|             BSPrim parentBefore = _linkset.Root; | ||||
|             BSPrim parentBefore = _linkset.LinksetRoot; | ||||
|             int childrenBefore = _linkset.NumberOfChildren; | ||||
| 
 | ||||
|             _linkset = parent.Linkset.AddMeToLinkset(this); | ||||
| 
 | ||||
|             DetailLog("{0},BSPrim.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}",  | ||||
|                 LocalID, parentBefore.LocalID, childrenBefore, _linkset.Root.LocalID, _linkset.NumberOfChildren); | ||||
|                 LocalID, parentBefore.LocalID, childrenBefore, _linkset.LinksetRoot.LocalID, _linkset.NumberOfChildren); | ||||
|         } | ||||
|         return;  | ||||
|     } | ||||
|  | @ -248,16 +245,14 @@ public sealed class BSPrim : PhysicsActor | |||
|     public override void delink() { | ||||
|         // TODO: decide if this parent checking needs to happen at taint time | ||||
|         // Race condition here: if link() and delink() in same simulation tick, the delink will not happen | ||||
|         DebugLog("{0}: delink {1}/{2}. Parent={3}", LogHeader, _avName, _localID,  | ||||
|                             _linkset.Root._avName+"/"+_linkset.Root.LocalID.ToString()); | ||||
| 
 | ||||
|         BSPrim parentBefore = _linkset.Root; | ||||
|         BSPrim parentBefore = _linkset.LinksetRoot; | ||||
|         int childrenBefore = _linkset.NumberOfChildren; | ||||
|          | ||||
|         _linkset = _linkset.RemoveMeFromLinkset(this); | ||||
| 
 | ||||
|         DetailLog("{0},BSPrim.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ",  | ||||
|             LocalID, parentBefore.LocalID, childrenBefore, _linkset.Root.LocalID, _linkset.NumberOfChildren); | ||||
|             LocalID, parentBefore.LocalID, childrenBefore, _linkset.LinksetRoot.LocalID, _linkset.NumberOfChildren); | ||||
|         return;  | ||||
|     } | ||||
| 
 | ||||
|  | @ -354,7 +349,7 @@ public sealed class BSPrim : PhysicsActor | |||
|             { | ||||
|                 // Done at taint time so we're sure the physics engine is not using the variables | ||||
|                 // Vehicle code changes the parameters for this vehicle type. | ||||
|                 _vehicle.ProcessTypeChange(type); | ||||
|                 _vehicle.ProcessTypeChange(type, Scene.LastSimulatedTimestep); | ||||
|                 // Tell the scene about the vehicle so it will get processing each frame. | ||||
|                 _scene.VehicleInSceneTypeChanged(this, type); | ||||
|             }); | ||||
|  | @ -486,17 +481,17 @@ public sealed class BSPrim : PhysicsActor | |||
|     // No locking here because only called when it is safe | ||||
|     private void SetObjectDynamic() | ||||
|     { | ||||
|         // RA: remove this for the moment. | ||||
|         // The problem is that dynamic objects are hulls so if we are becoming physical | ||||
|         //    the shape has to be checked and possibly built. | ||||
|         //    Maybe a VerifyCorrectPhysicalShape() routine? | ||||
|         // RecreateGeomAndObject(); | ||||
|         // If it's becoming dynamic, it will need hullness | ||||
|         VerifyCorrectPhysicalShape(); | ||||
| 
 | ||||
|         // Bullet wants static objects to have a mass of zero | ||||
|         float mass = IsStatic ? 0f : _mass; | ||||
| 
 | ||||
|         BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass); | ||||
| 
 | ||||
|         // recompute any linkset parameters | ||||
|         _linkset.Refresh(this); | ||||
| 
 | ||||
|         CollisionFlags cf = BulletSimAPI.GetCollisionFlags2(Body.Ptr); | ||||
|         DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, cf); | ||||
|     } | ||||
|  | @ -504,7 +499,9 @@ public sealed class BSPrim : PhysicsActor | |||
|     // prims don't fly | ||||
|     public override bool Flying {  | ||||
|         get { return _flying; }  | ||||
|         set { _flying = value; }  | ||||
|         set { | ||||
|             _flying = value; | ||||
|         }  | ||||
|     } | ||||
|     public override bool SetAlwaysRun {  | ||||
|         get { return _setAlwaysRun; }  | ||||
|  | @ -1039,7 +1036,14 @@ public sealed class BSPrim : PhysicsActor | |||
|     // No locking here because this is done when we know physics is not simulating | ||||
|     private void CreateGeomMesh() | ||||
|     { | ||||
|         float lod = _pbs.SculptEntry ? _scene.SculptLOD : _scene.MeshLOD; | ||||
|         // level of detail based on size and type of the object | ||||
|         float lod = _scene.MeshLOD; | ||||
|         if (_pbs.SculptEntry)  | ||||
|             lod = _scene.SculptLOD; | ||||
|         float maxAxis = Math.Max(_size.X, Math.Max(_size.Y, _size.Z)); | ||||
|         if (maxAxis > _scene.MeshMegaPrimThreshold)  | ||||
|             lod = _scene.MeshMegaPrimLOD; | ||||
| 
 | ||||
|         ulong newMeshKey = (ulong)_pbs.GetMeshKey(_size, lod); | ||||
|         // m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey); | ||||
| 
 | ||||
|  | @ -1095,28 +1099,21 @@ public sealed class BSPrim : PhysicsActor | |||
|         // if the hull hasn't changed, don't rebuild it | ||||
|         if (newHullKey == _hullKey) return; | ||||
| 
 | ||||
|         DetailLog("{0},BSPrim.CreateGeomHull,create,key={1}", LocalID, _meshKey); | ||||
|         DetailLog("{0},BSPrim.CreateGeomHull,create,oldKey={1},newKey={2}", LocalID, _hullKey, newHullKey); | ||||
|          | ||||
|         // Since we're recreating new, get rid of any previously generated shape | ||||
|         if (_hullKey != 0) | ||||
|         { | ||||
|             // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey); | ||||
|             DetailLog("{0},BSPrim.CreateGeomHull,deleteOldHull,key={1}", LocalID, _meshKey); | ||||
|             DetailLog("{0},BSPrim.CreateGeomHull,deleteOldHull,key={1}", LocalID, _hullKey); | ||||
|             BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey); | ||||
|             _hullKey = 0; | ||||
|             _hulls.Clear(); | ||||
|             DetailLog("{0},BSPrim.CreateGeomHull,deleteOldMesh,key={1}", LocalID, _meshKey); | ||||
|             BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey); | ||||
|             _mesh = null;   // the mesh cannot match either | ||||
|             _meshKey = 0; | ||||
|         } | ||||
| 
 | ||||
|         _hullKey = newHullKey; | ||||
|         if (_meshKey != _hullKey) | ||||
|         { | ||||
|             // if the underlying mesh has changed, rebuild it | ||||
|             CreateGeomMesh(); | ||||
|         } | ||||
| 
 | ||||
|         // Make sure the underlying mesh exists and is correct | ||||
|         CreateGeomMesh(); | ||||
| 
 | ||||
|         int[] indices = _mesh.getIndexListAsInt(); | ||||
|         List<OMV.Vector3> vertices = _mesh.getVertexList(); | ||||
|  | @ -1142,7 +1139,7 @@ public sealed class BSPrim : PhysicsActor | |||
|         // create the hull into the _hulls variable | ||||
|         convexBuilder.process(dcomp); | ||||
| 
 | ||||
|         // Convert the vertices and indices for passing to unmanaged | ||||
|         // Convert the vertices and indices for passing to unmanaged. | ||||
|         // The hull information is passed as a large floating point array.  | ||||
|         // The format is: | ||||
|         //  convHulls[0] = number of hulls | ||||
|  | @ -1214,6 +1211,27 @@ public sealed class BSPrim : PhysicsActor | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     private void VerifyCorrectPhysicalShape() | ||||
|     { | ||||
|         if (IsStatic) | ||||
|         { | ||||
|             // if static, we don't need a hull so, if there is one, rebuild without it | ||||
|             if (_hullKey != 0) | ||||
|             { | ||||
|                 RecreateGeomAndObject(); | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             // if not static, it will need a hull to efficiently collide with things | ||||
|             if (_hullKey == 0) | ||||
|             { | ||||
|                 RecreateGeomAndObject(); | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // Create an object in Bullet if it has not already been created | ||||
|     // No locking here because this is done when the physics engine is not simulating | ||||
|     // Returns 'true' if an object was actually created. | ||||
|  | @ -1338,13 +1356,12 @@ public sealed class BSPrim : PhysicsActor | |||
|             _acceleration = entprop.Acceleration; | ||||
|             _rotationalVelocity = entprop.RotationalVelocity; | ||||
| 
 | ||||
|             // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}, vel={5}, acc={6}, rvel={7}",  | ||||
|             //         LogHeader, LocalID, changed, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); | ||||
|             DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", | ||||
|                     LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); | ||||
| 
 | ||||
|             base.RequestPhysicsterseUpdate(); | ||||
|         } | ||||
|             /* | ||||
|         else | ||||
|         { | ||||
|             // For debugging, we also report the movement of children | ||||
|  | @ -1352,10 +1369,12 @@ public sealed class BSPrim : PhysicsActor | |||
|                     LocalID, entprop.Position, entprop.Rotation, entprop.Velocity,  | ||||
|                     entprop.Acceleration, entprop.RotationalVelocity); | ||||
|         } | ||||
|              */ | ||||
|     } | ||||
| 
 | ||||
|     // I've collided with something | ||||
|     CollisionEventUpdate collisionCollection = null; | ||||
|     // Called at taint time from within the Step() function | ||||
|     CollisionEventUpdate collisionCollection; | ||||
|     public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) | ||||
|     { | ||||
|         // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); | ||||
|  | @ -1367,6 +1386,17 @@ public sealed class BSPrim : PhysicsActor | |||
|             _collidingGroundStep = _scene.SimulationStep; | ||||
|         } | ||||
| 
 | ||||
|         // DetailLog("{0},BSPrim.Collison,call,with={1}", LocalID, collidingWith); | ||||
|         BSPrim collidingWithPrim; | ||||
|         if (_scene.Prims.TryGetValue(collidingWith, out collidingWithPrim)) | ||||
|         { | ||||
|             // prims in the same linkset cannot collide with each other | ||||
|             if (this.Linkset.LinksetID == collidingWithPrim.Linkset.LinksetID) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // if someone is subscribed to collision events.... | ||||
|         if (_subscribedEventsMs != 0) { | ||||
|             // throttle the collisions to the number of milliseconds specified in the subscription | ||||
|  | @ -1387,7 +1417,9 @@ public sealed class BSPrim : PhysicsActor | |||
|         if (collisionCollection != null && collisionCollection.Count > 0) | ||||
|         { | ||||
|             base.SendCollisionUpdate(collisionCollection); | ||||
|             collisionCollection.Clear(); | ||||
|             // The collisionCollection structure is passed around in the simulator. | ||||
|             // Make sure we don't have a handle to that one and that a new one is used next time. | ||||
|             collisionCollection = null; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -73,15 +73,22 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
|     private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||||
|     private static readonly string LogHeader = "[BULLETS SCENE]"; | ||||
| 
 | ||||
|     public void DebugLog(string mm, params Object[] xx) { if (ShouldDebugLog) m_log.DebugFormat(mm, xx); } | ||||
|     // The name of the region we're working for. | ||||
|     public string RegionName { get; private set; } | ||||
| 
 | ||||
|     public string BulletSimVersion = "?"; | ||||
| 
 | ||||
|     private Dictionary<uint, BSCharacter> m_avatars = new Dictionary<uint, BSCharacter>(); | ||||
|     public Dictionary<uint, BSCharacter> Characters { get { return m_avatars; } } | ||||
| 
 | ||||
|     private Dictionary<uint, BSPrim> m_prims = new Dictionary<uint, BSPrim>(); | ||||
|     public Dictionary<uint, BSPrim> Prims { get { return m_prims; } } | ||||
| 
 | ||||
|     private HashSet<BSCharacter> m_avatarsWithCollisions = new HashSet<BSCharacter>(); | ||||
|     private HashSet<BSPrim> m_primsWithCollisions = new HashSet<BSPrim>(); | ||||
| 
 | ||||
|     private List<BSPrim> m_vehicles = new List<BSPrim>(); | ||||
| 
 | ||||
|     private float[] m_heightMap; | ||||
|     private float m_waterLevel; | ||||
|     private uint m_worldID; | ||||
|  | @ -95,16 +102,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
|     private int m_detailedStatsStep = 0; | ||||
| 
 | ||||
|     public IMesher mesher; | ||||
|     private float m_meshLOD; | ||||
|     public float MeshLOD | ||||
|     { | ||||
|         get { return m_meshLOD; } | ||||
|     } | ||||
|     private float m_sculptLOD; | ||||
|     public float SculptLOD | ||||
|     { | ||||
|         get { return m_sculptLOD; } | ||||
|     } | ||||
|     // Level of Detail values kept as float because that's what the Meshmerizer wants | ||||
|     public float MeshLOD { get; private set; } | ||||
|     public float MeshMegaPrimLOD { get; private set; } | ||||
|     public float MeshMegaPrimThreshold { get; private set; } | ||||
|     public float SculptLOD { get; private set; } | ||||
| 
 | ||||
|     private BulletSim m_worldSim; | ||||
|     public BulletSim World | ||||
|  | @ -179,8 +181,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
|     ConfigurationParameters[] m_params; | ||||
|     GCHandle m_paramsHandle; | ||||
| 
 | ||||
|     public bool ShouldDebugLog { get; private set; } | ||||
| 
 | ||||
|     // Handle to the callback used by the unmanaged code to call into the managed code. | ||||
|     // Used for debug logging. | ||||
|     // Need to store the handle in a persistant variable so it won't be freed. | ||||
|     private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle; | ||||
| 
 | ||||
|     // Sometimes you just have to log everything. | ||||
|  | @ -196,6 +199,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
|     public BSScene(string identifier) | ||||
|     { | ||||
|         m_initialized = false; | ||||
|         // we are passed the name of the region we're working for. | ||||
|         RegionName = identifier; | ||||
|     } | ||||
| 
 | ||||
|     public override void Initialise(IMesher meshmerizer, IConfigSource config) | ||||
|  | @ -281,10 +286,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
|                 // Very detailed logging for physics debugging | ||||
|                 m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false); | ||||
|                 m_physicsLoggingDir = pConfig.GetString("PhysicsLoggingDir", "."); | ||||
|                 m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-"); | ||||
|                 m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-%REGIONNAME%-"); | ||||
|                 m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5); | ||||
|                 // Very detailed logging for vehicle debugging | ||||
|                 m_vehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false); | ||||
| 
 | ||||
|                 // Do any replacements in the parameters | ||||
|                 m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | @ -413,7 +421,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
|         // prevent simulation until we've been initialized | ||||
|         if (!m_initialized) return 10.0f; | ||||
| 
 | ||||
|         long simulateStartTime = Util.EnvironmentTickCount(); | ||||
|         int simulateStartTime = Util.EnvironmentTickCount(); | ||||
| 
 | ||||
|         // update the prim states while we know the physics engine is not busy | ||||
|         ProcessTaints(); | ||||
|  | @ -434,8 +442,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
|         catch (Exception e) | ||||
|         { | ||||
|             m_log.WarnFormat("{0},PhysicsStep Exception: substeps={1}, updates={2}, colliders={3}, e={4}", LogHeader, numSubSteps, updatedEntityCount, collidersCount, e); | ||||
|             DetailLog("{0},PhysicsStepException,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount); | ||||
|             // updatedEntityCount = 0; | ||||
|             // DetailLog("{0},PhysicsStepException,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount); | ||||
|             updatedEntityCount = 0; | ||||
|             collidersCount = 0; | ||||
|         } | ||||
| 
 | ||||
|  | @ -511,8 +519,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
|         // long simulateTotalTime = Util.EnvironmentTickCountSubtract(simulateStartTime); | ||||
|         // return (timeStep * (float)simulateTotalTime); | ||||
| 
 | ||||
|         // TODO: FIX THIS: fps calculation wrong. This calculation always returns about 1 in normal operation. | ||||
|         return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f; | ||||
|         // TODO: FIX THIS: fps calculation possibly wrong. | ||||
|         // This calculation says 1/timeStep is the ideal frame rate. Any time added to | ||||
|         //    that by the physics simulation gives a slower frame rate. | ||||
|         long totalSimulationTime = Util.EnvironmentTickCountSubtract(simulateStartTime); | ||||
|         if (totalSimulationTime >= timeStep) | ||||
|             return 0; | ||||
|         return 1f / (timeStep + totalSimulationTime); | ||||
|     } | ||||
| 
 | ||||
|     // Something has collided | ||||
|  | @ -529,6 +542,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
|         else if (m_avatars.ContainsKey(collidingWith)) | ||||
|             type = ActorTypes.Agent; | ||||
| 
 | ||||
|         // DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith); | ||||
| 
 | ||||
|         BSPrim prim; | ||||
|         if (m_prims.TryGetValue(localID, out prim)) { | ||||
|             prim.Collide(collidingWith, type, collidePoint, collideNormal, penitration); | ||||
|  | @ -590,12 +605,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
|         // make sure no stepping happens while we're deleting stuff | ||||
|         m_initialized = false; | ||||
| 
 | ||||
|         if (m_constraintCollection != null) | ||||
|         { | ||||
|             m_constraintCollection.Dispose(); | ||||
|             m_constraintCollection = null; | ||||
|         } | ||||
| 
 | ||||
|         foreach (KeyValuePair<uint, BSCharacter> kvp in m_avatars) | ||||
|         { | ||||
|             kvp.Value.Destroy(); | ||||
|  | @ -608,6 +617,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
|         } | ||||
|         m_prims.Clear(); | ||||
| 
 | ||||
|         // Now that the prims are all cleaned up, there should be no constraints left | ||||
|         if (m_constraintCollection != null) | ||||
|         { | ||||
|             m_constraintCollection.Dispose(); | ||||
|             m_constraintCollection = null; | ||||
|         } | ||||
| 
 | ||||
|         // Anything left in the unmanaged code should be cleaned out | ||||
|         BulletSimAPI.Shutdown(WorldID); | ||||
| 
 | ||||
|  | @ -891,16 +907,26 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
|             (s) => { return s.NumericBool(s._forceSimplePrimMeshing); }, | ||||
|             (s,p,l,v) => { s._forceSimplePrimMeshing = s.BoolNumeric(v); } ), | ||||
| 
 | ||||
|         new ParameterDefn("MeshLOD", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", | ||||
|         new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", | ||||
|             8f, | ||||
|             (s,cf,p,v) => { s.m_meshLOD = cf.GetInt(p, (int)v); }, | ||||
|             (s) => { return (float)s.m_meshLOD; }, | ||||
|             (s,p,l,v) => { s.m_meshLOD = (int)v; } ), | ||||
|         new ParameterDefn("SculptLOD", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)", | ||||
|             (s,cf,p,v) => { s.MeshLOD = (float)cf.GetInt(p, (int)v); }, | ||||
|             (s) => { return s.MeshLOD; }, | ||||
|             (s,p,l,v) => { s.MeshLOD = v; } ), | ||||
|         new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters", | ||||
|             16f, | ||||
|             (s,cf,p,v) => { s.MeshMegaPrimLOD = (float)cf.GetInt(p, (int)v); }, | ||||
|             (s) => { return s.MeshMegaPrimLOD; }, | ||||
|             (s,p,l,v) => { s.MeshMegaPrimLOD = v; } ), | ||||
|         new ParameterDefn("MeshLevelOfDetailMegaPrimThreshold", "Size (in meters) of a mesh before using MeshMegaPrimLOD", | ||||
|             10f, | ||||
|             (s,cf,p,v) => { s.MeshMegaPrimThreshold = (float)cf.GetInt(p, (int)v); }, | ||||
|             (s) => { return s.MeshMegaPrimThreshold; }, | ||||
|             (s,p,l,v) => { s.MeshMegaPrimThreshold = v; } ), | ||||
|         new ParameterDefn("SculptLevelOfDetail", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)", | ||||
|             32f, | ||||
|             (s,cf,p,v) => { s.m_sculptLOD = cf.GetInt(p, (int)v); }, | ||||
|             (s) => { return (float)s.m_sculptLOD; }, | ||||
|             (s,p,l,v) => { s.m_sculptLOD = (int)v; } ), | ||||
|             (s,cf,p,v) => { s.SculptLOD = (float)cf.GetInt(p, (int)v); }, | ||||
|             (s) => { return s.SculptLOD; }, | ||||
|             (s,p,l,v) => { s.SculptLOD = v; } ), | ||||
| 
 | ||||
|         new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps", | ||||
|             10f, | ||||
|  | @ -1131,12 +1157,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
|             (s,cf,p,v) => { s.m_detailedStatsStep = cf.GetInt(p, (int)v); }, | ||||
|             (s) => { return (float)s.m_detailedStatsStep; }, | ||||
|             (s,p,l,v) => { s.m_detailedStatsStep = (int)v; } ), | ||||
|         new ParameterDefn("ShouldDebugLog", "Enables detailed DEBUG log statements", | ||||
|             ConfigurationParameters.numericFalse, | ||||
|             (s,cf,p,v) => { s.ShouldDebugLog = cf.GetBoolean(p, s.BoolNumeric(v)); }, | ||||
|             (s) => { return s.NumericBool(s.ShouldDebugLog); }, | ||||
|             (s,p,l,v) => { s.ShouldDebugLog = s.BoolNumeric(v); } ), | ||||
| 
 | ||||
|     }; | ||||
| 
 | ||||
|     // Convert a boolean to our numeric true and false values | ||||
|  |  | |||
|  | @ -415,6 +415,27 @@ public static extern IntPtr Create6DofConstraint2(IntPtr world, IntPtr obj1, Int | |||
|                     Vector3 frame2loc, Quaternion frame2rot, | ||||
|                     bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); | ||||
| 
 | ||||
| [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||||
| public static extern IntPtr Create6DofConstraintToPoint2(IntPtr world, IntPtr obj1, IntPtr obj2, | ||||
|                     Vector3 joinPoint, | ||||
|                     bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); | ||||
| 
 | ||||
| [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||||
| public static extern IntPtr CreateHingeConstraint2(IntPtr world, IntPtr obj1, IntPtr obj2, | ||||
|                     Vector3 pivotinA, Vector3 pivotinB, | ||||
|                     Vector3 axisInA, Vector3 axisInB, | ||||
|                     bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); | ||||
| 
 | ||||
| [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||||
| public static extern void SetConstraintEnable2(IntPtr constrain, float numericTrueFalse); | ||||
| 
 | ||||
| [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||||
| public static extern void SetConstraintNumSolverIterations2(IntPtr constrain, float iterations); | ||||
| 
 | ||||
| [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||||
| public static extern bool SetFrames2(IntPtr constrain,  | ||||
|                 Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot); | ||||
| 
 | ||||
| [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||||
| public static extern bool SetLinearLimits2(IntPtr constrain, Vector3 low, Vector3 hi); | ||||
| 
 | ||||
|  | @ -427,6 +448,9 @@ public static extern bool UseFrameOffset2(IntPtr constrain, float enable); | |||
| [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||||
| public static extern bool TranslationalLimitMotor2(IntPtr constrain, float enable, float targetVel, float maxMotorForce); | ||||
| 
 | ||||
| [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||||
| public static extern bool SetBreakingImpulseThreshold2(IntPtr constrain, float threshold); | ||||
| 
 | ||||
| [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||||
| public static extern bool CalculateTransforms2(IntPtr constrain); | ||||
| 
 | ||||
|  | @ -517,6 +541,9 @@ public static extern bool SetGravity2(IntPtr obj, Vector3 val); | |||
| [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||||
| public static extern IntPtr ClearForces2(IntPtr obj); | ||||
| 
 | ||||
| [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||||
| public static extern IntPtr ClearAllForces2(IntPtr obj); | ||||
| 
 | ||||
| [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||||
| public static extern bool SetMargin2(IntPtr obj, float val); | ||||
| 
 | ||||
|  |  | |||
|  | @ -243,33 +243,38 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|         } | ||||
| 
 | ||||
|         public List<SceneObjectPart> GetLinkParts(int linkType) | ||||
|         { | ||||
|             return GetLinkParts(m_host, linkType); | ||||
|         } | ||||
| 
 | ||||
|         private List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) | ||||
|         { | ||||
|             List<SceneObjectPart> ret = new List<SceneObjectPart>(); | ||||
|             ret.Add(m_host); | ||||
|             ret.Add(part); | ||||
| 
 | ||||
|             switch (linkType) | ||||
|             { | ||||
|             case ScriptBaseClass.LINK_SET: | ||||
|                 return new List<SceneObjectPart>(m_host.ParentGroup.Parts); | ||||
|                 return new List<SceneObjectPart>(part.ParentGroup.Parts); | ||||
| 
 | ||||
|             case ScriptBaseClass.LINK_ROOT: | ||||
|                 ret = new List<SceneObjectPart>(); | ||||
|                 ret.Add(m_host.ParentGroup.RootPart); | ||||
|                 ret.Add(part.ParentGroup.RootPart); | ||||
|                 return ret; | ||||
| 
 | ||||
|             case ScriptBaseClass.LINK_ALL_OTHERS: | ||||
|                 ret = new List<SceneObjectPart>(m_host.ParentGroup.Parts); | ||||
|                 ret = new List<SceneObjectPart>(part.ParentGroup.Parts); | ||||
| 
 | ||||
|                 if (ret.Contains(m_host)) | ||||
|                     ret.Remove(m_host); | ||||
|                 if (ret.Contains(part)) | ||||
|                     ret.Remove(part); | ||||
| 
 | ||||
|                 return ret; | ||||
| 
 | ||||
|             case ScriptBaseClass.LINK_ALL_CHILDREN: | ||||
|                 ret = new List<SceneObjectPart>(m_host.ParentGroup.Parts); | ||||
|                 ret = new List<SceneObjectPart>(part.ParentGroup.Parts); | ||||
| 
 | ||||
|                 if (ret.Contains(m_host.ParentGroup.RootPart)) | ||||
|                     ret.Remove(m_host.ParentGroup.RootPart); | ||||
|                 if (ret.Contains(part.ParentGroup.RootPart)) | ||||
|                     ret.Remove(part.ParentGroup.RootPart); | ||||
|                 return ret; | ||||
| 
 | ||||
|             case ScriptBaseClass.LINK_THIS: | ||||
|  | @ -279,7 +284,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                 if (linkType < 0) | ||||
|                     return new List<SceneObjectPart>(); | ||||
| 
 | ||||
|                 SceneObjectPart target = m_host.ParentGroup.GetLinkNumPart(linkType); | ||||
|                 SceneObjectPart target = part.ParentGroup.GetLinkNumPart(linkType); | ||||
|                 if (target == null) | ||||
|                     return new List<SceneObjectPart>(); | ||||
|                 ret = new List<SceneObjectPart>(); | ||||
|  | @ -325,14 +330,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             return key; | ||||
|         } | ||||
| 
 | ||||
|         // convert a LSL_Rotation to a Quaternion | ||||
|         public static Quaternion Rot2Quaternion(LSL_Rotation r) | ||||
|         { | ||||
|             Quaternion q = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s); | ||||
|             q.Normalize(); | ||||
|             return q; | ||||
|         } | ||||
| 
 | ||||
|         //These are the implementations of the various ll-functions used by the LSL scripts. | ||||
|         public LSL_Float llSin(double f) | ||||
|         { | ||||
|  | @ -1092,9 +1089,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|         public LSL_Float llGround(LSL_Vector offset) | ||||
|         { | ||||
|             m_host.AddScriptLPS(1); | ||||
|             Vector3 pos = m_host.GetWorldPosition() + new Vector3((float)offset.x, | ||||
|                                                                   (float)offset.y, | ||||
|                                                                   (float)offset.z); | ||||
|             Vector3 pos = m_host.GetWorldPosition() + (Vector3)offset; | ||||
| 
 | ||||
|             //Get the slope normal.  This gives us the equation of the plane tangent to the slope. | ||||
|             LSL_Vector vsn = llGroundNormal(offset); | ||||
|  | @ -1338,31 +1333,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             if (part == null || part.ParentGroup.IsDeleted) | ||||
|                 return; | ||||
| 
 | ||||
|             if (scale.x < 0.01) | ||||
|                 scale.x = 0.01; | ||||
|             if (scale.y < 0.01) | ||||
|                 scale.y = 0.01; | ||||
|             if (scale.z < 0.01) | ||||
|                 scale.z = 0.01; | ||||
| 
 | ||||
|             // First we need to check whether or not we need to clamp the size of a physics-enabled prim | ||||
|             PhysicsActor pa = part.ParentGroup.RootPart.PhysActor; | ||||
| 
 | ||||
|             if (pa != null && pa.IsPhysical) | ||||
|             { | ||||
|                 if (scale.x > World.m_maxPhys) | ||||
|                     scale.x = World.m_maxPhys; | ||||
|                 if (scale.y > World.m_maxPhys) | ||||
|                     scale.y = World.m_maxPhys; | ||||
|                 if (scale.z > World.m_maxPhys) | ||||
|                     scale.z = World.m_maxPhys; | ||||
|                 scale.x = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.x)); | ||||
|                 scale.y = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.y)); | ||||
|                 scale.z = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.z)); | ||||
|             } | ||||
| 
 | ||||
|             if (scale.x > World.m_maxNonphys) | ||||
|                 scale.x = World.m_maxNonphys; | ||||
|             if (scale.y > World.m_maxNonphys) | ||||
|                 scale.y = World.m_maxNonphys; | ||||
|             if (scale.z > World.m_maxNonphys) | ||||
|                 scale.z = World.m_maxNonphys; | ||||
|             // Next we clamp the scale to the non-physical min/max | ||||
|             scale.x = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.x)); | ||||
|             scale.y = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.y)); | ||||
|             scale.z = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.z)); | ||||
| 
 | ||||
|             Vector3 tmp = part.Scale; | ||||
|             tmp.X = (float)scale.x; | ||||
|  | @ -1394,7 +1377,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             if (face == ScriptBaseClass.ALL_SIDES) | ||||
|                 face = SceneObjectPart.ALL_SIDES; | ||||
| 
 | ||||
|             m_host.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); | ||||
|             m_host.SetFaceColorAlpha(face, color, null); | ||||
|         } | ||||
| 
 | ||||
|         public void SetTexGen(SceneObjectPart part, int face,int style) | ||||
|  | @ -1981,7 +1964,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|             bool sameParcel = here.GlobalID == there.GlobalID; | ||||
| 
 | ||||
|             if (!sameParcel && !World.Permissions.CanRezObject(m_host.ParentGroup.PrimCount, m_host.ParentGroup.OwnerID, new Vector3((float)pos.x, (float)pos.y, (float)pos.z))) | ||||
|             if (!sameParcel && !World.Permissions.CanRezObject( | ||||
|                 m_host.ParentGroup.PrimCount, m_host.ParentGroup.OwnerID, pos)) | ||||
|             { | ||||
|                 return 0; | ||||
|             } | ||||
|  | @ -2041,13 +2025,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) | ||||
|                     targetPos.z = ground; | ||||
|                 SceneObjectGroup parent = part.ParentGroup; | ||||
|                 LSL_Vector real_vec = !adjust ? targetPos : SetPosAdjust(currentPos, targetPos); | ||||
|                 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z)); | ||||
|                 parent.UpdateGroupPosition(!adjust ? targetPos : | ||||
|                     SetPosAdjust(currentPos, targetPos)); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 LSL_Vector rel_vec = !adjust ? targetPos : SetPosAdjust(currentPos, targetPos); | ||||
|                 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z); | ||||
|                 part.OffsetPosition = !adjust ? targetPos : | ||||
|                     SetPosAdjust(currentPos, targetPos); | ||||
|                 SceneObjectGroup parent = part.ParentGroup; | ||||
|                 parent.HasGroupChanged = true; | ||||
|                 parent.ScheduleGroupForTerseUpdate(); | ||||
|  | @ -2091,7 +2075,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
| //            m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); | ||||
| 
 | ||||
|             return new LSL_Vector(pos.X, pos.Y, pos.Z); | ||||
|             return new LSL_Vector(pos); | ||||
|         } | ||||
| 
 | ||||
|         public void llSetRot(LSL_Rotation rot) | ||||
|  | @ -2102,7 +2086,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             if (m_host.ParentID == 0) | ||||
|             { | ||||
|                 // special case: If we are root, rotate complete SOG to new rotation | ||||
|                 SetRot(m_host, Rot2Quaternion(rot)); | ||||
|                 SetRot(m_host, rot); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|  | @ -2110,7 +2094,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                 SceneObjectPart rootPart = m_host.ParentGroup.RootPart; | ||||
|                 if (rootPart != null) // better safe than sorry | ||||
|                 { | ||||
|                     SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot)); | ||||
|                     SetRot(m_host, rootPart.RotationOffset * (Quaternion)rot); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|  | @ -2120,7 +2104,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|         public void llSetLocalRot(LSL_Rotation rot) | ||||
|         { | ||||
|             m_host.AddScriptLPS(1); | ||||
|             SetRot(m_host, Rot2Quaternion(rot)); | ||||
|             SetRot(m_host, rot); | ||||
|             ScriptSleep(200); | ||||
|         } | ||||
| 
 | ||||
|  | @ -2205,7 +2189,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                 if (local != 0) | ||||
|                     force *= llGetRot(); | ||||
| 
 | ||||
|                 m_host.ParentGroup.RootPart.SetForce(new Vector3((float)force.x, (float)force.y, (float)force.z)); | ||||
|                 m_host.ParentGroup.RootPart.SetForce(force); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -2217,10 +2201,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|             if (!m_host.ParentGroup.IsDeleted) | ||||
|             { | ||||
|                 Vector3 tmpForce = m_host.ParentGroup.RootPart.GetForce(); | ||||
|                 force.x = tmpForce.X; | ||||
|                 force.y = tmpForce.Y; | ||||
|                 force.z = tmpForce.Z; | ||||
|                 force = m_host.ParentGroup.RootPart.GetForce(); | ||||
|             } | ||||
| 
 | ||||
|             return force; | ||||
|  | @ -2229,8 +2210,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|         public LSL_Integer llTarget(LSL_Vector position, double range) | ||||
|         { | ||||
|             m_host.AddScriptLPS(1); | ||||
|             return m_host.ParentGroup.registerTargetWaypoint( | ||||
|                 new Vector3((float)position.x, (float)position.y, (float)position.z), (float)range); | ||||
|             return m_host.ParentGroup.registerTargetWaypoint(position, | ||||
|                 (float)range); | ||||
|         } | ||||
| 
 | ||||
|         public void llTargetRemove(int number) | ||||
|  | @ -2242,8 +2223,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|         public LSL_Integer llRotTarget(LSL_Rotation rot, double error) | ||||
|         { | ||||
|             m_host.AddScriptLPS(1); | ||||
|             return m_host.ParentGroup.registerRotTargetWaypoint( | ||||
|                 new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s), (float)error); | ||||
|             return m_host.ParentGroup.registerRotTargetWaypoint(rot, (float)error); | ||||
|         } | ||||
| 
 | ||||
|         public void llRotTargetRemove(int number) | ||||
|  | @ -2255,7 +2235,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|         public void llMoveToTarget(LSL_Vector target, double tau) | ||||
|         { | ||||
|             m_host.AddScriptLPS(1); | ||||
|             m_host.MoveToTarget(new Vector3((float)target.x, (float)target.y, (float)target.z), (float)tau); | ||||
|             m_host.MoveToTarget(target, (float)tau); | ||||
|         } | ||||
| 
 | ||||
|         public void llStopMoveToTarget() | ||||
|  | @ -2268,7 +2248,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|         { | ||||
|             m_host.AddScriptLPS(1); | ||||
|             //No energy force yet | ||||
|             Vector3 v = new Vector3((float)force.x, (float)force.y, (float)force.z); | ||||
|             Vector3 v = force; | ||||
|             if (v.Length() > 20000.0f) | ||||
|             { | ||||
|                 v.Normalize(); | ||||
|  | @ -2280,13 +2260,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|         public void llApplyRotationalImpulse(LSL_Vector force, int local) | ||||
|         { | ||||
|             m_host.AddScriptLPS(1); | ||||
|             m_host.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); | ||||
|             m_host.ApplyAngularImpulse(force, local != 0); | ||||
|         } | ||||
| 
 | ||||
|         public void llSetTorque(LSL_Vector torque, int local) | ||||
|         { | ||||
|             m_host.AddScriptLPS(1); | ||||
|             m_host.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); | ||||
|             m_host.SetAngularImpulse(torque, local != 0); | ||||
|         } | ||||
| 
 | ||||
|         public LSL_Vector llGetTorque() | ||||
|  | @ -2837,13 +2817,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                     return; | ||||
|                 } | ||||
| 
 | ||||
|                 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z); | ||||
|                 Vector3 llvel = new Vector3((float)vel.x, (float)vel.y, (float)vel.z); | ||||
| 
 | ||||
|                 // need the magnitude later | ||||
|                 // float velmag = (float)Util.GetMagnitude(llvel); | ||||
| 
 | ||||
|                 SceneObjectGroup new_group = World.RezObject(m_host, item, llpos, Rot2Quaternion(rot), llvel, param); | ||||
|                 SceneObjectGroup new_group = World.RezObject(m_host, item, pos, rot, vel, param); | ||||
| 
 | ||||
|                 // If either of these are null, then there was an unknown error. | ||||
|                 if (new_group == null) | ||||
|  | @ -2864,10 +2841,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|                 PhysicsActor pa = new_group.RootPart.PhysActor; | ||||
| 
 | ||||
|                 if (pa != null && pa.IsPhysical && llvel != Vector3.Zero) | ||||
|                 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) | ||||
|                 { | ||||
|                     //Recoil. | ||||
|                     llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0); | ||||
|                     llApplyImpulse(vel * groupmass, 0); | ||||
|                 } | ||||
|                 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) | ||||
|             }); | ||||
|  | @ -2912,7 +2889,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             } | ||||
|             else | ||||
|             { | ||||
|                 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); | ||||
|                 m_host.StartLookAt(rot, (float)strength, (float)damping); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -3307,7 +3284,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             } | ||||
|             else | ||||
|             { | ||||
|                 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping); | ||||
|                 m_host.RotLookAt(target, (float)strength, (float)damping); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -3388,7 +3365,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|         protected void TargetOmega(SceneObjectPart part, LSL_Vector axis, double spinrate, double gain) | ||||
|         { | ||||
|             part.UpdateAngularVelocity(new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate))); | ||||
|             part.UpdateAngularVelocity(axis * spinrate); | ||||
|          } | ||||
| 
 | ||||
|         public LSL_Integer llGetStartParameter() | ||||
|  | @ -3424,53 +3401,61 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|             m_host.AddScriptLPS(1); | ||||
| 
 | ||||
|             int implicitPerms = 0; | ||||
| 
 | ||||
|             if (m_host.ParentGroup.IsAttachment && (UUID)agent == m_host.ParentGroup.AttachedAvatar) | ||||
|             { | ||||
|                 // When attached, certain permissions are implicit if requested from owner | ||||
|                 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | | ||||
|                 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | | ||||
|                         ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | | ||||
|                         ScriptBaseClass.PERMISSION_CONTROL_CAMERA | | ||||
|                         ScriptBaseClass.PERMISSION_ATTACH; | ||||
| 
 | ||||
|                 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 bool sitting = false; | ||||
|                 if (m_host.SitTargetAvatar == agentID) | ||||
|                 { | ||||
|                     lock (m_host.TaskInventory) | ||||
|                     sitting = true; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     foreach (SceneObjectPart p in m_host.ParentGroup.Parts) | ||||
|                     { | ||||
|                         m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; | ||||
|                         m_host.TaskInventory[m_item.ItemID].PermsMask = perm; | ||||
|                         if (p.SitTargetAvatar == agentID) | ||||
|                             sitting = true; | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                     m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( | ||||
|                             "run_time_permissions", new Object[] { | ||||
|                             new LSL_Integer(perm) }, | ||||
|                             new DetectParams[0])); | ||||
| 
 | ||||
|                     return; | ||||
|                 if (sitting) | ||||
|                 { | ||||
|                     // When agent is sitting, certain permissions are implicit if requested from sitting agent | ||||
|                     implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | | ||||
|                         ScriptBaseClass.PERMISSION_CONTROL_CAMERA | | ||||
|                         ScriptBaseClass.PERMISSION_TRACK_CAMERA | | ||||
|                         ScriptBaseClass.PERMISSION_TAKE_CONTROLS; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     if (World.GetExtraSetting("auto_grant_attach_perms") == "true") | ||||
|                         implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; | ||||
|                 } | ||||
|             } | ||||
|             else if (m_host.SitTargetAvatar == agentID) // Sitting avatar | ||||
| 
 | ||||
|             if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms | ||||
|             { | ||||
|                 // When agent is sitting, certain permissions are implicit if requested from sitting agent | ||||
|                 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | | ||||
|                     ScriptBaseClass.PERMISSION_CONTROL_CAMERA | | ||||
|                     ScriptBaseClass.PERMISSION_TRACK_CAMERA | | ||||
|                     ScriptBaseClass.PERMISSION_TAKE_CONTROLS; | ||||
| 
 | ||||
|                 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms | ||||
|                 lock (m_host.TaskInventory) | ||||
|                 { | ||||
|                     lock (m_host.TaskInventory) | ||||
|                     { | ||||
|                         m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; | ||||
|                         m_host.TaskInventory[m_item.ItemID].PermsMask = perm; | ||||
|                     } | ||||
| 
 | ||||
|                     m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( | ||||
|                             "run_time_permissions", new Object[] { | ||||
|                             new LSL_Integer(perm) }, | ||||
|                             new DetectParams[0])); | ||||
| 
 | ||||
|                     return; | ||||
|                     m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; | ||||
|                     m_host.TaskInventory[m_item.ItemID].PermsMask = perm; | ||||
|                 } | ||||
| 
 | ||||
|                 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( | ||||
|                         "run_time_permissions", new Object[] { | ||||
|                         new LSL_Integer(perm) }, | ||||
|                         new DetectParams[0])); | ||||
| 
 | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             ScenePresence presence = World.GetScenePresence(agentID); | ||||
|  | @ -3587,7 +3572,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             List<SceneObjectPart> parts = GetLinkParts(linknumber); | ||||
| 
 | ||||
|             foreach (SceneObjectPart part in parts) | ||||
|                 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); | ||||
|                 part.SetFaceColorAlpha(face, color, null); | ||||
|         } | ||||
| 
 | ||||
|         public void llCreateLink(string target, int parent) | ||||
|  | @ -4018,9 +4003,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|         public void llSetText(string text, LSL_Vector color, double alpha) | ||||
|         { | ||||
|             m_host.AddScriptLPS(1); | ||||
|             Vector3 av3 = new Vector3(Util.Clip((float)color.x, 0.0f, 1.0f), | ||||
|                                       Util.Clip((float)color.y, 0.0f, 1.0f), | ||||
|                                       Util.Clip((float)color.z, 0.0f, 1.0f)); | ||||
|             Vector3 av3 = Util.Clip(color, 0.0f, 1.0f); | ||||
|             m_host.SetText(text.Length > 254 ? text.Remove(254) : text, av3, Util.Clip((float)alpha, 0.0f, 1.0f)); | ||||
|             //m_host.ParentGroup.HasGroupChanged = true; | ||||
|             //m_host.ParentGroup.ScheduleGroupForFullUpdate(); | ||||
|  | @ -4217,14 +4200,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             ScriptSleep(5000); | ||||
|         } | ||||
| 
 | ||||
|         public void llTeleportAgent(string agent, string destination, LSL_Vector pos, LSL_Vector lookAt) | ||||
|         public void llTeleportAgent(string agent, string destination, LSL_Vector targetPos, LSL_Vector targetLookAt) | ||||
|         { | ||||
|             m_host.AddScriptLPS(1); | ||||
|             UUID agentId = new UUID(); | ||||
| 
 | ||||
|             Vector3 targetPos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z); | ||||
|             Vector3 targetLookAt = new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z); | ||||
| 
 | ||||
|             if (UUID.TryParse(agent, out agentId)) | ||||
|             { | ||||
|                 ScenePresence presence = World.GetScenePresence(agentId); | ||||
|  | @ -4253,15 +4233,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void llTeleportAgentGlobalCoords(string agent, LSL_Vector global_coords, LSL_Vector pos, LSL_Vector lookAt) | ||||
|         public void llTeleportAgentGlobalCoords(string agent, LSL_Vector global_coords, LSL_Vector targetPos, LSL_Vector targetLookAt) | ||||
|         { | ||||
|             m_host.AddScriptLPS(1); | ||||
|             UUID agentId = new UUID(); | ||||
| 
 | ||||
|             ulong regionHandle = Utils.UIntsToLong((uint)global_coords.x, (uint)global_coords.y); | ||||
| 
 | ||||
|             Vector3 targetPos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z); | ||||
|             Vector3 targetLookAt = new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z); | ||||
|             if (UUID.TryParse(agent, out agentId)) | ||||
|             { | ||||
|                 ScenePresence presence = World.GetScenePresence(agentId); | ||||
|  | @ -4545,7 +4523,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                     distance_attenuation = 1f / normalized_units; | ||||
|                 } | ||||
| 
 | ||||
|                 Vector3 applied_linear_impulse = new Vector3((float)impulse.x, (float)impulse.y, (float)impulse.z); | ||||
|                 Vector3 applied_linear_impulse = impulse; | ||||
|                 { | ||||
|                     float impulse_length = applied_linear_impulse.Length(); | ||||
| 
 | ||||
|  | @ -6044,9 +6022,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|             //Plug the x,y coordinates of the slope normal into the equation of the plane to get | ||||
|             //the height of that point on the plane.  The resulting vector gives the slope. | ||||
|             Vector3 vsl = new Vector3(); | ||||
|             vsl.X = (float)vsn.x; | ||||
|             vsl.Y = (float)vsn.y; | ||||
|             Vector3 vsl = vsn; | ||||
|             vsl.Z = (float)(((vsn.x * vsn.x) + (vsn.y * vsn.y)) / (-1 * vsn.z)); | ||||
|             vsl.Normalize(); | ||||
|             //Normalization might be overkill here | ||||
|  | @ -6057,9 +6033,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|         public LSL_Vector llGroundNormal(LSL_Vector offset) | ||||
|         { | ||||
|             m_host.AddScriptLPS(1); | ||||
|             Vector3 pos = m_host.GetWorldPosition() + new Vector3((float)offset.x, | ||||
|                                                                 (float)offset.y, | ||||
|                                                                 (float)offset.z); | ||||
|             Vector3 pos = m_host.GetWorldPosition() + (Vector3)offset; | ||||
|             // Clamp to valid position | ||||
|             if (pos.X < 0) | ||||
|                 pos.X = 0; | ||||
|  | @ -6512,8 +6486,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|             if (!m_host.ParentGroup.IsDeleted) | ||||
|             { | ||||
|                 m_host.ParentGroup.RootPart.SetVehicleVectorParam(param, | ||||
|                     new Vector3((float)vec.x, (float)vec.y, (float)vec.z)); | ||||
|                 m_host.ParentGroup.RootPart.SetVehicleVectorParam(param, vec); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -6525,7 +6498,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|             if (!m_host.ParentGroup.IsDeleted) | ||||
|             { | ||||
|                 m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, Rot2Quaternion(rot)); | ||||
|                 m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, rot); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -6551,12 +6524,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|         protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) | ||||
|         { | ||||
|             // LSL quaternions can normalize to 0, normal Quaternions can't. | ||||
|             if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0) | ||||
|                 rot.z = 1; // ZERO_ROTATION = 0,0,0,1 | ||||
| 
 | ||||
|             part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z); | ||||
|             part.SitTargetOrientation = Rot2Quaternion(rot); | ||||
|             part.SitTargetPosition = offset; | ||||
|             part.SitTargetOrientation = rot; | ||||
|             part.ParentGroup.HasGroupChanged = true; | ||||
|         } | ||||
| 
 | ||||
|  | @ -6659,13 +6628,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|         public void llSetCameraEyeOffset(LSL_Vector offset) | ||||
|         { | ||||
|             m_host.AddScriptLPS(1); | ||||
|             m_host.SetCameraEyeOffset(new Vector3((float)offset.x, (float)offset.y, (float)offset.z)); | ||||
|             m_host.SetCameraEyeOffset(offset); | ||||
|         } | ||||
| 
 | ||||
|         public void llSetCameraAtOffset(LSL_Vector offset) | ||||
|         { | ||||
|             m_host.AddScriptLPS(1); | ||||
|             m_host.SetCameraAtOffset(new Vector3((float)offset.x, (float)offset.y, (float)offset.z)); | ||||
|             m_host.SetCameraAtOffset(offset); | ||||
|         } | ||||
| 
 | ||||
|         public LSL_String llDumpList2String(LSL_List src, string seperator) | ||||
|  | @ -6687,7 +6656,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|         public LSL_Integer llScriptDanger(LSL_Vector pos) | ||||
|         { | ||||
|             m_host.AddScriptLPS(1); | ||||
|             bool result = World.ScriptDanger(m_host.LocalId, new Vector3((float)pos.x, (float)pos.y, (float)pos.z)); | ||||
|             bool result = World.ScriptDanger(m_host.LocalId, pos); | ||||
|             if (result) | ||||
|             { | ||||
|                 return 1; | ||||
|  | @ -7246,7 +7215,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|         public void llSetPrimitiveParams(LSL_List rules) | ||||
|         { | ||||
|             m_host.AddScriptLPS(1); | ||||
|             SetPrimParams(m_host, rules); | ||||
| 
 | ||||
|             setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules); | ||||
| 
 | ||||
|             ScriptSleep(200); | ||||
|         } | ||||
|  | @ -7271,11 +7241,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|         { | ||||
|             List<SceneObjectPart> parts = GetLinkParts(linknumber); | ||||
| 
 | ||||
|             LSL_List remaining = null; | ||||
| 
 | ||||
|             foreach (SceneObjectPart part in parts) | ||||
|                 SetPrimParams(part, rules); | ||||
|                 remaining = SetPrimParams(part, rules); | ||||
| 
 | ||||
|             while(remaining != null && remaining.Length > 2) | ||||
|             { | ||||
|                 linknumber = remaining.GetLSLIntegerItem(0); | ||||
|                 rules = remaining.GetSublist(1,-1); | ||||
|                 parts = GetLinkParts(linknumber); | ||||
| 
 | ||||
|                 foreach (SceneObjectPart part in parts) | ||||
|                     remaining = SetPrimParams(part, rules); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         protected void SetPrimParams(SceneObjectPart part, LSL_List rules) | ||||
|         protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules) | ||||
|         { | ||||
|             int idx = 0; | ||||
| 
 | ||||
|  | @ -7298,7 +7280,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                         case (int)ScriptBaseClass.PRIM_POSITION: | ||||
|                         case (int)ScriptBaseClass.PRIM_POS_LOCAL: | ||||
|                             if (remain < 1) | ||||
|                                 return; | ||||
|                                 return null; | ||||
| 
 | ||||
|                             v=rules.GetVector3Item(idx++); | ||||
|                             positionChanged = true; | ||||
|  | @ -7307,7 +7289,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                             break; | ||||
|                         case (int)ScriptBaseClass.PRIM_SIZE: | ||||
|                             if (remain < 1) | ||||
|                                 return; | ||||
|                                 return null; | ||||
| 
 | ||||
|                             v=rules.GetVector3Item(idx++); | ||||
|                             SetScale(part, v); | ||||
|  | @ -7315,27 +7297,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                             break; | ||||
|                         case (int)ScriptBaseClass.PRIM_ROTATION: | ||||
|                             if (remain < 1) | ||||
|                                 return; | ||||
|                                 return null; | ||||
| 
 | ||||
|                             LSL_Rotation q = rules.GetQuaternionItem(idx++); | ||||
|                             // try to let this work as in SL... | ||||
|                             if (part.ParentID == 0) | ||||
|                             { | ||||
|                                 // special case: If we are root, rotate complete SOG to new rotation | ||||
|                                 SetRot(part, Rot2Quaternion(q)); | ||||
|                                 SetRot(part, q); | ||||
|                             } | ||||
|                             else | ||||
|                             { | ||||
|                                 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. | ||||
|                                 SceneObjectPart rootPart = part.ParentGroup.RootPart; | ||||
|                                 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q)); | ||||
|                                 SetRot(part, rootPart.RotationOffset * (Quaternion)q); | ||||
|                             } | ||||
| 
 | ||||
|                             break; | ||||
| 
 | ||||
|                         case (int)ScriptBaseClass.PRIM_TYPE: | ||||
|                             if (remain < 3) | ||||
|                                 return; | ||||
|                                 return null; | ||||
| 
 | ||||
|                             code = (int)rules.GetLSLIntegerItem(idx++); | ||||
| 
 | ||||
|  | @ -7354,7 +7336,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                             { | ||||
|                                 case (int)ScriptBaseClass.PRIM_TYPE_BOX: | ||||
|                                     if (remain < 6) | ||||
|                                         return; | ||||
|                                         return null; | ||||
| 
 | ||||
|                                     face = (int)rules.GetLSLIntegerItem(idx++); | ||||
|                                     v = rules.GetVector3Item(idx++); // cut | ||||
|  | @ -7369,7 +7351,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|                                 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER: | ||||
|                                     if (remain < 6) | ||||
|                                         return; | ||||
|                                         return null; | ||||
| 
 | ||||
|                                     face = (int)rules.GetLSLIntegerItem(idx++); // holeshape | ||||
|                                     v = rules.GetVector3Item(idx++); // cut | ||||
|  | @ -7383,7 +7365,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|                                 case (int)ScriptBaseClass.PRIM_TYPE_PRISM: | ||||
|                                     if (remain < 6) | ||||
|                                         return; | ||||
|                                         return null; | ||||
| 
 | ||||
|                                     face = (int)rules.GetLSLIntegerItem(idx++); // holeshape | ||||
|                                     v = rules.GetVector3Item(idx++); //cut | ||||
|  | @ -7397,7 +7379,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|                                 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE: | ||||
|                                     if (remain < 5) | ||||
|                                         return; | ||||
|                                         return null; | ||||
| 
 | ||||
|                                     face = (int)rules.GetLSLIntegerItem(idx++); // holeshape | ||||
|                                     v = rules.GetVector3Item(idx++); // cut | ||||
|  | @ -7410,7 +7392,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|                                 case (int)ScriptBaseClass.PRIM_TYPE_TORUS: | ||||
|                                     if (remain < 11) | ||||
|                                         return; | ||||
|                                         return null; | ||||
| 
 | ||||
|                                     face = (int)rules.GetLSLIntegerItem(idx++); // holeshape | ||||
|                                     v = rules.GetVector3Item(idx++); //cut | ||||
|  | @ -7429,7 +7411,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|                                 case (int)ScriptBaseClass.PRIM_TYPE_TUBE: | ||||
|                                     if (remain < 11) | ||||
|                                         return; | ||||
|                                         return null; | ||||
| 
 | ||||
|                                     face = (int)rules.GetLSLIntegerItem(idx++); // holeshape | ||||
|                                     v = rules.GetVector3Item(idx++); //cut | ||||
|  | @ -7448,7 +7430,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|                                 case (int)ScriptBaseClass.PRIM_TYPE_RING: | ||||
|                                     if (remain < 11) | ||||
|                                         return; | ||||
|                                         return null; | ||||
| 
 | ||||
|                                     face = (int)rules.GetLSLIntegerItem(idx++); // holeshape | ||||
|                                     v = rules.GetVector3Item(idx++); //cut | ||||
|  | @ -7467,7 +7449,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|                                 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT: | ||||
|                                     if (remain < 2) | ||||
|                                         return; | ||||
|                                         return null; | ||||
| 
 | ||||
|                                     string map = rules.Data[idx++].ToString(); | ||||
|                                     face = (int)rules.GetLSLIntegerItem(idx++); // type | ||||
|  | @ -7479,7 +7461,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|                         case (int)ScriptBaseClass.PRIM_TEXTURE: | ||||
|                             if (remain < 5) | ||||
|                                 return; | ||||
|                                 return null; | ||||
| 
 | ||||
|                             face=(int)rules.GetLSLIntegerItem(idx++); | ||||
|                             string tex=rules.Data[idx++].ToString(); | ||||
|  | @ -7496,20 +7478,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|                         case (int)ScriptBaseClass.PRIM_COLOR: | ||||
|                             if (remain < 3) | ||||
|                                 return; | ||||
|                                 return null; | ||||
| 
 | ||||
|                             face=(int)rules.GetLSLIntegerItem(idx++); | ||||
|                             LSL_Vector color=rules.GetVector3Item(idx++); | ||||
|                             double alpha=(double)rules.GetLSLFloatItem(idx++); | ||||
| 
 | ||||
|                             part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); | ||||
|                             SetAlpha(part, alpha, face); | ||||
|                             part.SetFaceColorAlpha(face, color, alpha); | ||||
| 
 | ||||
|                             break; | ||||
| 
 | ||||
|                         case (int)ScriptBaseClass.PRIM_FLEXIBLE: | ||||
|                             if (remain < 7) | ||||
|                                 return; | ||||
|                                 return null; | ||||
| 
 | ||||
|                             bool flexi = rules.GetLSLIntegerItem(idx++); | ||||
|                             int softness = rules.GetLSLIntegerItem(idx++); | ||||
|  | @ -7525,7 +7506,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|                         case (int)ScriptBaseClass.PRIM_POINT_LIGHT: | ||||
|                             if (remain < 5) | ||||
|                                 return; | ||||
|                                 return null; | ||||
|                             bool light = rules.GetLSLIntegerItem(idx++); | ||||
|                             LSL_Vector lightcolor = rules.GetVector3Item(idx++); | ||||
|                             float intensity = (float)rules.GetLSLFloatItem(idx++); | ||||
|  | @ -7538,7 +7519,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|                         case (int)ScriptBaseClass.PRIM_GLOW: | ||||
|                             if (remain < 2) | ||||
|                                 return; | ||||
|                                 return null; | ||||
|                             face = rules.GetLSLIntegerItem(idx++); | ||||
|                             float glow = (float)rules.GetLSLFloatItem(idx++); | ||||
| 
 | ||||
|  | @ -7548,7 +7529,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|                         case (int)ScriptBaseClass.PRIM_BUMP_SHINY: | ||||
|                             if (remain < 3) | ||||
|                                 return; | ||||
|                                 return null; | ||||
|                             face = (int)rules.GetLSLIntegerItem(idx++); | ||||
|                             int shiny = (int)rules.GetLSLIntegerItem(idx++); | ||||
|                             Bumpiness bump = (Bumpiness)(int)rules.GetLSLIntegerItem(idx++); | ||||
|  | @ -7559,7 +7540,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|                          case (int)ScriptBaseClass.PRIM_FULLBRIGHT: | ||||
|                              if (remain < 2) | ||||
|                                  return; | ||||
|                                  return null; | ||||
|                              face = rules.GetLSLIntegerItem(idx++); | ||||
|                              bool st = rules.GetLSLIntegerItem(idx++); | ||||
|                              SetFullBright(part, face , st); | ||||
|  | @ -7567,17 +7548,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|                          case (int)ScriptBaseClass.PRIM_MATERIAL: | ||||
|                              if (remain < 1) | ||||
|                                  return; | ||||
|                                  return null; | ||||
|                              int mat = rules.GetLSLIntegerItem(idx++); | ||||
|                              if (mat < 0 || mat > 7) | ||||
|                                  return; | ||||
|                                  return null; | ||||
| 
 | ||||
|                              part.Material = Convert.ToByte(mat); | ||||
|                              break; | ||||
| 
 | ||||
|                          case (int)ScriptBaseClass.PRIM_PHANTOM: | ||||
|                              if (remain < 1) | ||||
|                                  return; | ||||
|                                  return null; | ||||
| 
 | ||||
|                              string ph = rules.Data[idx++].ToString(); | ||||
|                              m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); | ||||
|  | @ -7586,7 +7567,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|                          case (int)ScriptBaseClass.PRIM_PHYSICS: | ||||
|                             if (remain < 1) | ||||
|                                  return; | ||||
|                                  return null; | ||||
|                              string phy = rules.Data[idx++].ToString(); | ||||
|                              bool physics; | ||||
| 
 | ||||
|  | @ -7600,7 +7581,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|                         case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: | ||||
|                             if (remain < 1) | ||||
|                                 return; | ||||
|                                 return null; | ||||
|                             string temp = rules.Data[idx++].ToString(); | ||||
| 
 | ||||
|                             m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); | ||||
|  | @ -7609,7 +7590,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|                         case (int)ScriptBaseClass.PRIM_TEXGEN: | ||||
|                             if (remain < 2) | ||||
|                                 return; | ||||
|                                 return null; | ||||
|                                 //face,type | ||||
|                             face = rules.GetLSLIntegerItem(idx++); | ||||
|                             int style = rules.GetLSLIntegerItem(idx++); | ||||
|  | @ -7617,53 +7598,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                             break; | ||||
|                         case (int)ScriptBaseClass.PRIM_TEXT: | ||||
|                             if (remain < 3) | ||||
|                                 return; | ||||
|                                 return null; | ||||
|                             string primText = rules.GetLSLStringItem(idx++); | ||||
|                             LSL_Vector primTextColor = rules.GetVector3Item(idx++); | ||||
|                             LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++); | ||||
|                             Vector3 av3 = new Vector3(Util.Clip((float)primTextColor.x, 0.0f, 1.0f), | ||||
|                                           Util.Clip((float)primTextColor.y, 0.0f, 1.0f), | ||||
|                                           Util.Clip((float)primTextColor.z, 0.0f, 1.0f)); | ||||
|                             Vector3 av3 = Util.Clip(primTextColor, 0.0f, 1.0f); | ||||
|                             part.SetText(primText, av3, Util.Clip((float)primTextAlpha, 0.0f, 1.0f)); | ||||
| 
 | ||||
|                             break; | ||||
|                         case (int)ScriptBaseClass.PRIM_NAME: | ||||
|                             if (remain < 1) | ||||
|                                 return; | ||||
|                                 return null; | ||||
|                             string primName = rules.GetLSLStringItem(idx++); | ||||
|                             part.Name = primName; | ||||
|                             break; | ||||
|                         case (int)ScriptBaseClass.PRIM_DESC: | ||||
|                             if (remain < 1) | ||||
|                                 return; | ||||
|                                 return null; | ||||
|                             string primDesc = rules.GetLSLStringItem(idx++); | ||||
|                             part.Description = primDesc; | ||||
|                             break; | ||||
|                         case (int)ScriptBaseClass.PRIM_ROT_LOCAL: | ||||
|                             if (remain < 1) | ||||
|                                 return; | ||||
|                             LSL_Rotation lr = rules.GetQuaternionItem(idx++); | ||||
|                             SetRot(part, Rot2Quaternion(lr)); | ||||
|                                 return null; | ||||
|                             SetRot(part, rules.GetQuaternionItem(idx++)); | ||||
|                             break; | ||||
|                         case (int)ScriptBaseClass.PRIM_OMEGA: | ||||
|                             if (remain < 3) | ||||
|                                 return; | ||||
|                                 return null; | ||||
|                             LSL_Vector axis = rules.GetVector3Item(idx++); | ||||
|                             LSL_Float spinrate = rules.GetLSLFloatItem(idx++); | ||||
|                             LSL_Float gain = rules.GetLSLFloatItem(idx++); | ||||
|                             TargetOmega(part, axis, (double)spinrate, (double)gain); | ||||
|                             break; | ||||
|                         case (int)ScriptBaseClass.PRIM_SLICE: | ||||
|                             if (remain < 1) | ||||
|                                 return null; | ||||
|                             LSL_Vector slice = rules.GetVector3Item(idx++); | ||||
|                             part.UpdateSlice((float)slice.x, (float)slice.y); | ||||
|                             break; | ||||
|                         case (int)ScriptBaseClass.PRIM_LINK_TARGET: | ||||
|                             if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. | ||||
|                                 return; | ||||
|                             LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++); | ||||
|                             LSL_List new_rules = rules.GetSublist(idx, -1); | ||||
|                             setLinkPrimParams((int)new_linknumber, new_rules); | ||||
|                                 return null; | ||||
| 
 | ||||
|                             return; | ||||
|                             return rules.GetSublist(idx, -1); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             catch (InvalidCastException e) | ||||
|             { | ||||
|                 ShoutError(e.Message); | ||||
|             } | ||||
|             finally | ||||
|             { | ||||
|                 if (positionChanged) | ||||
|  | @ -7671,17 +7656,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                     if (part.ParentGroup.RootPart == part) | ||||
|                     { | ||||
|                         SceneObjectGroup parent = part.ParentGroup; | ||||
|                         parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); | ||||
|                         parent.UpdateGroupPosition(currentPosition); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z); | ||||
|                         part.OffsetPosition = currentPosition; | ||||
|                         SceneObjectGroup parent = part.ParentGroup; | ||||
|                         parent.HasGroupChanged = true; | ||||
|                         parent.ScheduleGroupForTerseUpdate(); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         public LSL_String llStringToBase64(string str) | ||||
|  | @ -7911,8 +7897,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             if (part != null) | ||||
|             { | ||||
|                 Vector3 halfSize = part.Scale / 2.0f; | ||||
|                 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); | ||||
|                 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); | ||||
|                 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; | ||||
|                 LSL_Vector upper = new LSL_Vector(halfSize); | ||||
|                 result.Add(lower); | ||||
|                 result.Add(upper); | ||||
|                 return result; | ||||
|  | @ -8325,6 +8311,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                     case (int)ScriptBaseClass.PRIM_POS_LOCAL: | ||||
|                         res.Add(new LSL_Vector(GetPartLocalPos(part))); | ||||
|                         break; | ||||
|                     case (int)ScriptBaseClass.PRIM_SLICE: | ||||
|                         PrimType prim_type = part.GetPrimType(); | ||||
|                         bool useProfileBeginEnd = (prim_type == PrimType.SPHERE || prim_type == PrimType.TORUS || prim_type == PrimType.TUBE || prim_type == PrimType.RING); | ||||
|                         res.Add(new LSL_Vector( | ||||
|                             (useProfileBeginEnd ? part.Shape.ProfileBegin : part.Shape.PathBegin) / 50000.0, | ||||
|                             1 - (useProfileBeginEnd ? part.Shape.ProfileEnd : part.Shape.PathEnd) / 50000.0, | ||||
|                             0 | ||||
|                         )); | ||||
|                         break; | ||||
|                 } | ||||
|             } | ||||
|             return res; | ||||
|  | @ -9913,9 +9908,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             ScenePresence avatar = World.GetScenePresence(detectedParams.Key); | ||||
|             if (avatar != null) | ||||
|             { | ||||
|                 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, simname, | ||||
|                                                                    new Vector3((float)pos.x, (float)pos.y, (float)pos.z), | ||||
|                                                                    new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); | ||||
|                 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, | ||||
|                     simname, pos, lookAt); | ||||
|             } | ||||
|             ScriptSleep(1000); | ||||
|         } | ||||
|  | @ -10522,12 +10516,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                                     else | ||||
|                                         rot = obj.GetWorldRotation(); | ||||
| 
 | ||||
|                                     LSL_Rotation objrot = new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W); | ||||
|                                     LSL_Rotation objrot = new LSL_Rotation(rot); | ||||
|                                     ret.Add(objrot); | ||||
|                                 } | ||||
|                                 break; | ||||
|                             case ScriptBaseClass.OBJECT_VELOCITY: | ||||
|                                 ret.Add(new LSL_Vector(obj.Velocity.X, obj.Velocity.Y, obj.Velocity.Z)); | ||||
|                                 ret.Add(new LSL_Vector(obj.Velocity)); | ||||
|                                 break; | ||||
|                             case ScriptBaseClass.OBJECT_OWNER: | ||||
|                                 ret.Add(new LSL_String(obj.OwnerID.ToString())); | ||||
|  | @ -10754,7 +10748,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             if (obj.OwnerID != m_host.OwnerID) | ||||
|                 return; | ||||
| 
 | ||||
|             SetPrimParams(obj, rules); | ||||
|             LSL_List remaining = SetPrimParams(obj, rules); | ||||
| 
 | ||||
|             while ((object)remaining != null && remaining.Length > 2) | ||||
|             { | ||||
|                 LSL_Integer newLink = remaining.GetLSLIntegerItem(0); | ||||
|                 LSL_List newrules = remaining.GetSublist(1, -1); | ||||
|                 foreach(SceneObjectPart part in GetLinkParts(obj, newLink)){ | ||||
|                     remaining = SetPrimParams(part, newrules); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules) | ||||
|  | @ -11104,8 +11107,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|             m_host.AddScriptLPS(1); | ||||
| 
 | ||||
|             Vector3 rayStart = new Vector3((float)start.x, (float)start.y, (float)start.z); | ||||
|             Vector3 rayEnd = new Vector3((float)end.x, (float)end.y, (float)end.z); | ||||
|             Vector3 rayStart = start; | ||||
|             Vector3 rayEnd = end; | ||||
|             Vector3 dir = rayEnd - rayStart; | ||||
| 
 | ||||
|             float dist = Vector3.Mag(dir); | ||||
|  |  | |||
|  | @ -304,7 +304,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                     case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: | ||||
|                         idx++; | ||||
|                         iV = rules.GetVector3Item(idx); | ||||
|                         wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); | ||||
|                         wl.cloudDetailXYDensity = iV; | ||||
|                         break; | ||||
|                     case (int)ScriptBaseClass.WL_CLOUD_SCALE: | ||||
|                         idx++; | ||||
|  | @ -329,7 +329,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                     case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: | ||||
|                         idx++; | ||||
|                         iV = rules.GetVector3Item(idx); | ||||
|                         wl.cloudXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); | ||||
|                         wl.cloudXYDensity = iV; | ||||
|                         break; | ||||
|                     case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: | ||||
|                         idx++; | ||||
|  | @ -384,7 +384,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                     case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: | ||||
|                         idx++; | ||||
|                         iV = rules.GetVector3Item(idx); | ||||
|                         wl.reflectionWaveletScale = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); | ||||
|                         wl.reflectionWaveletScale = iV; | ||||
|                         break; | ||||
|                     case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: | ||||
|                         idx++; | ||||
|  | @ -422,7 +422,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                     case (int)ScriptBaseClass.WL_WATER_COLOR: | ||||
|                         idx++; | ||||
|                         iV = rules.GetVector3Item(idx); | ||||
|                         wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); | ||||
|                         wl.waterColor = iV; | ||||
|                         break; | ||||
|                     case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: | ||||
|                         idx++; | ||||
|  |  | |||
|  | @ -333,8 +333,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             { | ||||
|                 if (type == typeof(OpenMetaverse.Quaternion)) | ||||
|                 { | ||||
|                     LSL_Rotation rot = (LSL_Rotation)lslparm; | ||||
|                     return new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s); | ||||
|                     return (OpenMetaverse.Quaternion)((LSL_Rotation)lslparm); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|  | @ -343,8 +342,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             { | ||||
|                 if (type == typeof(OpenMetaverse.Vector3)) | ||||
|                 { | ||||
|                     LSL_Vector vect = (LSL_Vector)lslparm; | ||||
|                     return new OpenMetaverse.Vector3((float)vect.x,(float)vect.y,(float)vect.z); | ||||
|                     return (OpenMetaverse.Vector3)((LSL_Vector)lslparm); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|  | @ -367,13 +365,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                             result[i] = new UUID((LSL_Key)plist[i]); | ||||
|                         else if (plist[i] is LSL_Rotation) | ||||
|                         { | ||||
|                             LSL_Rotation rot = (LSL_Rotation)plist[i]; | ||||
|                             result[i] = new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s); | ||||
|                             result[i] = (OpenMetaverse.Quaternion)( | ||||
|                                 (LSL_Rotation)plist[i]); | ||||
|                         } | ||||
|                         else if (plist[i] is LSL_Vector) | ||||
|                         { | ||||
|                             LSL_Vector vect = (LSL_Vector)plist[i]; | ||||
|                             result[i] = new OpenMetaverse.Vector3((float)vect.x,(float)vect.y,(float)vect.z); | ||||
|                             result[i] = (OpenMetaverse.Vector3)( | ||||
|                                 (LSL_Vector)plist[i]); | ||||
|                         } | ||||
|                         else | ||||
|                             MODError("unknown LSL list element type"); | ||||
|  |  | |||
|  | @ -773,10 +773,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|                         // We will launch the teleport on a new thread so that when the script threads are terminated | ||||
|                         // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.                         | ||||
|                         Util.FireAndForget( | ||||
|                             o => World.RequestTeleportLocation(presence.ControllingClient, regionName, | ||||
|                                 new Vector3((float)position.x, (float)position.y, (float)position.z), | ||||
|                                 new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation)); | ||||
|                         Util.FireAndForget(o => World.RequestTeleportLocation( | ||||
|                             presence.ControllingClient, regionName, position, | ||||
|                             lookat, (uint)TPFlags.ViaLocation)); | ||||
| 
 | ||||
|                         ScriptSleep(5000); | ||||
| 
 | ||||
|  | @ -819,10 +818,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|                         // We will launch the teleport on a new thread so that when the script threads are terminated | ||||
|                         // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting. | ||||
|                         Util.FireAndForget( | ||||
|                             o => World.RequestTeleportLocation(presence.ControllingClient, regionHandle, | ||||
|                                 new Vector3((float)position.x, (float)position.y, (float)position.z), | ||||
|                                 new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation)); | ||||
|                         Util.FireAndForget(o => World.RequestTeleportLocation( | ||||
|                             presence.ControllingClient, regionHandle,  | ||||
|                             position, lookat, (uint)TPFlags.ViaLocation)); | ||||
| 
 | ||||
|                         ScriptSleep(5000); | ||||
| 
 | ||||
|  | @ -2329,7 +2327,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                     ownerID = m_host.OwnerID; | ||||
|                 UUID x = module.CreateNPC(firstname, | ||||
|                                           lastname, | ||||
|                                           new Vector3((float) position.x, (float) position.y, (float) position.z), | ||||
|                                           position, | ||||
|                                           ownerID, | ||||
|                                           senseAsAgent, | ||||
|                                           World, | ||||
|  | @ -2446,7 +2444,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             return new LSL_Vector(0, 0, 0); | ||||
|         } | ||||
| 
 | ||||
|         public void osNpcMoveTo(LSL_Key npc, LSL_Vector position) | ||||
|         public void osNpcMoveTo(LSL_Key npc, LSL_Vector pos) | ||||
|         { | ||||
|             CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo"); | ||||
|             m_host.AddScriptLPS(1); | ||||
|  | @ -2461,7 +2459,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                 if (!module.CheckPermissions(npcId, m_host.OwnerID)) | ||||
|                     return; | ||||
|                  | ||||
|                 Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z); | ||||
|                 module.MoveToTarget(npcId, World, pos, false, true, false); | ||||
|             } | ||||
|         } | ||||
|  | @ -2481,11 +2478,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                 if (!module.CheckPermissions(npcId, m_host.OwnerID)) | ||||
|                     return; | ||||
| 
 | ||||
|                 Vector3 pos = new Vector3((float)target.x, (float)target.y, (float)target.z); | ||||
|                 module.MoveToTarget( | ||||
|                     new UUID(npc.m_string), | ||||
|                     World, | ||||
|                     pos, | ||||
|                     target, | ||||
|                     (options & ScriptBaseClass.OS_NPC_NO_FLY) != 0, | ||||
|                     (options & ScriptBaseClass.OS_NPC_LAND_AT_TARGET) != 0, | ||||
|                     (options & ScriptBaseClass.OS_NPC_RUNNING) != 0); | ||||
|  | @ -2537,7 +2533,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                 ScenePresence sp = World.GetScenePresence(npcId); | ||||
| 
 | ||||
|                 if (sp != null) | ||||
|                     sp.Rotation = LSL_Api.Rot2Quaternion(rotation); | ||||
|                     sp.Rotation = rotation; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -2881,7 +2877,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                 avatar.SpeedModifier = (float)SpeedModifier; | ||||
|         } | ||||
|          | ||||
|         public void osKickAvatar(string FirstName,string SurName,string alert) | ||||
|         public void osKickAvatar(string FirstName, string SurName, string alert) | ||||
|         { | ||||
|             CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar"); | ||||
|             m_host.AddScriptLPS(1); | ||||
|  | @ -2895,7 +2891,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                         sp.ControllingClient.Kick(alert); | ||||
| 
 | ||||
|                     // ...and close on our side | ||||
|                     sp.Scene.IncomingCloseAgent(sp.UUID); | ||||
|                     sp.Scene.IncomingCloseAgent(sp.UUID, false); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  |  | |||
|  | @ -351,7 +351,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
|                 q = avatar.Rotation * q; | ||||
|             } | ||||
| 
 | ||||
|             LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); | ||||
|             LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); | ||||
|             LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); | ||||
|             double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); | ||||
| 
 | ||||
|  | @ -428,9 +428,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
|                             try | ||||
|                             { | ||||
|                                 Vector3 diff = toRegionPos - fromRegionPos; | ||||
|                                 LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(diff.X, diff.Y, diff.Z); | ||||
|                                 double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir); | ||||
|                                 double mag_obj = LSL_Types.Vector3.Mag(obj_dir); | ||||
|                                 double dot = LSL_Types.Vector3.Dot(forward_dir, diff); | ||||
|                                 double mag_obj = LSL_Types.Vector3.Mag(diff); | ||||
|                                 ang_obj = Math.Acos(dot / (mag_fwd * mag_obj)); | ||||
|                             } | ||||
|                             catch | ||||
|  | @ -479,7 +478,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
|                 q = avatar.Rotation * q; | ||||
|             } | ||||
| 
 | ||||
|             LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); | ||||
|             LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); | ||||
|             LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); | ||||
|             double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); | ||||
|             bool attached = (SensePoint.ParentGroup.AttachmentPoint != 0); | ||||
|  | @ -560,8 +559,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
|                         double ang_obj = 0; | ||||
|                         try | ||||
|                         { | ||||
|                             Vector3 diff = toRegionPos - fromRegionPos; | ||||
|                             LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(diff.X, diff.Y, diff.Z); | ||||
|                             LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3( | ||||
|                                 toRegionPos - fromRegionPos); | ||||
|                             double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir); | ||||
|                             double mag_obj = LSL_Types.Vector3.Mag(obj_dir); | ||||
|                             ang_obj = Math.Acos(dot / (mag_fwd * mag_obj)); | ||||
|  |  | |||
|  | @ -226,6 +226,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
|         public const int ATTACH_BELLY = 28; | ||||
|         public const int ATTACH_RPEC = 29; | ||||
|         public const int ATTACH_LPEC = 30; | ||||
|         public const int ATTACH_LEFT_PEC = 29; // Same value as ATTACH_RPEC, see https://jira.secondlife.com/browse/SVC-580 | ||||
|         public const int ATTACH_RIGHT_PEC = 30; // Same value as ATTACH_LPEC, see https://jira.secondlife.com/browse/SVC-580 | ||||
|         public const int ATTACH_HUD_CENTER_2 = 31; | ||||
|         public const int ATTACH_HUD_TOP_RIGHT = 32; | ||||
|         public const int ATTACH_HUD_TOP_CENTER = 33; | ||||
|  | @ -326,6 +328,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
|         public const int PRIM_OMEGA = 32; | ||||
|         public const int PRIM_POS_LOCAL = 33; | ||||
|         public const int PRIM_LINK_TARGET = 34; | ||||
|         public const int PRIM_SLICE = 35; | ||||
|         public const int PRIM_TEXGEN_DEFAULT = 0; | ||||
|         public const int PRIM_TEXGEN_PLANAR = 1; | ||||
| 
 | ||||
|  |  | |||
|  | @ -546,6 +546,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
|                     "OpenSim.Region.ScriptEngine.Shared.dll")); | ||||
|             parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, | ||||
|                     "OpenSim.Region.ScriptEngine.Shared.Api.Runtime.dll")); | ||||
|             parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, | ||||
|                     "OpenMetaverseTypes.dll")); | ||||
| 
 | ||||
|             if (lang == enumCompileType.yp) | ||||
|             { | ||||
|  |  | |||
|  | @ -160,11 +160,11 @@ namespace OpenSim.Region.ScriptEngine.Shared | |||
|                 else | ||||
|                 { | ||||
|                     // Set the values from the touch data provided by the client | ||||
|                     touchST = new LSL_Types.Vector3(value.STCoord.X, value.STCoord.Y, value.STCoord.Z); | ||||
|                     touchUV = new LSL_Types.Vector3(value.UVCoord.X, value.UVCoord.Y, value.UVCoord.Z); | ||||
|                     touchNormal = new LSL_Types.Vector3(value.Normal.X, value.Normal.Y, value.Normal.Z); | ||||
|                     touchBinormal = new LSL_Types.Vector3(value.Binormal.X, value.Binormal.Y, value.Binormal.Z); | ||||
|                     touchPos = new LSL_Types.Vector3(value.Position.X, value.Position.Y, value.Position.Z); | ||||
|                     touchST = new LSL_Types.Vector3(value.STCoord); | ||||
|                     touchUV = new LSL_Types.Vector3(value.UVCoord); | ||||
|                     touchNormal = new LSL_Types.Vector3(value.Normal); | ||||
|                     touchBinormal = new LSL_Types.Vector3(value.Binormal); | ||||
|                     touchPos = new LSL_Types.Vector3(value.Position); | ||||
|                     touchFace = value.FaceIndex; | ||||
|                 } | ||||
|             } | ||||
|  | @ -181,19 +181,13 @@ namespace OpenSim.Region.ScriptEngine.Shared | |||
| 
 | ||||
|                 Name = presence.Firstname + " " + presence.Lastname; | ||||
|                 Owner = Key; | ||||
|                 Position = new LSL_Types.Vector3( | ||||
|                         presence.AbsolutePosition.X, | ||||
|                         presence.AbsolutePosition.Y, | ||||
|                         presence.AbsolutePosition.Z); | ||||
|                 Position = new LSL_Types.Vector3(presence.AbsolutePosition); | ||||
|                 Rotation = new LSL_Types.Quaternion( | ||||
|                         presence.Rotation.X, | ||||
|                         presence.Rotation.Y, | ||||
|                         presence.Rotation.Z, | ||||
|                         presence.Rotation.W); | ||||
|                 Velocity = new LSL_Types.Vector3( | ||||
|                         presence.Velocity.X, | ||||
|                         presence.Velocity.Y, | ||||
|                         presence.Velocity.Z); | ||||
|                 Velocity = new LSL_Types.Vector3(presence.Velocity); | ||||
| 
 | ||||
|                 if (presence.PresenceType != PresenceType.Npc) | ||||
|                 { | ||||
|  | @ -241,16 +235,12 @@ namespace OpenSim.Region.ScriptEngine.Shared | |||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             Position = new LSL_Types.Vector3(part.AbsolutePosition.X, | ||||
|                                              part.AbsolutePosition.Y, | ||||
|                                              part.AbsolutePosition.Z); | ||||
|             Position = new LSL_Types.Vector3(part.AbsolutePosition); | ||||
| 
 | ||||
|             Quaternion wr = part.ParentGroup.GroupRotation; | ||||
|             Rotation = new LSL_Types.Quaternion(wr.X, wr.Y, wr.Z, wr.W); | ||||
| 
 | ||||
|             Velocity = new LSL_Types.Vector3(part.Velocity.X, | ||||
|                                              part.Velocity.Y, | ||||
|                                              part.Velocity.Z); | ||||
|             Velocity = new LSL_Types.Vector3(part.Velocity); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -31,6 +31,11 @@ using System.Globalization; | |||
| using System.Text.RegularExpressions; | ||||
| using OpenSim.Framework; | ||||
| 
 | ||||
| using OpenMetaverse; | ||||
| using OMV_Vector3 = OpenMetaverse.Vector3; | ||||
| using OMV_Vector3d = OpenMetaverse.Vector3d; | ||||
| using OMV_Quaternion = OpenMetaverse.Quaternion; | ||||
| 
 | ||||
| namespace OpenSim.Region.ScriptEngine.Shared | ||||
| { | ||||
|     [Serializable] | ||||
|  | @ -54,6 +59,20 @@ namespace OpenSim.Region.ScriptEngine.Shared | |||
|                 z = (float)vector.z; | ||||
|             } | ||||
| 
 | ||||
|             public Vector3(OMV_Vector3 vector) | ||||
|             { | ||||
|                 x = vector.X; | ||||
|                 y = vector.Y; | ||||
|                 z = vector.Z; | ||||
|             } | ||||
| 
 | ||||
|             public Vector3(OMV_Vector3d vector) | ||||
|             { | ||||
|                 x = vector.X; | ||||
|                 y = vector.Y; | ||||
|                 z = vector.Z; | ||||
|             } | ||||
| 
 | ||||
|             public Vector3(double X, double Y, double Z) | ||||
|             { | ||||
|                 x = X; | ||||
|  | @ -109,6 +128,26 @@ namespace OpenSim.Region.ScriptEngine.Shared | |||
|                 return new list(new object[] { vec }); | ||||
|             } | ||||
| 
 | ||||
|             public static implicit operator OMV_Vector3(Vector3 vec) | ||||
|             { | ||||
|                 return new OMV_Vector3((float)vec.x, (float)vec.y, (float)vec.z); | ||||
|             } | ||||
| 
 | ||||
|             public static implicit operator Vector3(OMV_Vector3 vec) | ||||
|             { | ||||
|                 return new Vector3(vec); | ||||
|             } | ||||
| 
 | ||||
|             public static implicit operator OMV_Vector3d(Vector3 vec) | ||||
|             { | ||||
|                 return new OMV_Vector3d(vec.x, vec.y, vec.z); | ||||
|             } | ||||
| 
 | ||||
|             public static implicit operator Vector3(OMV_Vector3d vec) | ||||
|             { | ||||
|                 return new Vector3(vec); | ||||
|             } | ||||
| 
 | ||||
|             public static bool operator ==(Vector3 lhs, Vector3 rhs) | ||||
|             { | ||||
|                 return (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z); | ||||
|  | @ -322,6 +361,14 @@ namespace OpenSim.Region.ScriptEngine.Shared | |||
|                     s = 1; | ||||
|             } | ||||
| 
 | ||||
|             public Quaternion(OMV_Quaternion rot) | ||||
|             { | ||||
|                 x = rot.X; | ||||
|                 y = rot.Y; | ||||
|                 z = rot.Z; | ||||
|                 s = rot.W; | ||||
|             } | ||||
| 
 | ||||
|             #endregion | ||||
| 
 | ||||
|             #region Overriders | ||||
|  | @ -368,6 +415,21 @@ namespace OpenSim.Region.ScriptEngine.Shared | |||
|                 return new list(new object[] { r }); | ||||
|             } | ||||
| 
 | ||||
|             public static implicit operator OMV_Quaternion(Quaternion rot) | ||||
|             { | ||||
|                 // LSL quaternions can normalize to 0, normal Quaternions can't. | ||||
|                 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0) | ||||
|                     rot.z = 1; // ZERO_ROTATION = 0,0,0,1 | ||||
|                 OMV_Quaternion omvrot = new OMV_Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); | ||||
|                 omvrot.Normalize(); | ||||
|                 return omvrot; | ||||
|             } | ||||
| 
 | ||||
|             public static implicit operator Quaternion(OMV_Quaternion rot) | ||||
|             { | ||||
|                 return new Quaternion(rot); | ||||
|             } | ||||
| 
 | ||||
|             public static bool operator ==(Quaternion lhs, Quaternion rhs) | ||||
|             { | ||||
|                 // Return true if the fields match: | ||||
|  | @ -560,12 +622,23 @@ namespace OpenSim.Region.ScriptEngine.Shared | |||
|                 else if (m_data[itemIndex] is LSL_Types.LSLString) | ||||
|                     return new LSLInteger(m_data[itemIndex].ToString()); | ||||
|                 else | ||||
|                     throw new InvalidCastException(); | ||||
|                     throw new InvalidCastException(string.Format( | ||||
|                         "{0} expected but {1} given", | ||||
|                         typeof(LSL_Types.LSLInteger).Name, | ||||
|                         m_data[itemIndex] != null ? | ||||
|                         m_data[itemIndex].GetType().Name : "null")); | ||||
|             } | ||||
| 
 | ||||
|             public LSL_Types.Vector3 GetVector3Item(int itemIndex) | ||||
|             { | ||||
|               return (LSL_Types.Vector3)m_data[itemIndex]; | ||||
|                 if(m_data[itemIndex] is LSL_Types.Vector3) | ||||
|                     return (LSL_Types.Vector3)m_data[itemIndex]; | ||||
|                 else | ||||
|                     throw new InvalidCastException(string.Format( | ||||
|                         "{0} expected but {1} given", | ||||
|                         typeof(LSL_Types.Vector3).Name, | ||||
|                         m_data[itemIndex] != null ? | ||||
|                         m_data[itemIndex].GetType().Name : "null")); | ||||
|             } | ||||
| 
 | ||||
|             public LSL_Types.Quaternion GetQuaternionItem(int itemIndex) | ||||
|  |  | |||
|  | @ -152,9 +152,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
|             det[0] = new DetectParams(); | ||||
|             det[0].Key = remoteClient.AgentId; | ||||
|             det[0].Populate(myScriptEngine.World); | ||||
|             det[0].OffsetPos = new LSL_Types.Vector3(offsetPos.X, | ||||
|                                                      offsetPos.Y, | ||||
|                                                      offsetPos.Z); | ||||
|             det[0].OffsetPos = offsetPos; | ||||
| 
 | ||||
|             if (originalID == 0) | ||||
|             { | ||||
|  | @ -298,9 +296,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
|             foreach (DetectedObject detobj in col.Colliders) | ||||
|             { | ||||
|                 DetectParams d = new DetectParams(); | ||||
|                 d.Position = new LSL_Types.Vector3(detobj.posVector.X, | ||||
|                     detobj.posVector.Y, | ||||
|                     detobj.posVector.Z); | ||||
|                 d.Position = detobj.posVector; | ||||
|                 d.Populate(myScriptEngine.World); | ||||
|                 det.Add(d); | ||||
|                 myScriptEngine.PostObjectEvent(localID, new EventParams( | ||||
|  | @ -318,9 +314,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
|             foreach (DetectedObject detobj in col.Colliders) | ||||
|             { | ||||
|                 DetectParams d = new DetectParams(); | ||||
|                 d.Position = new LSL_Types.Vector3(detobj.posVector.X, | ||||
|                     detobj.posVector.Y, | ||||
|                     detobj.posVector.Z); | ||||
|                 d.Position = detobj.posVector; | ||||
|                 d.Populate(myScriptEngine.World); | ||||
|                 det.Add(d); | ||||
|                 myScriptEngine.PostObjectEvent(localID, new EventParams( | ||||
|  | @ -337,9 +331,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
|             foreach (DetectedObject detobj in col.Colliders) | ||||
|             { | ||||
|                 DetectParams d = new DetectParams(); | ||||
|                 d.Position = new LSL_Types.Vector3(detobj.posVector.X, | ||||
|                     detobj.posVector.Y, | ||||
|                     detobj.posVector.Z); | ||||
|                 d.Position = detobj.posVector; | ||||
|                 d.Populate(myScriptEngine.World); | ||||
|                 det.Add(d); | ||||
|                 myScriptEngine.PostObjectEvent(localID, new EventParams( | ||||
|  | @ -381,8 +373,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
|             myScriptEngine.PostObjectEvent(localID, new EventParams( | ||||
|                     "at_target", new object[] { | ||||
|                     new LSL_Types.LSLInteger(handle), | ||||
|                     new LSL_Types.Vector3(targetpos.X,targetpos.Y,targetpos.Z), | ||||
|                     new LSL_Types.Vector3(atpos.X,atpos.Y,atpos.Z) }, | ||||
|                     new LSL_Types.Vector3(targetpos), | ||||
|                     new LSL_Types.Vector3(atpos) }, | ||||
|                     new DetectParams[0])); | ||||
|         } | ||||
| 
 | ||||
|  | @ -399,8 +391,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
|             myScriptEngine.PostObjectEvent(localID, new EventParams( | ||||
|                     "at_rot_target", new object[] { | ||||
|                     new LSL_Types.LSLInteger(handle), | ||||
|                     new LSL_Types.Quaternion(targetrot.X,targetrot.Y,targetrot.Z,targetrot.W), | ||||
|                     new LSL_Types.Quaternion(atrot.X,atrot.Y,atrot.Z,atrot.W) }, | ||||
|                     new LSL_Types.Quaternion(targetrot), | ||||
|                     new LSL_Types.Quaternion(atrot) }, | ||||
|                     new DetectParams[0])); | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -982,10 +982,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
|                 return false; | ||||
|             } | ||||
| 
 | ||||
|             UUID assetID = item.AssetID; | ||||
|             m_log.DebugFormat( | ||||
|                 "[XEngine] Loading script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", | ||||
|                 part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, | ||||
|                 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | ||||
| 
 | ||||
|             //m_log.DebugFormat("[XEngine] Compiling script {0} ({1} on object {2})", | ||||
|             //        item.Name, itemID.ToString(), part.ParentGroup.RootPart.Name); | ||||
|             UUID assetID = item.AssetID; | ||||
| 
 | ||||
|             ScenePresence presence = m_Scene.GetScenePresence(item.OwnerID); | ||||
| 
 | ||||
|  | @ -1164,10 +1166,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
|                                                   stateSource, m_MaxScriptQueue); | ||||
| 
 | ||||
| //                    if (DebugLevel >= 1) | ||||
|                     m_log.DebugFormat( | ||||
|                         "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", | ||||
|                         part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, | ||||
|                         part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | ||||
| //                    m_log.DebugFormat( | ||||
| //                        "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", | ||||
| //                        part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, | ||||
| //                        part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | ||||
| 
 | ||||
|                     if (presence != null) | ||||
|                     { | ||||
|  | @ -1465,9 +1467,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
|                 else if (p[i] is string) | ||||
|                     lsl_p[i] = new LSL_Types.LSLString((string)p[i]); | ||||
|                 else if (p[i] is Vector3) | ||||
|                     lsl_p[i] = new LSL_Types.Vector3(((Vector3)p[i]).X, ((Vector3)p[i]).Y, ((Vector3)p[i]).Z); | ||||
|                     lsl_p[i] = new LSL_Types.Vector3((Vector3)p[i]); | ||||
|                 else if (p[i] is Quaternion) | ||||
|                     lsl_p[i] = new LSL_Types.Quaternion(((Quaternion)p[i]).X, ((Quaternion)p[i]).Y, ((Quaternion)p[i]).Z, ((Quaternion)p[i]).W); | ||||
|                     lsl_p[i] = new LSL_Types.Quaternion((Quaternion)p[i]); | ||||
|                 else if (p[i] is float) | ||||
|                     lsl_p[i] = new LSL_Types.LSLFloat((float)p[i]); | ||||
|                 else | ||||
|  | @ -1491,9 +1493,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
|                 else if (p[i] is string) | ||||
|                     lsl_p[i] = new LSL_Types.LSLString((string)p[i]); | ||||
|                 else if (p[i] is Vector3) | ||||
|                     lsl_p[i] = new LSL_Types.Vector3(((Vector3)p[i]).X, ((Vector3)p[i]).Y, ((Vector3)p[i]).Z); | ||||
|                     lsl_p[i] = new LSL_Types.Vector3((Vector3)p[i]); | ||||
|                 else if (p[i] is Quaternion) | ||||
|                     lsl_p[i] = new LSL_Types.Quaternion(((Quaternion)p[i]).X, ((Quaternion)p[i]).Y, ((Quaternion)p[i]).Z, ((Quaternion)p[i]).W); | ||||
|                     lsl_p[i] = new LSL_Types.Quaternion((Quaternion)p[i]); | ||||
|                 else if (p[i] is float) | ||||
|                     lsl_p[i] = new LSL_Types.LSLFloat((float)p[i]); | ||||
|                 else | ||||
|  |  | |||
|  | @ -164,5 +164,19 @@ namespace OpenSim.Services.Connectors | |||
|             m_database.RemoveRegionEnvironmentSettings(regionUUID); | ||||
|         } | ||||
| 
 | ||||
|         public void SaveExtra(UUID regionID, string name, string val) | ||||
|         { | ||||
|             m_database.SaveExtra(regionID, name, val); | ||||
|         } | ||||
| 
 | ||||
|         public void RemoveExtra(UUID regionID, string name) | ||||
|         { | ||||
|             m_database.RemoveExtra(regionID, name); | ||||
|         } | ||||
| 
 | ||||
|         public Dictionary<string, string> GetExtra(UUID regionID) | ||||
|         { | ||||
|             return m_database.GetExtra(regionID); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -127,6 +127,19 @@ namespace OpenSim.Data.Null | |||
|         { | ||||
|             m_store.RemoveRegionEnvironmentSettings(regionUUID); | ||||
|         } | ||||
| 
 | ||||
|         public void SaveExtra(UUID regionID, string name, string value) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public void RemoveExtra(UUID regionID, string name) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public Dictionary<string, string> GetExtra(UUID regionID) | ||||
|         { | ||||
|             return null; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|  | @ -318,5 +331,18 @@ namespace OpenSim.Data.Null | |||
|         public void Shutdown() | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public void SaveExtra(UUID regionID, string name, string value) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public void RemoveExtra(UUID regionID, string name) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public Dictionary<string, string> GetExtra(UUID regionID) | ||||
|         { | ||||
|             return null; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -933,6 +933,11 @@ namespace OpenSim.Tests.Common.Mock | |||
|         } | ||||
| 
 | ||||
|         public void Close() | ||||
|         { | ||||
|             Close(false); | ||||
|         } | ||||
| 
 | ||||
|         public void Close(bool force) | ||||
|         { | ||||
|             // Fire the callback for this connection closing | ||||
|             // This is necesary to get the presence detector to notice that a client has logged out. | ||||
|  |  | |||
|  | @ -87,10 +87,18 @@ | |||
|     ;; from the selected region_info_source. | ||||
|     ; allow_regionless = false | ||||
| 
 | ||||
|     ;# {NonPhysicalPrimMin} {} {Minimum size of nonphysical prims?} {} 0.01 | ||||
|     ;; Minimum size for non-physical prims.  Affects resizing of existing prims.  This can be overriden in the region config file (as NonphysicalPrimMin!). | ||||
|     ; NonphysicalPrimMin = 0.01 | ||||
| 
 | ||||
|     ;# {NonPhysicalPrimMax} {} {Maximum size of nonphysical prims?} {} 256 | ||||
|     ;; Maximum size for non-physical prims.  Affects resizing of existing prims.  This can be overriden in the region config file (as NonphysicalPrimMax!). | ||||
|     ; NonphysicalPrimMax = 256 | ||||
| 
 | ||||
|     ;# {PhysicalPrimMin} {} {Minimum size of physical prims?} {} 10 | ||||
|     ;; Maximum size where a prim can be physical.  Affects resizing of existing prims.  This can be overriden in the region config file. | ||||
|     ; PhysicalPrimMin = 0.01 | ||||
| 
 | ||||
|     ;# {PhysicalPrimMax} {} {Maximum size of physical prims?} {} 10 | ||||
|     ;; Maximum size where a prim can be physical.  Affects resizing of existing prims.  This can be overriden in the region config file. | ||||
|     ; PhysicalPrimMax = 10 | ||||
|  | @ -675,7 +683,9 @@ | |||
|     ;; Maximum number of events to queue for a script (excluding timers) | ||||
|     ; MaxScriptEventQueue = 300 | ||||
| 
 | ||||
|     ;; Stack size per thread created | ||||
|     ;; Stack size per script engine thread in bytes. | ||||
|     ;; If you are experiencing StackOverflowExceptions you may want to increase this (e.g. double it). | ||||
|     ;; The trade-off may be increased memory usage by the script engine. | ||||
|     ; ThreadStackSize = 262144 | ||||
| 
 | ||||
|     ;# {DeleteScriptsOnStartup} {} {Delete previously compiled script DLLs on startup?} (true false) true | ||||
|  |  | |||
|  | @ -894,7 +894,7 @@ | |||
|     AvatarDensity = 60.0 | ||||
|     AvatarCapsuleRadius = 0.37 | ||||
|     AvatarCapsuleHeight = 1.5 | ||||
|     AvatarContactProcessingThreshold = 0.1; | ||||
|     AvatarContactProcessingThreshold = 0.1 | ||||
| 
 | ||||
|     MaxObjectMass = 10000.01 | ||||
| 
 | ||||
|  | @ -908,19 +908,19 @@ | |||
|     CcdSweptSphereRadius = 0.0 | ||||
|     ContactProcessingThreshold = 0.1 | ||||
|     ; If setting a pool size, also disable dynamic allocation (default pool size is 4096 with dynamic alloc) | ||||
|     MaxPersistantManifoldPoolSize = 0; | ||||
|     ShouldDisableContactPoolDynamicAllocation = False; | ||||
|     ShouldForceUpdateAllAabbs = False; | ||||
|     ShouldRandomizeSolverOrder = False; | ||||
|     ShouldSplitSimulationIslands = False; | ||||
|     ShouldEnableFrictionCaching = False; | ||||
|     MaxPersistantManifoldPoolSize = 0 | ||||
|     ShouldDisableContactPoolDynamicAllocation = False | ||||
|     ShouldForceUpdateAllAabbs = False | ||||
|     ShouldRandomizeSolverOrder = False | ||||
|     ShouldSplitSimulationIslands = False | ||||
|     ShouldEnableFrictionCaching = False | ||||
|     NumberOfSolverIterations = 0;    | ||||
| 
 | ||||
|     ; Linkset constraint parameters | ||||
|     LinkConstraintUseFrameOffset = False; | ||||
|     LinkConstraintEnableTransMotor = True; | ||||
|     LinkConstraintTransMotorMaxVel = 5.0; | ||||
|     LinkConstraintTransMotorMaxForce = 0.1; | ||||
|     LinkConstraintUseFrameOffset = False | ||||
|     LinkConstraintEnableTransMotor = True | ||||
|     LinkConstraintTransMotorMaxVel = 5.0 | ||||
|     LinkConstraintTransMotorMaxForce = 0.1 | ||||
| 
 | ||||
| 
 | ||||
|     ; Whether to mesh sculpties | ||||
|  | @ -931,16 +931,24 @@ | |||
| 
 | ||||
|     ; level of detail for physical meshes. 32,16,8 or 4 with 32 being full detail | ||||
|     MeshLevelOfDetail = 8 | ||||
|     ; if mesh size is > threshold meters, we need to add more detail because people will notice | ||||
|     MeshLevelOfDetailMegaPrimThreshold = 10 | ||||
|     MeshLevelOfDetailMegaPrim = 16 | ||||
|     ; number^2 non-physical level of detail of the sculpt texture.  32x32 - 1024 verticies | ||||
|     SculptLevelOfDetail = 32 | ||||
| 
 | ||||
|     ; Bullet step parameters | ||||
|     MaxSubSteps = 10; | ||||
|     MaxSubSteps = 10 | ||||
|     FixedTimeStep = .01667 | ||||
| 
 | ||||
|     MaxCollisionsPerFrame = 2048 | ||||
|     MaxUpdatesPerFrame = 8192 | ||||
| 
 | ||||
|     ; Detailed physics debug logging | ||||
|     PhysicsLoggingEnabled = False | ||||
|     PhysicsLoggingDir = "." | ||||
|     VehicleLoggingEnabled = False | ||||
| 
 | ||||
| [RemoteAdmin] | ||||
|     enabled = false | ||||
| 
 | ||||
|  |  | |||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							|  | @ -1799,6 +1799,7 @@ | |||
|       <Reference name="System.Core"/> | ||||
|       <Reference name="System.Xml"/> | ||||
|       <Reference name="Mono.Addins" path="../../../bin/"/> | ||||
|       <Reference name="NDesk.Options" path="../../../bin/"/> | ||||
|       <Reference name="OpenMetaverseTypes" path="../../../bin/"/> | ||||
|       <Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/> | ||||
|       <Reference name="OpenMetaverse" path="../../../bin/"/> | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 BlueWall
						BlueWall