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; | 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 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 |     public class Cache | ||||||
|     { |     { | ||||||
|  |         /// <summary> | ||||||
|  |         /// Must only be accessed under lock. | ||||||
|  |         /// </summary> | ||||||
|         private List<CacheItemBase> m_Index = new List<CacheItemBase>(); |         private List<CacheItemBase> m_Index = new List<CacheItemBase>(); | ||||||
|  | 
 | ||||||
|  |         /// <summary> | ||||||
|  |         /// Must only be accessed under m_Index lock. | ||||||
|  |         /// </summary> | ||||||
|         private Dictionary<string, CacheItemBase> m_Lookup = |         private Dictionary<string, CacheItemBase> m_Lookup = | ||||||
|             new Dictionary<string, CacheItemBase>(); |             new Dictionary<string, CacheItemBase>(); | ||||||
| 
 | 
 | ||||||
|  | @ -320,7 +327,6 @@ namespace OpenSim.Framework | ||||||
|             { |             { | ||||||
|                 if (m_Lookup.ContainsKey(index)) |                 if (m_Lookup.ContainsKey(index)) | ||||||
|                     item = m_Lookup[index]; |                     item = m_Lookup[index]; | ||||||
|             } |  | ||||||
| 
 | 
 | ||||||
|                 if (item == null) |                 if (item == null) | ||||||
|                 { |                 { | ||||||
|  | @ -332,6 +338,7 @@ namespace OpenSim.Framework | ||||||
|                 item.lastUsed = DateTime.Now; |                 item.lastUsed = DateTime.Now; | ||||||
|      |      | ||||||
|                 Expire(true); |                 Expire(true); | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             return item; |             return item; | ||||||
|         } |         } | ||||||
|  | @ -385,7 +392,10 @@ namespace OpenSim.Framework | ||||||
|         // |         // | ||||||
|         public Object Find(Predicate<CacheItemBase> d) |         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) |             if (item == null) | ||||||
|                 return null; |                 return null; | ||||||
|  | @ -419,12 +429,12 @@ namespace OpenSim.Framework | ||||||
|         public virtual void Store(string index, Object data, Type container, |         public virtual void Store(string index, Object data, Type container, | ||||||
|                 Object[] parameters) |                 Object[] parameters) | ||||||
|         { |         { | ||||||
|             Expire(false); |  | ||||||
| 
 |  | ||||||
|             CacheItemBase item; |             CacheItemBase item; | ||||||
| 
 | 
 | ||||||
|             lock (m_Index) |             lock (m_Index) | ||||||
|             { |             { | ||||||
|  |                 Expire(false); | ||||||
|  | 
 | ||||||
|                 if (m_Index.Contains(new CacheItemBase(index))) |                 if (m_Index.Contains(new CacheItemBase(index))) | ||||||
|                 { |                 { | ||||||
|                     if ((m_Flags & CacheFlags.AllowUpdate) != 0) |                     if ((m_Flags & CacheFlags.AllowUpdate) != 0) | ||||||
|  | @ -450,9 +460,17 @@ namespace OpenSim.Framework | ||||||
|                 m_Index.Add(item); |                 m_Index.Add(item); | ||||||
|                 m_Lookup[index] = item; |                 m_Lookup[index] = item; | ||||||
|             } |             } | ||||||
|  | 
 | ||||||
|             item.Store(data); |             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) |         protected virtual void Expire(bool getting) | ||||||
|         { |         { | ||||||
|             if (getting && (m_Strategy == CacheStrategy.Aggressive)) |             if (getting && (m_Strategy == CacheStrategy.Aggressive)) | ||||||
|  | @ -479,8 +497,6 @@ namespace OpenSim.Framework | ||||||
|                     if (Count < Size) |                     if (Count < Size) | ||||||
|                         return; |                         return; | ||||||
| 
 | 
 | ||||||
|                 lock (m_Index) |  | ||||||
|                 { |  | ||||||
|                     m_Index.Sort(new SortLRU()); |                     m_Index.Sort(new SortLRU()); | ||||||
|                     m_Index.Reverse(); |                     m_Index.Reverse(); | ||||||
| 
 | 
 | ||||||
|  | @ -513,14 +529,17 @@ namespace OpenSim.Framework | ||||||
|                         foreach (CacheItemBase item in m_Index) |                         foreach (CacheItemBase item in m_Index) | ||||||
|                             m_Lookup[item.uuid] = item; |                             m_Lookup[item.uuid] = item; | ||||||
|                     } |                     } | ||||||
|                 } | 
 | ||||||
|                     break; |                     break; | ||||||
|  | 
 | ||||||
|                     default: |                     default: | ||||||
|                         break; |                         break; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public void Invalidate(string uuid) |         public void Invalidate(string uuid) | ||||||
|  |         { | ||||||
|  |             lock (m_Index) | ||||||
|             { |             { | ||||||
|                 if (!m_Lookup.ContainsKey(uuid)) |                 if (!m_Lookup.ContainsKey(uuid)) | ||||||
|                     return; |                     return; | ||||||
|  | @ -529,11 +548,15 @@ namespace OpenSim.Framework | ||||||
|                 m_Lookup.Remove(uuid); |                 m_Lookup.Remove(uuid); | ||||||
|                 m_Index.Remove(item); |                 m_Index.Remove(item); | ||||||
|             } |             } | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         public void Clear() |         public void Clear() | ||||||
|  |         { | ||||||
|  |             lock (m_Index) | ||||||
|             { |             { | ||||||
|                 m_Index.Clear(); |                 m_Index.Clear(); | ||||||
|                 m_Lookup.Clear(); |                 m_Lookup.Clear(); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | @ -678,6 +678,8 @@ namespace OpenSim.Framework.Console | ||||||
|     { |     { | ||||||
| //        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | //        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||||
| 
 | 
 | ||||||
|  |         public event OnOutputDelegate OnOutput; | ||||||
|  | 
 | ||||||
|         public ICommands Commands { get; private set; } |         public ICommands Commands { get; private set; } | ||||||
| 
 | 
 | ||||||
|         public CommandConsole(string defaultPrompt) : base(defaultPrompt) |         public CommandConsole(string defaultPrompt) : base(defaultPrompt) | ||||||
|  | @ -697,6 +699,13 @@ namespace OpenSim.Framework.Console | ||||||
|                 Output(s); |                 Output(s); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         protected void FireOnOutput(string text) | ||||||
|  |         { | ||||||
|  |             OnOutputDelegate onOutput = OnOutput; | ||||||
|  |             if (onOutput != null) | ||||||
|  |                 onOutput(text); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Display a command prompt on the console and wait for user input |         /// Display a command prompt on the console and wait for user input | ||||||
|         /// </summary> |         /// </summary> | ||||||
|  |  | ||||||
|  | @ -319,6 +319,8 @@ namespace OpenSim.Framework.Console | ||||||
| 
 | 
 | ||||||
|         public override void Output(string text, string level) |         public override void Output(string text, string level) | ||||||
|         { |         { | ||||||
|  |             FireOnOutput(text); | ||||||
|  | 
 | ||||||
|             lock (m_commandLine) |             lock (m_commandLine) | ||||||
|             { |             { | ||||||
|                 if (m_cursorYPosition == -1) |                 if (m_cursorYPosition == -1) | ||||||
|  |  | ||||||
|  | @ -40,6 +40,8 @@ namespace OpenSim.Framework.Console | ||||||
|     /// </summary> |     /// </summary> | ||||||
|     public class MockConsole : ICommandConsole |     public class MockConsole : ICommandConsole | ||||||
|     { |     { | ||||||
|  |         public event OnOutputDelegate OnOutput; | ||||||
|  | 
 | ||||||
|         private MockCommands m_commands = new MockCommands(); |         private MockCommands m_commands = new MockCommands(); | ||||||
| 
 | 
 | ||||||
|         public ICommands Commands { get { return m_commands; } } |         public ICommands Commands { get { return m_commands; } } | ||||||
|  |  | ||||||
|  | @ -100,6 +100,7 @@ namespace OpenSim.Framework.Console | ||||||
|                 m_LineNumber++; |                 m_LineNumber++; | ||||||
|                 m_Scrollback.Add(String.Format("{0}", m_LineNumber)+":"+level+":"+text); |                 m_Scrollback.Add(String.Format("{0}", m_LineNumber)+":"+level+":"+text); | ||||||
|             } |             } | ||||||
|  |             FireOnOutput(text.Trim()); | ||||||
|             System.Console.WriteLine(text.Trim()); |             System.Console.WriteLine(text.Trim()); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1033,7 +1033,21 @@ namespace OpenSim.Framework | ||||||
| 
 | 
 | ||||||
|         void InPacket(object NewPack); |         void InPacket(object NewPack); | ||||||
|         void ProcessInPacket(Packet NewPack); |         void ProcessInPacket(Packet NewPack); | ||||||
|  | 
 | ||||||
|  |         /// <summary> | ||||||
|  |         /// Close this client | ||||||
|  |         /// </summary> | ||||||
|         void Close(); |         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); |         void Kick(string message); | ||||||
|          |          | ||||||
|         /// <summary> |         /// <summary> | ||||||
|  |  | ||||||
|  | @ -74,8 +74,12 @@ namespace OpenSim.Framework | ||||||
|         XmlElement GetXml(XmlDocument doc); |         XmlElement GetXml(XmlDocument doc); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public delegate void OnOutputDelegate(string message); | ||||||
|  | 
 | ||||||
|     public interface ICommandConsole : IConsole |     public interface ICommandConsole : IConsole | ||||||
|     { |     { | ||||||
|  |         event OnOutputDelegate OnOutput; | ||||||
|  | 
 | ||||||
|         ICommands Commands { get; } |         ICommands Commands { get; } | ||||||
| 
 | 
 | ||||||
|         /// <summary> |         /// <summary> | ||||||
|  |  | ||||||
|  | @ -89,6 +89,17 @@ namespace OpenSim.Framework.Monitoring | ||||||
|                 FirstTick = Environment.TickCount & Int32.MaxValue; |                 FirstTick = Environment.TickCount & Int32.MaxValue; | ||||||
|                 LastTick = FirstTick; |                 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> |         /// <summary> | ||||||
|  | @ -97,6 +108,32 @@ namespace OpenSim.Framework.Monitoring | ||||||
|         /// /summary> |         /// /summary> | ||||||
|         public static event Action<ThreadWatchdogInfo> OnWatchdogTimeout; |         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 readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||||||
|         private static Dictionary<int, ThreadWatchdogInfo> m_threads; |         private static Dictionary<int, ThreadWatchdogInfo> m_threads; | ||||||
|         private static System.Timers.Timer m_watchdogTimer; |         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 = new System.Timers.Timer(WATCHDOG_INTERVAL_MS); | ||||||
|             m_watchdogTimer.AutoReset = false; |             m_watchdogTimer.AutoReset = false; | ||||||
|             m_watchdogTimer.Elapsed += WatchdogTimerElapsed; |             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> |         /// <summary> | ||||||
|  | @ -314,7 +346,9 @@ namespace OpenSim.Framework.Monitoring | ||||||
|                                 if (callbackInfos == null) |                                 if (callbackInfos == null) | ||||||
|                                     callbackInfos = new List<ThreadWatchdogInfo>(); |                                     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 UUID lastMapUUID = UUID.Zero; | ||||||
|         public string lastMapRefresh = "0"; |         public string lastMapRefresh = "0"; | ||||||
| 
 | 
 | ||||||
|  |         private float m_nonphysPrimMin = 0; | ||||||
|         private int m_nonphysPrimMax = 0; |         private int m_nonphysPrimMax = 0; | ||||||
|  |         private float m_physPrimMin = 0; | ||||||
|         private int m_physPrimMax = 0; |         private int m_physPrimMax = 0; | ||||||
|         private bool m_clampPrimSize = false; |         private bool m_clampPrimSize = false; | ||||||
|         private int m_objectCapacity = 0; |         private int m_objectCapacity = 0; | ||||||
|  | @ -285,11 +287,21 @@ namespace OpenSim.Framework | ||||||
|             set { m_windlight = value; } |             set { m_windlight = value; } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         public float NonphysPrimMin | ||||||
|  |         { | ||||||
|  |             get { return m_nonphysPrimMin; } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         public int NonphysPrimMax |         public int NonphysPrimMax | ||||||
|         { |         { | ||||||
|             get { return m_nonphysPrimMax; } |             get { return m_nonphysPrimMax; } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         public float PhysPrimMin | ||||||
|  |         { | ||||||
|  |             get { return m_physPrimMin; } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         public int PhysPrimMax |         public int PhysPrimMax | ||||||
|         { |         { | ||||||
|             get { return m_physPrimMax; } |             get { return m_physPrimMax; } | ||||||
|  | @ -623,16 +635,28 @@ namespace OpenSim.Framework | ||||||
|             m_regionType = config.GetString("RegionType", String.Empty); |             m_regionType = config.GetString("RegionType", String.Empty); | ||||||
|             allKeys.Remove("RegionType"); |             allKeys.Remove("RegionType"); | ||||||
| 
 | 
 | ||||||
|             // Prim stuff |             #region Prim stuff | ||||||
|             // | 
 | ||||||
|  |             m_nonphysPrimMin = config.GetFloat("NonphysicalPrimMin", 0); | ||||||
|  |             allKeys.Remove("NonphysicalPrimMin"); | ||||||
|  | 
 | ||||||
|             m_nonphysPrimMax = config.GetInt("NonphysicalPrimMax", 0); |             m_nonphysPrimMax = config.GetInt("NonphysicalPrimMax", 0); | ||||||
|             allKeys.Remove("NonphysicalPrimMax"); |             allKeys.Remove("NonphysicalPrimMax"); | ||||||
|  | 
 | ||||||
|  |             m_physPrimMin = config.GetFloat("PhysicalPrimMin", 0); | ||||||
|  |             allKeys.Remove("PhysicalPrimMin"); | ||||||
|  | 
 | ||||||
|             m_physPrimMax = config.GetInt("PhysicalPrimMax", 0); |             m_physPrimMax = config.GetInt("PhysicalPrimMax", 0); | ||||||
|             allKeys.Remove("PhysicalPrimMax"); |             allKeys.Remove("PhysicalPrimMax"); | ||||||
|  |              | ||||||
|             m_clampPrimSize = config.GetBoolean("ClampPrimSize", false); |             m_clampPrimSize = config.GetBoolean("ClampPrimSize", false); | ||||||
|             allKeys.Remove("ClampPrimSize"); |             allKeys.Remove("ClampPrimSize"); | ||||||
|  |              | ||||||
|             m_objectCapacity = config.GetInt("MaxPrims", 15000); |             m_objectCapacity = config.GetInt("MaxPrims", 15000); | ||||||
|             allKeys.Remove("MaxPrims"); |             allKeys.Remove("MaxPrims"); | ||||||
|  |              | ||||||
|  |             #endregion | ||||||
|  | 
 | ||||||
|             m_agentCapacity = config.GetInt("MaxAgents", 100); |             m_agentCapacity = config.GetInt("MaxAgents", 100); | ||||||
|             allKeys.Remove("MaxAgents"); |             allKeys.Remove("MaxAgents"); | ||||||
| 
 | 
 | ||||||
|  | @ -668,10 +692,18 @@ namespace OpenSim.Framework | ||||||
| 
 | 
 | ||||||
|             config.Set("ExternalHostName", m_externalHostName); |             config.Set("ExternalHostName", m_externalHostName); | ||||||
| 
 | 
 | ||||||
|  |             if (m_nonphysPrimMin != 0) | ||||||
|  |                 config.Set("NonphysicalPrimMax", m_nonphysPrimMin); | ||||||
|  | 
 | ||||||
|             if (m_nonphysPrimMax != 0) |             if (m_nonphysPrimMax != 0) | ||||||
|                 config.Set("NonphysicalPrimMax", m_nonphysPrimMax); |                 config.Set("NonphysicalPrimMax", m_nonphysPrimMax); | ||||||
|  | 
 | ||||||
|  |             if (m_physPrimMin != 0) | ||||||
|  |                 config.Set("PhysicalPrimMax", m_physPrimMin); | ||||||
|  |              | ||||||
|             if (m_physPrimMax != 0) |             if (m_physPrimMax != 0) | ||||||
|                 config.Set("PhysicalPrimMax", m_physPrimMax); |                 config.Set("PhysicalPrimMax", m_physPrimMax); | ||||||
|  |                          | ||||||
|             config.Set("ClampPrimSize", m_clampPrimSize.ToString()); |             config.Set("ClampPrimSize", m_clampPrimSize.ToString()); | ||||||
| 
 | 
 | ||||||
|             if (m_objectCapacity != 0) |             if (m_objectCapacity != 0) | ||||||
|  | @ -754,9 +786,15 @@ namespace OpenSim.Framework | ||||||
|             configMember.addConfigurationOption("lastmap_refresh", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, |             configMember.addConfigurationOption("lastmap_refresh", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, | ||||||
|                                                 "Last Map Refresh", Util.UnixTimeSinceEpoch().ToString(), true); |                                                 "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, |             configMember.addConfigurationOption("nonphysical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32, | ||||||
|                                                 "Maximum size for nonphysical prims", m_nonphysPrimMax.ToString(), true); |                                                 "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, |             configMember.addConfigurationOption("physical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32, | ||||||
|                                                 "Maximum size for physical prims", m_physPrimMax.ToString(), true); |                                                 "Maximum size for physical prims", m_physPrimMax.ToString(), true); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -850,6 +850,12 @@ namespace OpenSim.Framework | ||||||
|             return Math.Min(Math.Max(x, min), max); |             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> |         /// <summary> | ||||||
|         /// Convert an UUID to a raw uuid string.  Right now this is a string without hyphens. |         /// Convert an UUID to a raw uuid string.  Right now this is a string without hyphens. | ||||||
|         /// </summary> |         /// </summary> | ||||||
|  |  | ||||||
|  | @ -35,6 +35,7 @@ using System.Text; | ||||||
| using System.Text.RegularExpressions; | using System.Text.RegularExpressions; | ||||||
| using System.Timers; | using System.Timers; | ||||||
| using log4net; | using log4net; | ||||||
|  | using NDesk.Options; | ||||||
| using Nini.Config; | using Nini.Config; | ||||||
| using OpenMetaverse; | using OpenMetaverse; | ||||||
| using OpenSim.Framework; | using OpenSim.Framework; | ||||||
|  | @ -310,8 +311,11 @@ namespace OpenSim | ||||||
|                                           "Change the scale of a named prim", HandleEditScale); |                                           "Change the scale of a named prim", HandleEditScale); | ||||||
| 
 | 
 | ||||||
|             m_console.Commands.AddCommand("Users", false, "kick user", |             m_console.Commands.AddCommand("Users", false, "kick user", | ||||||
|                                           "kick user <first> <last> [message]", |                                           "kick user <first> <last> [--force] [message]", | ||||||
|                                           "Kick a user off the simulator", KickUserCommand); |                                           "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", |             m_console.Commands.AddCommand("Users", false, "show users", | ||||||
|                                           "show users [full]", |                                           "show users [full]", | ||||||
|  | @ -416,6 +420,7 @@ namespace OpenSim | ||||||
|             { |             { | ||||||
|                 RunCommandScript(m_shutdownCommandsFile); |                 RunCommandScript(m_shutdownCommandsFile); | ||||||
|             } |             } | ||||||
|  |              | ||||||
|             base.ShutdownSpecific(); |             base.ShutdownSpecific(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -453,11 +458,17 @@ namespace OpenSim | ||||||
|         /// <param name="cmdparams">name of avatar to kick</param> |         /// <param name="cmdparams">name of avatar to kick</param> | ||||||
|         private void KickUserCommand(string module, string[] cmdparams) |         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; |                 return; | ||||||
| 
 | 
 | ||||||
|             string alert = null; |             string alert = null; | ||||||
|             if (cmdparams.Length > 4) |             if (mainParams.Count > 4) | ||||||
|                 alert = String.Format("\n{0}\n", String.Join(" ", cmdparams, 4, cmdparams.Length - 4)); |                 alert = String.Format("\n{0}\n", String.Join(" ", cmdparams, 4, cmdparams.Length - 4)); | ||||||
| 
 | 
 | ||||||
|             IList agents = SceneManager.GetCurrentSceneAvatars(); |             IList agents = SceneManager.GetCurrentSceneAvatars(); | ||||||
|  | @ -466,8 +477,8 @@ namespace OpenSim | ||||||
|             { |             { | ||||||
|                 RegionInfo regionInfo = presence.Scene.RegionInfo; |                 RegionInfo regionInfo = presence.Scene.RegionInfo; | ||||||
| 
 | 
 | ||||||
|                 if (presence.Firstname.ToLower().Contains(cmdparams[2].ToLower()) && |                 if (presence.Firstname.ToLower().Contains(mainParams[2].ToLower()) && | ||||||
|                     presence.Lastname.ToLower().Contains(cmdparams[3].ToLower())) |                     presence.Lastname.ToLower().Contains(mainParams[3].ToLower())) | ||||||
|                 { |                 { | ||||||
|                     MainConsole.Instance.Output( |                     MainConsole.Instance.Output( | ||||||
|                         String.Format( |                         String.Format( | ||||||
|  | @ -480,7 +491,7 @@ namespace OpenSim | ||||||
|                     else |                     else | ||||||
|                         presence.ControllingClient.Kick("\nThe OpenSim manager kicked you out.\n"); |                         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; |             m_httpServerPort = m_networkServersInfo.HttpListenerPort; | ||||||
|             SceneManager.OnRestartSim += handleRestartRegion; |             SceneManager.OnRestartSim += handleRestartRegion; | ||||||
| 
 | 
 | ||||||
|             // Only start the memory watchdog once all regions are ready |             // Only enable the watchdogs when all regions are ready.  Otherwise we get false positives when cpu is | ||||||
|             SceneManager.OnRegionsReadyStatusChange += sm => MemoryWatchdog.Enabled = sm.AllRegionsReady; |             // 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> |         /// <summary> | ||||||
|  |  | ||||||
|  | @ -94,7 +94,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests | ||||||
|             UUID spId = TestHelpers.ParseTail(0x1); |             UUID spId = TestHelpers.ParseTail(0x1); | ||||||
| 
 | 
 | ||||||
|             SceneHelpers.AddScenePresence(m_scene, spId); |             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 |             // TODO: Add more assertions for the other aspects of event queues | ||||||
|             Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0)); |             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 |         #region Client Methods | ||||||
| 
 | 
 | ||||||
|         /// <summary> |  | ||||||
|         /// Close down the client view |  | ||||||
|         /// </summary> |  | ||||||
|         public void Close() |         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. |             // 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. |             // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection. | ||||||
|             lock (CloseSyncLock) |             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; |                     return; | ||||||
| 
 | 
 | ||||||
|                 IsActive = false; |                 IsActive = false; | ||||||
|  | @ -5810,7 +5814,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | ||||||
|                 args.Channel = ch; |                 args.Channel = ch; | ||||||
|                 args.From = String.Empty; |                 args.From = String.Empty; | ||||||
|                 args.Message = Utils.BytesToString(msg); |                 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.Position = new Vector3(); | ||||||
|                 args.Scene = Scene; |                 args.Scene = Scene; | ||||||
|                 args.Sender = this; |                 args.Sender = this; | ||||||
|  | @ -11989,7 +11993,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | ||||||
|         { |         { | ||||||
|             Kick(reason); |             Kick(reason); | ||||||
|             Thread.Sleep(1000); |             Thread.Sleep(1000); | ||||||
|             Close(); |             Disconnect(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public void Disconnect() |         public void Disconnect() | ||||||
|  |  | ||||||
|  | @ -458,10 +458,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | ||||||
| 
 | 
 | ||||||
|         public void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup so) |         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) |             lock (sp.AttachmentsSyncLock) | ||||||
|             { |             { | ||||||
|                 // Save avatar attachment information |                 // Save avatar attachment information | ||||||
|  | @ -976,7 +972,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | ||||||
|             ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); |             ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); | ||||||
|             SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); |             SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); | ||||||
| 
 | 
 | ||||||
|             if (sp != null && group != null) |             if (sp != null && group != null && group.FromItemID != UUID.Zero) | ||||||
|                 DetachSingleAttachmentToInv(sp, group); |                 DetachSingleAttachmentToInv(sp, group); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -994,7 +990,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | ||||||
|      |      | ||||||
|                     foreach (SceneObjectGroup group in attachments) |                     foreach (SceneObjectGroup group in attachments) | ||||||
|                     { |                     { | ||||||
|                         if (group.FromItemID == itemID) |                         if (group.FromItemID == itemID && group.FromItemID != UUID.Zero) | ||||||
|                         { |                         { | ||||||
|                             DetachSingleAttachmentToInv(sp, group); |                             DetachSingleAttachmentToInv(sp, group); | ||||||
|                             return; |                             return; | ||||||
|  |  | ||||||
|  | @ -461,7 +461,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | ||||||
| 
 | 
 | ||||||
|             SceneObjectGroup rezzedAtt = presence.GetAttachments()[0]; |             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. |             // Check that we can't retrieve this attachment from the scene. | ||||||
|             Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null); |             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. |                 // an agent cannot teleport back to this region if it has teleported away. | ||||||
|                 Thread.Sleep(2000); |                 Thread.Sleep(2000); | ||||||
| 
 | 
 | ||||||
|                 sp.Scene.IncomingCloseAgent(sp.UUID); |                 sp.Scene.IncomingCloseAgent(sp.UUID, false); | ||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|  |  | ||||||
|  | @ -312,7 +312,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | ||||||
| //                        "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", | //                        "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", | ||||||
| //                        s.RegionInfo.RegionName, destination.RegionHandle); | //                        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; |                 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) |         public ArchiveReadRequest(Scene scene, string loadPath, bool merge, bool skipAssets, Guid requestId) | ||||||
|         { |         { | ||||||
|             m_scene = scene; |             m_scene = scene; | ||||||
|  | @ -120,6 +127,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver | ||||||
| 
 | 
 | ||||||
|             // Zero can never be a valid user id |             // Zero can never be a valid user id | ||||||
|             m_validUserUuids[UUID.Zero] = false; |             m_validUserUuids[UUID.Zero] = false; | ||||||
|  | 
 | ||||||
|  |             m_groupsModule = m_scene.RequestModuleInterface<IGroupsModule>(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public ArchiveReadRequest(Scene scene, Stream loadStream, bool merge, bool skipAssets, Guid requestId) |         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 |             // Zero can never be a valid user id | ||||||
|             m_validUserUuids[UUID.Zero] = false; |             m_validUserUuids[UUID.Zero] = false; | ||||||
|  | 
 | ||||||
|  |             m_groupsModule = m_scene.RequestModuleInterface<IGroupsModule>(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         /// <summary> |         /// <summary> | ||||||
|  | @ -302,6 +313,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver | ||||||
|                     if (!ResolveUserUuid(part.LastOwnerID)) |                     if (!ResolveUserUuid(part.LastOwnerID)) | ||||||
|                         part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; |                         part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | ||||||
| 
 | 
 | ||||||
|  |                     if (!ResolveGroupUuid(part.GroupID)) | ||||||
|  |                         part.GroupID = UUID.Zero; | ||||||
|  | 
 | ||||||
|                     // And zap any troublesome sit target information |                     // And zap any troublesome sit target information | ||||||
| //                    part.SitTargetOrientation = new Quaternion(0, 0, 0, 1); | //                    part.SitTargetOrientation = new Quaternion(0, 0, 0, 1); | ||||||
| //                    part.SitTargetPosition    = new Vector3(0, 0, 0); | //                    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; |                                 kvp.Value.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | ||||||
|                             } |                             } | ||||||
|  | 
 | ||||||
|                             if (kvp.Value.CreatorData == null || kvp.Value.CreatorData == string.Empty) |                             if (kvp.Value.CreatorData == null || kvp.Value.CreatorData == string.Empty) | ||||||
|                             { |                             { | ||||||
|                                 if (!ResolveUserUuid(kvp.Value.CreatorID)) |                                 if (!ResolveUserUuid(kvp.Value.CreatorID)) | ||||||
|                                     kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; |                                     kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; | ||||||
|                             } |                             } | ||||||
|  | 
 | ||||||
|                             if (UserManager != null) |                             if (UserManager != null) | ||||||
|                                 UserManager.AddUser(kvp.Value.CreatorID, kvp.Value.CreatorData); |                                 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) |             foreach (string serialisedParcel in serialisedParcels) | ||||||
|             { |             { | ||||||
|                 LandData parcel = LandDataSerializer.Deserialize(serialisedParcel); |                 LandData parcel = LandDataSerializer.Deserialize(serialisedParcel); | ||||||
|  |                  | ||||||
|  |                 // Validate User and Group UUID's | ||||||
|  | 
 | ||||||
|                 if (!ResolveUserUuid(parcel.OwnerID)) |                 if (!ResolveUserUuid(parcel.OwnerID)) | ||||||
|                     parcel.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; |                     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( | //                m_log.DebugFormat( | ||||||
| //                    "[ARCHIVER]: Adding parcel {0}, local id {1}, area {2}",  | //                    "[ARCHIVER]: Adding parcel {0}, local id {1}, area {2}",  | ||||||
| //                    parcel.Name, parcel.LocalID, parcel.Area); | //                    parcel.Name, parcel.LocalID, parcel.Area); | ||||||
|  | @ -401,6 +438,30 @@ namespace OpenSim.Region.CoreModules.World.Archiver | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         /// <summary> |         /// <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 |         /// Load an asset | ||||||
|         /// </summary> |         /// </summary> | ||||||
|         /// <param name="assetFilename"></param> |         /// <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> |         /// <param name="regionUUID">the region UUID</param> | ||||||
|         void RemoveRegionEnvironmentSettings(UUID regionUUID); |         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> |         /// <param name="regionUUID">the region UUID</param> | ||||||
|         void RemoveRegionEnvironmentSettings(UUID regionUUID); |         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(); |         void Shutdown(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -213,6 +213,9 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
|         /// </remarks> |         /// </remarks> | ||||||
|         public event NewScript OnNewScript; |         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) |         public virtual void TriggerNewScript(UUID clientID, SceneObjectPart part, UUID itemID) | ||||||
|         { |         { | ||||||
|             NewScript handlerNewScript = OnNewScript; |             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> |         /// </summary> | ||||||
|         public bool CollidablePrims { get; private set; } |         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; |         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 float m_maxPhys = 10; | ||||||
|  | 
 | ||||||
|         public bool m_clampPrimSize; |         public bool m_clampPrimSize; | ||||||
|         public bool m_trustBinaries; |         public bool m_trustBinaries; | ||||||
|         public bool m_allowScriptCrossings; |         public bool m_allowScriptCrossings; | ||||||
|  | @ -174,6 +192,8 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
|         protected ICapabilitiesModule m_capsModule; |         protected ICapabilitiesModule m_capsModule; | ||||||
|         protected IGroupsModule m_groupsModule; |         protected IGroupsModule m_groupsModule; | ||||||
| 
 | 
 | ||||||
|  |         private Dictionary<string, string> m_extraSettings; | ||||||
|  | 
 | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Current scene frame number |         /// Current scene frame number | ||||||
|         /// </summary> |         /// </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 |             // 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. |             // region is set up and avoid these gyrations. | ||||||
|             RegionSettings rs = simDataService.LoadRegionSettings(RegionInfo.RegionID); |             RegionSettings rs = simDataService.LoadRegionSettings(RegionInfo.RegionID); | ||||||
|  |             m_extraSettings = simDataService.GetExtra(RegionInfo.RegionID); | ||||||
|  | 
 | ||||||
|             bool updatedTerrainTextures = false; |             bool updatedTerrainTextures = false; | ||||||
|             if (rs.TerrainTexture1 == UUID.Zero) |             if (rs.TerrainTexture1 == UUID.Zero) | ||||||
|             { |             { | ||||||
|  | @ -717,14 +739,25 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
|                 PhysicalPrims = startupConfig.GetBoolean("physical_prim", PhysicalPrims); |                 PhysicalPrims = startupConfig.GetBoolean("physical_prim", PhysicalPrims); | ||||||
|                 CollidablePrims = startupConfig.GetBoolean("collidable_prim", CollidablePrims); |                 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); |                 m_maxNonphys = startupConfig.GetFloat("NonphysicalPrimMax", m_maxNonphys); | ||||||
|                 if (RegionInfo.NonphysPrimMax > 0) |                 if (RegionInfo.NonphysPrimMax > 0) | ||||||
|                 { |                 { | ||||||
|                     m_maxNonphys = RegionInfo.NonphysPrimMax; |                     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) |                 if (RegionInfo.PhysPrimMax > 0) | ||||||
|                 { |                 { | ||||||
|                     m_maxPhys = RegionInfo.PhysPrimMax; |                     m_maxPhys = RegionInfo.PhysPrimMax; | ||||||
|  | @ -4083,16 +4116,19 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Tell a single agent to disconnect from the region. |         /// Tell a single agent to disconnect from the region. | ||||||
|         /// </summary> |         /// </summary> | ||||||
|         /// <param name="regionHandle"></param> |  | ||||||
|         /// <param name="agentID"></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); |             //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); | ||||||
| 
 | 
 | ||||||
|             ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); |             ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); | ||||||
|             if (presence != null) |             if (presence != null) | ||||||
|             { |             { | ||||||
|                 presence.ControllingClient.Close(); |                 presence.ControllingClient.Close(force); | ||||||
|                 return true; |                 return true; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  | @ -5443,5 +5479,44 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
| 
 | 
 | ||||||
|             callback(asset); |             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; |                     Vector3 scale = part.Shape.Scale; | ||||||
| 
 | 
 | ||||||
|                     if (scale.X > m_parentScene.m_maxNonphys) |                     scale.X = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.X)); | ||||||
|                         scale.X = m_parentScene.m_maxNonphys; |                     scale.Y = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.Y)); | ||||||
|                     if (scale.Y > m_parentScene.m_maxNonphys) |                     scale.Z = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.Z)); | ||||||
|                         scale.Y = m_parentScene.m_maxNonphys; |  | ||||||
|                     if (scale.Z > m_parentScene.m_maxNonphys) |  | ||||||
|                         scale.Z = m_parentScene.m_maxNonphys; |  | ||||||
| 
 | 
 | ||||||
|                     part.Shape.Scale = scale; |                     part.Shape.Scale = scale; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|  | @ -2674,17 +2674,17 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
| 
 | 
 | ||||||
|             RootPart.StoreUndoState(true); |             RootPart.StoreUndoState(true); | ||||||
| 
 | 
 | ||||||
|             scale.X = Math.Min(scale.X, Scene.m_maxNonphys); |             scale.X = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.X)); | ||||||
|             scale.Y = Math.Min(scale.Y, Scene.m_maxNonphys); |             scale.Y = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Y)); | ||||||
|             scale.Z = Math.Min(scale.Z, Scene.m_maxNonphys); |             scale.Z = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Z)); | ||||||
| 
 | 
 | ||||||
|             PhysicsActor pa = m_rootPart.PhysActor; |             PhysicsActor pa = m_rootPart.PhysActor; | ||||||
| 
 | 
 | ||||||
|             if (pa != null && pa.IsPhysical) |             if (pa != null && pa.IsPhysical) | ||||||
|             { |             { | ||||||
|                 scale.X = Math.Min(scale.X, Scene.m_maxPhys); |                 scale.X = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.X)); | ||||||
|                 scale.Y = Math.Min(scale.Y, Scene.m_maxPhys); |                 scale.Y = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Y)); | ||||||
|                 scale.Z = Math.Min(scale.Z, Scene.m_maxPhys); |                 scale.Z = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Z)); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             float x = (scale.X / RootPart.Scale.X); |             float x = (scale.X / RootPart.Scale.X); | ||||||
|  | @ -2716,6 +2716,14 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
|                                 y *= a; |                                 y *= a; | ||||||
|                                 z *= 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) |                             if (oldSize.Y * y > m_scene.m_maxPhys) | ||||||
|                             { |                             { | ||||||
|  | @ -2725,6 +2733,14 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
|                                 y *= a; |                                 y *= a; | ||||||
|                                 z *= 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) |                             if (oldSize.Z * z > m_scene.m_maxPhys) | ||||||
|                             { |                             { | ||||||
|  | @ -2734,6 +2750,14 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
|                                 y *= a; |                                 y *= a; | ||||||
|                                 z *= 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 |                         else | ||||||
|                         { |                         { | ||||||
|  | @ -2745,6 +2769,14 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
|                                 y *= a; |                                 y *= a; | ||||||
|                                 z *= 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) |                             if (oldSize.Y * y > m_scene.m_maxNonphys) | ||||||
|                             { |                             { | ||||||
|  | @ -2754,6 +2786,14 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
|                                 y *= a; |                                 y *= a; | ||||||
|                                 z *= 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) |                             if (oldSize.Z * z > m_scene.m_maxNonphys) | ||||||
|                             { |                             { | ||||||
|  | @ -2763,6 +2803,14 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
|                                 y *= a; |                                 y *= a; | ||||||
|                                 z *= 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; | //                        obPart.IgnoreUndoUpdate = false; | ||||||
|  |  | ||||||
|  | @ -733,7 +733,7 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
|                     } |                     } | ||||||
|                     catch (Exception e) |                     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> |         /// <param name="scale"></param> | ||||||
|         public void Resize(Vector3 scale) |         public void Resize(Vector3 scale) | ||||||
|         { |         { | ||||||
|             scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxNonphys); |             scale.X = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.X)); | ||||||
|             scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxNonphys); |             scale.Y = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Y)); | ||||||
|             scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxNonphys); |             scale.Z = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Z)); | ||||||
| 
 | 
 | ||||||
|             PhysicsActor pa = PhysActor; |             PhysicsActor pa = PhysActor; | ||||||
| 
 |  | ||||||
|             if (pa != null && pa.IsPhysical) |             if (pa != null && pa.IsPhysical) | ||||||
|             { |             { | ||||||
|                 scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxPhys); |                 scale.X = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.X)); | ||||||
|                 scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxPhys); |                 scale.Y = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Y)); | ||||||
|                 scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxPhys); |                 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); | //            m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale); | ||||||
|  | @ -2852,23 +2851,32 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Set the color of prim faces |         /// Set the color & alpha of prim faces | ||||||
|         /// </summary> |         /// </summary> | ||||||
|         /// <param name="color"></param> |  | ||||||
|         /// <param name="face"></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 |             // 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(); |             Byte[] buf = Shape.Textures.GetBytes(); | ||||||
|             Primitive.TextureEntry tex = new Primitive.TextureEntry(buf, 0, buf.Length); |             Primitive.TextureEntry tex = new Primitive.TextureEntry(buf, 0, buf.Length); | ||||||
|             Color4 texcolor; |             Color4 texcolor; | ||||||
|             if (face >= 0 && face < GetNumberOfSides()) |             if (face >= 0 && face < GetNumberOfSides()) | ||||||
|             { |             { | ||||||
|                 texcolor = tex.CreateFace((uint)face).RGBA; |                 texcolor = tex.CreateFace((uint)face).RGBA; | ||||||
|                 texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); |                 texcolor.R = clippedColor.X; | ||||||
|                 texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); |                 texcolor.G = clippedColor.Y; | ||||||
|                 texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); |                 texcolor.B = clippedColor.Z; | ||||||
|  |                 if (alpha.HasValue) | ||||||
|  |                 { | ||||||
|  |                     texcolor.A = clippedAlpha; | ||||||
|  |                 } | ||||||
|                 tex.FaceTextures[face].RGBA = texcolor; |                 tex.FaceTextures[face].RGBA = texcolor; | ||||||
|                 UpdateTextureEntry(tex.GetBytes()); |                 UpdateTextureEntry(tex.GetBytes()); | ||||||
|                 return; |                 return; | ||||||
|  | @ -2880,15 +2888,23 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
|                     if (tex.FaceTextures[i] != null) |                     if (tex.FaceTextures[i] != null) | ||||||
|                     { |                     { | ||||||
|                         texcolor = tex.FaceTextures[i].RGBA; |                         texcolor = tex.FaceTextures[i].RGBA; | ||||||
|                         texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); |                         texcolor.R = clippedColor.X; | ||||||
|                         texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); |                         texcolor.G = clippedColor.Y; | ||||||
|                         texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); |                         texcolor.B = clippedColor.Z; | ||||||
|  |                         if (alpha.HasValue) | ||||||
|  |                         { | ||||||
|  |                             texcolor.A = clippedAlpha; | ||||||
|  |                         } | ||||||
|                         tex.FaceTextures[i].RGBA = texcolor; |                         tex.FaceTextures[i].RGBA = texcolor; | ||||||
|                     } |                     } | ||||||
|                     texcolor = tex.DefaultTexture.RGBA; |                     texcolor = tex.DefaultTexture.RGBA; | ||||||
|                     texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); |                     texcolor.R = clippedColor.X; | ||||||
|                     texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); |                     texcolor.G = clippedColor.Y; | ||||||
|                     texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); |                     texcolor.B = clippedColor.Z; | ||||||
|  |                     if (alpha.HasValue) | ||||||
|  |                     { | ||||||
|  |                         texcolor.A = clippedAlpha; | ||||||
|  |                     } | ||||||
|                     tex.DefaultTexture.RGBA = texcolor; |                     tex.DefaultTexture.RGBA = texcolor; | ||||||
|                 } |                 } | ||||||
|                 UpdateTextureEntry(tex.GetBytes()); |                 UpdateTextureEntry(tex.GetBytes()); | ||||||
|  | @ -4237,6 +4253,57 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
|             ScheduleFullUpdate(); |             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> |         /// <summary> | ||||||
|         /// If the part is a sculpt/mesh, retrieve the mesh data and reinsert it into the shape so that the physics |         /// 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. |         /// engine can use it. | ||||||
|  |  | ||||||
|  | @ -1385,17 +1385,22 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
|                 bool DCFlagKeyPressed = false; |                 bool DCFlagKeyPressed = false; | ||||||
|                 Vector3 agent_control_v3 = Vector3.Zero; |                 Vector3 agent_control_v3 = Vector3.Zero; | ||||||
| 
 | 
 | ||||||
|                 bool oldflying = Flying; |                 bool newFlying = actor.Flying; | ||||||
| 
 | 
 | ||||||
|                 if (ForceFly) |                 if (ForceFly) | ||||||
|                     actor.Flying = true; |                     newFlying = true; | ||||||
|                 else if (FlyDisabled) |                 else if (FlyDisabled) | ||||||
|                     actor.Flying = false; |                     newFlying = false; | ||||||
|                 else |                 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; |                     update_movementflag = true; | ||||||
|  |                 } | ||||||
| 
 | 
 | ||||||
|                 if (ParentID == 0) |                 if (ParentID == 0) | ||||||
|                 { |                 { | ||||||
|  |  | ||||||
|  | @ -141,7 +141,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests | ||||||
|             TestScene scene = new SceneHelpers().SetupScene(); |             TestScene scene = new SceneHelpers().SetupScene(); | ||||||
|             ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); |             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.GetScenePresence(sp.UUID), Is.Null); | ||||||
|             Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(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() |         public void Close() | ||||||
|  |         { | ||||||
|  |             Close(false); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public void Close(bool force) | ||||||
|         { |         { | ||||||
|             Disconnect(); |             Disconnect(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -43,15 +43,13 @@ using OpenSim.Region.Framework.Scenes; | ||||||
| 
 | 
 | ||||||
| namespace OpenSim.Region.OptionalModules.Avatar.Attachments | 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")] |     [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "TempAttachmentsModule")] | ||||||
|     public class TempAttachmentsModule : INonSharedRegionModule |     public class TempAttachmentsModule : INonSharedRegionModule | ||||||
|     { |     { | ||||||
|         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||||
| 
 | 
 | ||||||
|         private Scene m_scene; |         private Scene m_scene; | ||||||
|  |         private IRegionConsole m_console; | ||||||
| 
 | 
 | ||||||
|         public void Initialise(IConfigSource configSource) |         public void Initialise(IConfigSource configSource) | ||||||
|         { |         { | ||||||
|  | @ -74,6 +72,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments | ||||||
|             { |             { | ||||||
|                 comms.RegisterScriptInvocation( this, "llAttachToAvatarTemp"); |                 comms.RegisterScriptInvocation( this, "llAttachToAvatarTemp"); | ||||||
|                 m_log.DebugFormat("[TEMP ATTACHS]: Registered script functions"); |                 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 |             else | ||||||
|             { |             { | ||||||
|  | @ -95,6 +99,37 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments | ||||||
|             get { return "TempAttachmentsModule"; } |             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) |         private void llAttachToAvatarTemp(UUID host, UUID script, int attachmentPoint) | ||||||
|         { |         { | ||||||
|             SceneObjectPart hostPart = m_scene.GetSceneObjectPart(host); |             SceneObjectPart hostPart = m_scene.GetSceneObjectPart(host); | ||||||
|  |  | ||||||
|  | @ -900,6 +900,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public void Close() |         public void Close() | ||||||
|  |         { | ||||||
|  |             Close(false); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public void Close(bool force) | ||||||
|         { |         { | ||||||
|             // Remove ourselves from the scene |             // Remove ourselves from the scene | ||||||
|             m_scene.RemoveClient(AgentId, false); |             m_scene.RemoveClient(AgentId, false); | ||||||
|  |  | ||||||
|  | @ -37,7 +37,8 @@ public class BS6DofConstraint : BSConstraint | ||||||
|     // Create a btGeneric6DofConstraint |     // Create a btGeneric6DofConstraint | ||||||
|     public BS6DofConstraint(BulletSim world, BulletBody obj1, BulletBody obj2, |     public BS6DofConstraint(BulletSim world, BulletBody obj1, BulletBody obj2, | ||||||
|                     Vector3 frame1, Quaternion frame1rot, |                     Vector3 frame1, Quaternion frame1rot, | ||||||
|                     Vector3 frame2, Quaternion frame2rot ) |                     Vector3 frame2, Quaternion frame2rot, | ||||||
|  |                     bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) | ||||||
|     { |     { | ||||||
|         m_world = world; |         m_world = world; | ||||||
|         m_body1 = obj1; |         m_body1 = obj1; | ||||||
|  | @ -46,16 +47,45 @@ public class BS6DofConstraint : BSConstraint | ||||||
|                             BulletSimAPI.Create6DofConstraint2(m_world.Ptr, m_body1.Ptr, m_body2.Ptr, |                             BulletSimAPI.Create6DofConstraint2(m_world.Ptr, m_body1.Ptr, m_body2.Ptr, | ||||||
|                                 frame1, frame1rot, |                                 frame1, frame1rot, | ||||||
|                                 frame2, frame2rot, |                                 frame2, frame2rot, | ||||||
|                                 true /*useLinearReferenceFrameA*/, true /*disableCollisionsBetweenLinkedBodies*/)); |                                 useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); | ||||||
|         m_enabled = true; |         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) |     public bool SetCFMAndERP(float cfm, float erp) | ||||||
|     { |     { | ||||||
|         bool ret = true; |         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_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_STOP_ERP, erp, ConstraintParamAxis.AXIS_ALL); | ||||||
|             BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_CFM, cfm, ConstraintParamAxis.AXIS_ALL); |             BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_CFM, cfm, ConstraintParamAxis.AXIS_ALL); | ||||||
|  |             ret = true; | ||||||
|  |         } | ||||||
|         return ret; |         return ret; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -76,5 +106,13 @@ public class BS6DofConstraint : BSConstraint | ||||||
|             ret = BulletSimAPI.TranslationalLimitMotor2(m_constraint.Ptr, onOff, targetVelocity, maxMotorForce); |             ret = BulletSimAPI.TranslationalLimitMotor2(m_constraint.Ptr, onOff, targetVelocity, maxMotorForce); | ||||||
|         return ret; |         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 |         // do actual create at taint time | ||||||
|         _scene.TaintedObject("BSCharacter.create", delegate() |         _scene.TaintedObject("BSCharacter.create", delegate() | ||||||
|         { |         { | ||||||
|  |             DetailLog("{0},BSCharacter.create", _localID); | ||||||
|             BulletSimAPI.CreateObject(parent_scene.WorldID, shapeData); |             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)); |             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); |             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 |     // called when this character is being destroyed and the resources should be released | ||||||
|     public void Destroy() |     public void Destroy() | ||||||
|     { |     { | ||||||
|         // DetailLog("{0},Destroy", LocalID); |         DetailLog("{0},BSCharacter.Destroy", LocalID); | ||||||
|         _scene.TaintedObject("BSCharacter.destroy", delegate() |         _scene.TaintedObject("BSCharacter.destroy", delegate() | ||||||
|         { |         { | ||||||
|             BulletSimAPI.DestroyObject(_scene.WorldID, _localID); |             BulletSimAPI.DestroyObject(_scene.WorldID, _localID); | ||||||
|  | @ -209,7 +213,7 @@ public class BSCharacter : PhysicsActor | ||||||
| 
 | 
 | ||||||
|             _scene.TaintedObject("BSCharacter.setPosition", delegate() |             _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); |                 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); | ||||||
|             }); |             }); | ||||||
|         }  |         }  | ||||||
|  | @ -226,7 +230,7 @@ public class BSCharacter : PhysicsActor | ||||||
|         float terrainHeight = Scene.GetTerrainHeightAtXYZ(_position); |         float terrainHeight = Scene.GetTerrainHeightAtXYZ(_position); | ||||||
|         if (_position.Z < terrainHeight) |         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; |             _position.Z = terrainHeight + 2.0f; | ||||||
|             ret = true; |             ret = true; | ||||||
|         } |         } | ||||||
|  | @ -319,14 +323,13 @@ public class BSCharacter : PhysicsActor | ||||||
|     public override bool Flying {  |     public override bool Flying {  | ||||||
|         get { return _flying; }  |         get { return _flying; }  | ||||||
|         set { |         set { | ||||||
|             if (_flying != value) |  | ||||||
|             { |  | ||||||
|             _flying = value; |             _flying = value; | ||||||
|             // simulate flying by changing the effect of gravity |             // simulate flying by changing the effect of gravity | ||||||
|             this.Buoyancy = ComputeBuoyancyFromFlying(_flying); |             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) { |     private float ComputeBuoyancyFromFlying(bool ifFlying) { | ||||||
|         return ifFlying ? 1f : 0f; |         return ifFlying ? 1f : 0f; | ||||||
|     } |     } | ||||||
|  | @ -368,7 +371,7 @@ public class BSCharacter : PhysicsActor | ||||||
|         set { _buoyancy = value;  |         set { _buoyancy = value;  | ||||||
|             _scene.TaintedObject("BSCharacter.setBuoyancy", delegate() |             _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); |                 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); |             // m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force); | ||||||
|             _scene.TaintedObject("BSCharacter.AddForce", delegate() |             _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); |                 BulletSimAPI.AddObjectForce2(Body.Ptr, _force); | ||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
|  | @ -507,6 +510,7 @@ public class BSCharacter : PhysicsActor | ||||||
|         { |         { | ||||||
|             _collidingGroundStep = _scene.SimulationStep; |             _collidingGroundStep = _scene.SimulationStep; | ||||||
|         } |         } | ||||||
|  |         // DetailLog("{0},BSCharacter.Collison,call,with={1}", LocalID, collidingWith); | ||||||
| 
 | 
 | ||||||
|         // throttle collisions to the rate specified in the subscription |         // throttle collisions to the rate specified in the subscription | ||||||
|         if (_subscribedEventsMs != 0) { |         if (_subscribedEventsMs != 0) { | ||||||
|  | @ -535,7 +539,10 @@ public class BSCharacter : PhysicsActor | ||||||
|         if (collisionCollection == null) |         if (collisionCollection == null) | ||||||
|             collisionCollection = new CollisionEventUpdate(); |             collisionCollection = new CollisionEventUpdate(); | ||||||
|         base.SendCollisionUpdate(collisionCollection); |         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 |         // End kludge | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -80,10 +80,33 @@ public abstract class BSConstraint : IDisposable | ||||||
|         bool ret = false; |         bool ret = false; | ||||||
|         if (m_enabled) |         if (m_enabled) | ||||||
|         { |         { | ||||||
|  |             // Recompute the internal transforms | ||||||
|             BulletSimAPI.CalculateTransforms2(m_constraint.Ptr); |             BulletSimAPI.CalculateTransforms2(m_constraint.Ptr); | ||||||
|             ret = true; |             ret = true; | ||||||
|         } |         } | ||||||
|         return ret; |         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; | ||||||
|  |     } | ||||||
| } | } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -55,6 +55,8 @@ public class BSConstraintCollection : IDisposable | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public void Clear() |     public void Clear() | ||||||
|  |     { | ||||||
|  |         lock (m_constraints) | ||||||
|         { |         { | ||||||
|             foreach (BSConstraint cons in m_constraints) |             foreach (BSConstraint cons in m_constraints) | ||||||
|             { |             { | ||||||
|  | @ -62,15 +64,17 @@ public class BSConstraintCollection : IDisposable | ||||||
|             } |             } | ||||||
|             m_constraints.Clear(); |             m_constraints.Clear(); | ||||||
|         } |         } | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     public bool AddConstraint(BSConstraint cons) |     public bool AddConstraint(BSConstraint cons) | ||||||
|  |     { | ||||||
|  |         lock (m_constraints) | ||||||
|         { |         { | ||||||
|             // There is only one constraint between any bodies. Remove any old just to make sure. |             // There is only one constraint between any bodies. Remove any old just to make sure. | ||||||
|             RemoveAndDestroyConstraint(cons.Body1, cons.Body2); |             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; |         return true; | ||||||
|     } |     } | ||||||
|  | @ -84,16 +88,19 @@ public class BSConstraintCollection : IDisposable | ||||||
| 
 | 
 | ||||||
|         uint lookingID1 = body1.ID; |         uint lookingID1 = body1.ID; | ||||||
|         uint lookingID2 = body2.ID; |         uint lookingID2 = body2.ID; | ||||||
|         ForEachConstraint(delegate(BSConstraint constrain) |         lock (m_constraints) | ||||||
|  |         { | ||||||
|  |             foreach (BSConstraint constrain in m_constraints) | ||||||
|             { |             { | ||||||
|                 if ((constrain.Body1.ID == lookingID1 && constrain.Body2.ID == lookingID2) |                 if ((constrain.Body1.ID == lookingID1 && constrain.Body2.ID == lookingID2) | ||||||
|                     || (constrain.Body1.ID == lookingID2 && constrain.Body2.ID == lookingID1)) |                     || (constrain.Body1.ID == lookingID2 && constrain.Body2.ID == lookingID1)) | ||||||
|                 { |                 { | ||||||
|                     foundConstraint = constrain; |                     foundConstraint = constrain; | ||||||
|                     found = true; |                     found = true; | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|             return found; |  | ||||||
|         }); |  | ||||||
|         returnConstraint = foundConstraint; |         returnConstraint = foundConstraint; | ||||||
|         return found; |         return found; | ||||||
|     } |     } | ||||||
|  | @ -103,25 +110,35 @@ public class BSConstraintCollection : IDisposable | ||||||
|     // Return 'true' if a constraint was found and destroyed. |     // Return 'true' if a constraint was found and destroyed. | ||||||
|     public bool RemoveAndDestroyConstraint(BulletBody body1, BulletBody body2) |     public bool RemoveAndDestroyConstraint(BulletBody body1, BulletBody body2) | ||||||
|     { |     { | ||||||
|         // return BulletSimAPI.RemoveConstraint(m_world.ID, obj1.ID, obj2.ID); |  | ||||||
| 
 |  | ||||||
|         bool ret = false; |         bool ret = false; | ||||||
|  |         lock (m_constraints) | ||||||
|  |         { | ||||||
|             BSConstraint constrain; |             BSConstraint constrain; | ||||||
| 
 |  | ||||||
|             if (this.TryGetConstraint(body1, body2, out constrain)) |             if (this.TryGetConstraint(body1, body2, out constrain)) | ||||||
|             { |             { | ||||||
|             m_world.scene.DetailLog("{0},BSConstraintCollection.RemoveAndDestroyConstraint,taint,body1={1},body2={2}", BSScene.DetailLogZero, body1.ID, body2.ID); |  | ||||||
|                 // remove the constraint from our collection |                 // remove the constraint from our collection | ||||||
|             m_constraints.Remove(constrain); |                 RemoveAndDestroyConstraint(constrain); | ||||||
|             // tell the engine that all its structures need to be freed |  | ||||||
|             constrain.Dispose(); |  | ||||||
|             // we destroyed something |  | ||||||
|                 ret = true; |                 ret = true; | ||||||
|             } |             } | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         return ret; |         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. |     // Remove all constraints that reference the passed body. | ||||||
|     // Return 'true' if any constraints were destroyed. |     // Return 'true' if any constraints were destroyed. | ||||||
|     public bool RemoveAndDestroyConstraint(BulletBody body1) |     public bool RemoveAndDestroyConstraint(BulletBody body1) | ||||||
|  | @ -130,16 +147,15 @@ public class BSConstraintCollection : IDisposable | ||||||
| 
 | 
 | ||||||
|         List<BSConstraint> toRemove = new List<BSConstraint>(); |         List<BSConstraint> toRemove = new List<BSConstraint>(); | ||||||
|         uint lookingID = body1.ID; |         uint lookingID = body1.ID; | ||||||
|         ForEachConstraint(delegate(BSConstraint constrain) |         lock (m_constraints) | ||||||
|  |         { | ||||||
|  |             foreach (BSConstraint constrain in m_constraints) | ||||||
|             { |             { | ||||||
|                 if (constrain.Body1.ID == lookingID || constrain.Body2.ID == lookingID) |                 if (constrain.Body1.ID == lookingID || constrain.Body2.ID == lookingID) | ||||||
|                 { |                 { | ||||||
|                     toRemove.Add(constrain); |                     toRemove.Add(constrain); | ||||||
|                 } |                 } | ||||||
|             return false; |             } | ||||||
|         }); |  | ||||||
|         lock (m_constraints) |  | ||||||
|         { |  | ||||||
|             foreach (BSConstraint constrain in toRemove) |             foreach (BSConstraint constrain in toRemove) | ||||||
|             { |             { | ||||||
|                 m_constraints.Remove(constrain); |                 m_constraints.Remove(constrain); | ||||||
|  | @ -151,28 +167,16 @@ public class BSConstraintCollection : IDisposable | ||||||
| 
 | 
 | ||||||
|     public bool RecalculateAllConstraints() |     public bool RecalculateAllConstraints() | ||||||
|     { |     { | ||||||
|         ForEachConstraint(delegate(BSConstraint constrain) |         bool ret = false; | ||||||
|         { |  | ||||||
|             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) |  | ||||||
|     { |  | ||||||
|         lock (m_constraints) |         lock (m_constraints) | ||||||
|         { |         { | ||||||
|             foreach (BSConstraint constrain in m_constraints) |             foreach (BSConstraint constrain in m_constraints) | ||||||
|             { |             { | ||||||
|                 if (action(constrain)) |                 constrain.CalculateTransforms(); | ||||||
|                     break; |                 ret = true; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |         return ret; | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| } | } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -57,6 +57,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | ||||||
|         private int frcount = 0;                                        // Used to limit dynamics debug output to |         private int frcount = 0;                                        // Used to limit dynamics debug output to | ||||||
|                                                                         // every 100th frame |                                                                         // every 100th frame | ||||||
| 
 | 
 | ||||||
|  |         private BSScene m_physicsScene; | ||||||
|         private BSPrim m_prim;      // the prim this dynamic controller belongs to |         private BSPrim m_prim;      // the prim this dynamic controller belongs to | ||||||
| 
 | 
 | ||||||
|         // Vehicle properties |         // Vehicle properties | ||||||
|  | @ -74,7 +75,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin | ||||||
|                                                                         // HOVER_UP_ONLY |                                                                         // HOVER_UP_ONLY | ||||||
|                                                                         // LIMIT_MOTOR_UP |                                                                         // LIMIT_MOTOR_UP | ||||||
|                                                                         // LIMIT_ROLL_ONLY |                                                                         // LIMIT_ROLL_ONLY | ||||||
|         private VehicleFlag m_Hoverflags = (VehicleFlag)0; |  | ||||||
|         private Vector3 m_BlockingEndPoint = Vector3.Zero; |         private Vector3 m_BlockingEndPoint = Vector3.Zero; | ||||||
|         private Quaternion m_RollreferenceFrame = Quaternion.Identity; |         private Quaternion m_RollreferenceFrame = Quaternion.Identity; | ||||||
|         // Linear properties |         // Linear properties | ||||||
|  | @ -124,15 +124,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin | ||||||
|         private float m_verticalAttractionEfficiency = 1.0f;        // damped |         private float m_verticalAttractionEfficiency = 1.0f;        // damped | ||||||
|         private float m_verticalAttractionTimescale = 500f;         // Timescale > 300  means no vert attractor. |         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_prim = myPrim; | ||||||
|             m_type = Vehicle.TYPE_NONE; |             m_type = Vehicle.TYPE_NONE; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue, float timestep) |         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) |             switch (pParam) | ||||||
|             { |             { | ||||||
|                 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: |                 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: | ||||||
|  | @ -231,7 +232,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | ||||||
| 
 | 
 | ||||||
|         internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue, float timestep) |         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) |             switch (pParam) | ||||||
|             { |             { | ||||||
|                 case Vehicle.ANGULAR_FRICTION_TIMESCALE: |                 case Vehicle.ANGULAR_FRICTION_TIMESCALE: | ||||||
|  | @ -266,7 +267,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | ||||||
| 
 | 
 | ||||||
|         internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) |         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) |             switch (pParam) | ||||||
|             { |             { | ||||||
|                 case Vehicle.REFERENCE_FRAME: |                 case Vehicle.REFERENCE_FRAME: | ||||||
|  | @ -280,164 +281,27 @@ namespace OpenSim.Region.Physics.BulletSPlugin | ||||||
| 
 | 
 | ||||||
|         internal void ProcessVehicleFlags(int pParam, bool remove) |         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 (remove) | ||||||
|             { |             { | ||||||
|                 if (pParam == -1) |                 if (pParam == -1) | ||||||
|                 { |                 { | ||||||
|                     m_flags = (VehicleFlag)0; |                     m_flags = (VehicleFlag)0; | ||||||
|                     m_Hoverflags = (VehicleFlag)0; |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
|                 if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) |  | ||||||
|                 { |  | ||||||
|                     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); |  | ||||||
|                 } |  | ||||||
|                 } |                 } | ||||||
|                 else |                 else | ||||||
|                 { |                 { | ||||||
|                 if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) |                     m_flags &= ~parm; | ||||||
|                 { |  | ||||||
|                     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 |         }//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 |             // Set Defaults For Type | ||||||
|             m_type = pType; |             m_type = pType; | ||||||
|             switch (pType) |             switch (pType) | ||||||
|  | @ -478,10 +342,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin | ||||||
|                     // m_bankingMix = 1; |                     // m_bankingMix = 1; | ||||||
|                     // m_bankingTimescale = 10; |                     // m_bankingTimescale = 10; | ||||||
|                     // m_referenceFrame = Quaternion.Identity; |                     // 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_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | | ||||||
|                            VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); |                            VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); | ||||||
|                     m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP); |  | ||||||
|                     break; |                     break; | ||||||
|                 case Vehicle.TYPE_CAR: |                 case Vehicle.TYPE_CAR: | ||||||
|                     m_linearFrictionTimescale = new Vector3(100, 2, 1000); |                     m_linearFrictionTimescale = new Vector3(100, 2, 1000); | ||||||
|  | @ -506,10 +370,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin | ||||||
|                     // m_bankingMix = 1; |                     // m_bankingMix = 1; | ||||||
|                     // m_bankingTimescale = 1; |                     // m_bankingTimescale = 1; | ||||||
|                     // m_referenceFrame = Quaternion.Identity; |                     // 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 | |                     m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | | ||||||
|                                 VehicleFlag.LIMIT_MOTOR_UP); |                                 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; |                     break; | ||||||
|                 case Vehicle.TYPE_BOAT: |                 case Vehicle.TYPE_BOAT: | ||||||
|                     m_linearFrictionTimescale = new Vector3(10, 3, 2); |                     m_linearFrictionTimescale = new Vector3(10, 3, 2); | ||||||
|  | @ -534,12 +398,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin | ||||||
|                     // m_bankingMix = 0.8f; |                     // m_bankingMix = 0.8f; | ||||||
|                     // m_bankingTimescale = 1; |                     // m_bankingTimescale = 1; | ||||||
|                     // m_referenceFrame = Quaternion.Identity; |                     // m_referenceFrame = Quaternion.Identity; | ||||||
|                     m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | |                     m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | | ||||||
|                             VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); |                             VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); | ||||||
|                     m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY); |                     m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY); | ||||||
|                     m_flags |= (VehicleFlag.NO_DEFLECTION_UP | |                     m_flags |= (VehicleFlag.NO_DEFLECTION_UP | | ||||||
|                                 VehicleFlag.LIMIT_MOTOR_UP); |                                 VehicleFlag.LIMIT_MOTOR_UP); | ||||||
|                     m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY); |                     m_flags |= (VehicleFlag.HOVER_WATER_ONLY); | ||||||
|                     break; |                     break; | ||||||
|                 case Vehicle.TYPE_AIRPLANE: |                 case Vehicle.TYPE_AIRPLANE: | ||||||
|                     m_linearFrictionTimescale = new Vector3(200, 10, 5); |                     m_linearFrictionTimescale = new Vector3(200, 10, 5); | ||||||
|  | @ -564,7 +428,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | ||||||
|                     // m_bankingMix = 0.7f; |                     // m_bankingMix = 0.7f; | ||||||
|                     // m_bankingTimescale = 2; |                     // m_bankingTimescale = 2; | ||||||
|                     // m_referenceFrame = Quaternion.Identity; |                     // 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); |                         VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); | ||||||
|                     m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP); |                     m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP); | ||||||
|                     m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); |                     m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); | ||||||
|  | @ -592,11 +456,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin | ||||||
|                     // m_bankingMix = 0.7f; |                     // m_bankingMix = 0.7f; | ||||||
|                     // m_bankingTimescale = 5; |                     // m_bankingTimescale = 5; | ||||||
|                     // m_referenceFrame = Quaternion.Identity; |                     // 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); |                         VehicleFlag.HOVER_UP_ONLY); | ||||||
|                     m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP); |                     m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP); | ||||||
|                     m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); |                     m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); | ||||||
|                     m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT); |                     m_flags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT); | ||||||
|                     break; |                     break; | ||||||
|             } |             } | ||||||
|         }//end SetDefaultsForType |         }//end SetDefaultsForType | ||||||
|  | @ -613,7 +477,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | ||||||
|             MoveAngular(pTimestep); |             MoveAngular(pTimestep); | ||||||
|             LimitRotation(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); |                     m_prim.LocalID, m_prim.Position, m_prim.Force, m_prim.Velocity, m_prim.RotationalVelocity); | ||||||
|         }// end Step |         }// 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); |                     m_prim.LocalID, origDir, origVel, addAmount, decayfraction, m_linearMotorDirection, m_lastLinearVelocityVector); | ||||||
|             } |             } | ||||||
|             else |             else | ||||||
|  | @ -669,7 +533,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | ||||||
|                 m_lastLinearVelocityVector = Vector3.Zero; |                 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; |             Quaternion rotq = m_prim.Orientation; | ||||||
|             m_dir = m_lastLinearVelocityVector * rotq; |             m_dir = m_lastLinearVelocityVector * rotq; | ||||||
| 
 | 
 | ||||||
|  | @ -722,7 +586,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | ||||||
|                 if (changed) |                 if (changed) | ||||||
|                 { |                 { | ||||||
|                     m_prim.Position = pos; |                     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); |                                 m_prim.LocalID, m_BlockingEndPoint, posChange, pos); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  | @ -732,32 +596,32 @@ namespace OpenSim.Region.Physics.BulletSPlugin | ||||||
|             { |             { | ||||||
|                 pos.Z = m_prim.Scene.GetTerrainHeightAtXYZ(pos) + 2; |                 pos.Z = m_prim.Scene.GetTerrainHeightAtXYZ(pos) + 2; | ||||||
|                 m_prim.Position = pos; |                 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 |             // 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 |                 // 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; |                     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; |                     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; |                     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 body is aready heigher, use its height as target height | ||||||
|                     if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z; |                     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) |                     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_VhoverEfficiency = 0f;    // 0=boucy, 1=Crit.damped | ||||||
| //                m_VhoverTimescale = 0f;        // time to acheive height | //                m_VhoverTimescale = 0f;        // time to acheive height | ||||||
|  | @ -815,7 +679,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | ||||||
|                 { |                 { | ||||||
|                     grav.Z = (float)(grav.Z * 1.037125); |                     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 |                 //End Experimental Values | ||||||
|             } |             } | ||||||
|             if ((m_flags & (VehicleFlag.NO_X)) != 0) |             if ((m_flags & (VehicleFlag.NO_X)) != 0) | ||||||
|  | @ -844,7 +708,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | ||||||
|             Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep); |             Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep); | ||||||
|             m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount; |             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); |                         m_prim.LocalID, m_lastPositionVector, m_dir, grav, decayamount); | ||||||
| 
 | 
 | ||||||
|         } // end MoveLinear() |         } // end MoveLinear() | ||||||
|  | @ -876,7 +740,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | ||||||
|                 m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) /  (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); |                 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_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 |                 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 |                 // No motor recently applied, keep the body velocity | ||||||
|                 // and decay the velocity |                 // and decay the velocity | ||||||
|                 m_angularMotorVelocity -= m_angularMotorVelocity /  (m_angularMotorDecayTimescale / pTimestep); |                 m_angularMotorVelocity -= m_angularMotorVelocity /  (m_angularMotorDecayTimescale / pTimestep); | ||||||
|  |                 if (m_angularMotorVelocity.LengthSquared() < 0.00001) | ||||||
|  |                     m_angularMotorVelocity = Vector3.Zero; | ||||||
|             } // end motor section |             } // end motor section | ||||||
| 
 | 
 | ||||||
|             // Vertical attractor section |             // Vertical attractor section | ||||||
|  | @ -924,7 +790,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | ||||||
|                 vertattr.X += bounce * angularVelocity.X; |                 vertattr.X += bounce * angularVelocity.X; | ||||||
|                 vertattr.Y += bounce * angularVelocity.Y; |                 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); |                             m_prim.LocalID, verterr, bounce, vertattr); | ||||||
| 
 | 
 | ||||||
|             } // else vertical attractor is off |             } // else vertical attractor is off | ||||||
|  | @ -942,13 +808,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin | ||||||
|             { |             { | ||||||
|                 m_lastAngularVelocity.X = 0; |                 m_lastAngularVelocity.X = 0; | ||||||
|                 m_lastAngularVelocity.Y = 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)) |             if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) | ||||||
|             { |             { | ||||||
|                 m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. |                 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 |              // apply friction | ||||||
|  | @ -958,7 +824,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | ||||||
|             // Apply to the body |             // Apply to the body | ||||||
|             m_prim.RotationalVelocity = m_lastAngularVelocity; |             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 |         } //end MoveAngular | ||||||
| 
 | 
 | ||||||
|         internal void LimitRotation(float timestep) |         internal void LimitRotation(float timestep) | ||||||
|  | @ -1005,11 +871,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin | ||||||
|             if (changed) |             if (changed) | ||||||
|                 m_prim.Orientation = m_rot; |                 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. |         // 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) |             if (m_prim.Scene.VehicleLoggingEnabled) | ||||||
|                 m_prim.Scene.PhysicsLogging.Write(msg, args); |                 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 static string LogHeader = "[BULLETSIM LINKSET]"; | ||||||
| 
 | 
 | ||||||
|     private BSPrim m_linksetRoot; |     private BSPrim m_linksetRoot; | ||||||
|     public BSPrim Root { get { return m_linksetRoot; } } |     public BSPrim LinksetRoot { get { return m_linksetRoot; } } | ||||||
| 
 | 
 | ||||||
|     private BSScene m_scene; |     private BSScene m_physicsScene; | ||||||
|     public BSScene Scene { get { return m_scene; } } |     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; |     private List<BSPrim> m_children; | ||||||
| 
 | 
 | ||||||
|     // We lock the diddling of linkset classes to prevent any badness. |     // We lock the diddling of linkset classes to prevent any badness. | ||||||
|  | @ -73,7 +77,11 @@ public class BSLinkset | ||||||
|     public BSLinkset(BSScene scene, BSPrim parent) |     public BSLinkset(BSScene scene, BSPrim parent) | ||||||
|     { |     { | ||||||
|         // A simple linkset of one (no children) |         // 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_linksetRoot = parent; | ||||||
|         m_children = new List<BSPrim>(); |         m_children = new List<BSPrim>(); | ||||||
|         m_mass = parent.MassRaw; |         m_mass = parent.MassRaw; | ||||||
|  | @ -91,6 +99,9 @@ public class BSLinkset | ||||||
|         return this; |         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) |     public BSLinkset RemoveMeFromLinkset(BSPrim child) | ||||||
|     { |     { | ||||||
|         lock (m_linksetActivityLock) |         lock (m_linksetActivityLock) | ||||||
|  | @ -114,60 +125,9 @@ public class BSLinkset | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // The child is down to a linkset of just itself |         // 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 |     // Return 'true' if the passed object is the root object of this linkset | ||||||
|     public bool IsRoot(BSPrim requestor) |     public bool IsRoot(BSPrim requestor) | ||||||
|     { |     { | ||||||
|  | @ -183,6 +143,8 @@ public class BSLinkset | ||||||
|     public bool HasChild(BSPrim child) |     public bool HasChild(BSPrim child) | ||||||
|     { |     { | ||||||
|         bool ret = false; |         bool ret = false; | ||||||
|  |         lock (m_linksetActivityLock) | ||||||
|  |         { | ||||||
|             foreach (BSPrim bp in m_children) |             foreach (BSPrim bp in m_children) | ||||||
|             { |             { | ||||||
|                 if (child.LocalID == bp.LocalID) |                 if (child.LocalID == bp.LocalID) | ||||||
|  | @ -191,6 +153,7 @@ public class BSLinkset | ||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |         } | ||||||
|         return ret; |         return ret; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -209,6 +172,8 @@ public class BSLinkset | ||||||
|         OMV.Vector3 com = m_linksetRoot.Position * m_linksetRoot.MassRaw; |         OMV.Vector3 com = m_linksetRoot.Position * m_linksetRoot.MassRaw; | ||||||
|         float totalMass = m_linksetRoot.MassRaw; |         float totalMass = m_linksetRoot.MassRaw; | ||||||
| 
 | 
 | ||||||
|  |         lock (m_linksetActivityLock) | ||||||
|  |         { | ||||||
|             foreach (BSPrim bp in m_children) |             foreach (BSPrim bp in m_children) | ||||||
|             { |             { | ||||||
|                 com += bp.Position * bp.MassRaw; |                 com += bp.Position * bp.MassRaw; | ||||||
|  | @ -216,6 +181,7 @@ public class BSLinkset | ||||||
|             } |             } | ||||||
|             if (totalMass != 0f) |             if (totalMass != 0f) | ||||||
|                 com /= totalMass; |                 com /= totalMass; | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         return com; |         return com; | ||||||
|     } |     } | ||||||
|  | @ -224,29 +190,83 @@ public class BSLinkset | ||||||
|     { |     { | ||||||
|         OMV.Vector3 com = m_linksetRoot.Position; |         OMV.Vector3 com = m_linksetRoot.Position; | ||||||
| 
 | 
 | ||||||
|  |         lock (m_linksetActivityLock) | ||||||
|  |         { | ||||||
|             foreach (BSPrim bp in m_children) |             foreach (BSPrim bp in m_children) | ||||||
|             { |             { | ||||||
|                 com += bp.Position * bp.MassRaw; |                 com += bp.Position * bp.MassRaw; | ||||||
|             } |             } | ||||||
|             com /= (m_children.Count + 1); |             com /= (m_children.Count + 1); | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         return com; |         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 |     // I am the root of a linkset and a new child is being added | ||||||
|     // Called while LinkActivity is locked. |     // Called while LinkActivity is locked. | ||||||
|     public void AddChildToLinkset(BSPrim child) |     private void AddChildToLinkset(BSPrim child) | ||||||
|     { |     { | ||||||
|         if (!HasChild(child)) |         if (!HasChild(child)) | ||||||
|         { |         { | ||||||
|             m_children.Add(child); |             m_children.Add(child); | ||||||
| 
 | 
 | ||||||
|             BSPrim root = Root; // capture the root as of now |             BSPrim rootx = LinksetRoot; // capture the root as of now | ||||||
|             m_scene.TaintedObject("AddChildToLinkset", delegate() |             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); |                 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; |         return; | ||||||
|  | @ -257,31 +277,33 @@ public class BSLinkset | ||||||
|     //    it's still connected to the linkset. |     //    it's still connected to the linkset. | ||||||
|     // Normal OpenSimulator operation will never do this because other SceneObjectPart information |     // Normal OpenSimulator operation will never do this because other SceneObjectPart information | ||||||
|     //    has to be updated also (like pointer to prim's parent). |     //    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); |         RemoveChildFromLinkset(pchild); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // I am the root of a linkset and one of my children is being removed. |     // 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. |     // 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)) |         if (m_children.Remove(child)) | ||||||
|         { |         { | ||||||
|             BSPrim root = Root; // capture the root as of now |             BSPrim rootx = LinksetRoot; // capture the root as of now | ||||||
|             m_scene.TaintedObject("RemoveChildFromLinkset", delegate() |             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); |                 DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID); | ||||||
| 
 | 
 | ||||||
|                 PhysicallyUnlinkAChildFromRoot(root, child); |                 PhysicallyUnlinkAChildFromRoot(rootx, childx); | ||||||
|             }); |             }); | ||||||
|  | 
 | ||||||
|  |             RecomputeLinksetConstraintVariables(); | ||||||
|         } |         } | ||||||
|         else |         else | ||||||
|         { |         { | ||||||
|             // This will happen if we remove the root of the linkset first. Non-fatal occurance. |             // 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; |         return; | ||||||
|     } |     } | ||||||
|  | @ -293,48 +315,81 @@ public class BSLinkset | ||||||
|         // Zero motion for children so they don't interpolate |         // Zero motion for children so they don't interpolate | ||||||
|         childPrim.ZeroMotion(); |         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 |         // relative position normalized to the root prim | ||||||
|         OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation); |         OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation); | ||||||
|         OMV.Vector3 childRelativePosition = (childPrim.Position - rootPrim.Position) * invThisOrientation; |         OMV.Vector3 childRelativePosition = (childPrim.Position - rootPrim.Position) * invThisOrientation; | ||||||
| 
 | 
 | ||||||
|         // relative rotation of the child to the parent |         // relative rotation of the child to the parent | ||||||
|         OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation; |         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 |         // create a constraint that allows no freedom of movement between the two objects | ||||||
|         // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 |         // 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); |         DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); | ||||||
|         BS6DofConstraint constrain = new BS6DofConstraint( |         BS6DofConstraint constrain = new BS6DofConstraint( | ||||||
|                         m_scene.World, rootPrim.Body, childPrim.Body, |                         PhysicsScene.World, rootPrim.Body, childPrim.Body, | ||||||
|                         childRelativePosition, |  | ||||||
|                         childRelativeRotation, |  | ||||||
|                         OMV.Vector3.Zero, |                         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 |         // 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.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); | ||||||
|         constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); |         constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); | ||||||
| 
 | 
 | ||||||
|         // tweek the constraint to increase stability |         // tweek the constraint to increase stability | ||||||
|         constrain.UseFrameOffset(m_scene.BoolNumeric(m_scene.Params.linkConstraintUseFrameOffset)); |         constrain.UseFrameOffset(PhysicsScene.BoolNumeric(PhysicsScene.Params.linkConstraintUseFrameOffset)); | ||||||
|         constrain.TranslationalLimitMotor(m_scene.BoolNumeric(m_scene.Params.linkConstraintEnableTransMotor), |         constrain.TranslationalLimitMotor(PhysicsScene.BoolNumeric(PhysicsScene.Params.linkConstraintEnableTransMotor), | ||||||
|                         m_scene.Params.linkConstraintTransMotorMaxVel, |                         PhysicsScene.Params.linkConstraintTransMotorMaxVel, | ||||||
|                         m_scene.Params.linkConstraintTransMotorMaxForce); |                         PhysicsScene.Params.linkConstraintTransMotorMaxForce); | ||||||
|         constrain.SetCFMAndERP(m_scene.Params.linkConstraintCFM, m_scene.Params.linkConstraintERP); |         constrain.SetCFMAndERP(PhysicsScene.Params.linkConstraintCFM, PhysicsScene.Params.linkConstraintERP); | ||||||
| 
 | 
 | ||||||
|  |         RecomputeLinksetConstraintVariables(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Remove linkage between myself and a particular child |     // Remove linkage between myself and a particular child | ||||||
|     // Called at taint time! |     // Called at taint time! | ||||||
|     private void PhysicallyUnlinkAChildFromRoot(BSPrim rootPrim, BSPrim childPrim) |     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); |         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 |         // Make the child refresh its location | ||||||
|         BulletSimAPI.PushUpdate2(childPrim.Body.Ptr); |         BulletSimAPI.PushUpdate2(childPrim.Body.Ptr); | ||||||
|     } |     } | ||||||
|  | @ -343,23 +398,15 @@ public class BSLinkset | ||||||
|     // Called at taint time! |     // Called at taint time! | ||||||
|     private void PhysicallyUnlinkAllChildrenFromRoot(BSPrim rootPrim) |     private void PhysicallyUnlinkAllChildrenFromRoot(BSPrim rootPrim) | ||||||
|     { |     { | ||||||
|         // DebugLog("{0}: PhysicallyUnlinkAllChildren:", LogHeader); |  | ||||||
|         DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); |         DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); | ||||||
| 
 | 
 | ||||||
|         m_scene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body); |         m_physicsScene.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); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Invoke the detailed logger and output something if it's enabled. |     // Invoke the detailed logger and output something if it's enabled. | ||||||
|     private void DetailLog(string msg, params Object[] args) |     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 ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||||
|     private static readonly string LogHeader = "[BULLETS PRIM]"; |     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 IMesh _mesh; | ||||||
|     private PrimitiveBaseShape _pbs; |     private PrimitiveBaseShape _pbs; | ||||||
|     private ShapeData.PhysicsShapeType _shapeType; |     private ShapeData.PhysicsShapeType _shapeType; | ||||||
|  | @ -141,8 +139,8 @@ public sealed class BSPrim : PhysicsActor | ||||||
|         _friction = _scene.Params.defaultFriction;  // TODO: compute based on object material |         _friction = _scene.Params.defaultFriction;  // TODO: compute based on object material | ||||||
|         _density = _scene.Params.defaultDensity;    // TODO: compute based on object material |         _density = _scene.Params.defaultDensity;    // TODO: compute based on object material | ||||||
|         _restitution = _scene.Params.defaultRestitution; |         _restitution = _scene.Params.defaultRestitution; | ||||||
|         _linkset = new BSLinkset(_scene, this);     // a linkset of one |         _linkset = new BSLinkset(Scene, this);     // a linkset of one | ||||||
|         _vehicle = new BSDynamics(this);            // add vehicleness |         _vehicle = new BSDynamics(Scene, this);            // add vehicleness | ||||||
|         _mass = CalculateMass(); |         _mass = CalculateMass(); | ||||||
|         // do the actual object creation at taint time |         // do the actual object creation at taint time | ||||||
|         DetailLog("{0},BSPrim.constructor,call", LocalID); |         DetailLog("{0},BSPrim.constructor,call", LocalID); | ||||||
|  | @ -163,13 +161,13 @@ public sealed class BSPrim : PhysicsActor | ||||||
|         // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); |         // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); | ||||||
| 
 | 
 | ||||||
|         // Undo any links between me and any other object |         // Undo any links between me and any other object | ||||||
|         BSPrim parentBefore = _linkset.Root; |         BSPrim parentBefore = _linkset.LinksetRoot; | ||||||
|         int childrenBefore = _linkset.NumberOfChildren; |         int childrenBefore = _linkset.NumberOfChildren; | ||||||
| 
 | 
 | ||||||
|         _linkset = _linkset.RemoveMeFromLinkset(this); |         _linkset = _linkset.RemoveMeFromLinkset(this); | ||||||
| 
 | 
 | ||||||
|         DetailLog("{0},BSPrim.Destroy,call,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}", |         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 |         // Undo any vehicle properties | ||||||
|         this.VehicleType = (int)Vehicle.TYPE_NONE; |         this.VehicleType = (int)Vehicle.TYPE_NONE; | ||||||
|  | @ -193,7 +191,7 @@ public sealed class BSPrim : PhysicsActor | ||||||
|             { |             { | ||||||
|                 _mass = CalculateMass();   // changing size changes the mass |                 _mass = CalculateMass();   // changing size changes the mass | ||||||
|                 BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical); |                 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(); |                 RecreateGeomAndObject(); | ||||||
|             }); |             }); | ||||||
|         }  |         }  | ||||||
|  | @ -232,14 +230,13 @@ public sealed class BSPrim : PhysicsActor | ||||||
|         BSPrim parent = obj as BSPrim; |         BSPrim parent = obj as BSPrim; | ||||||
|         if (parent != null) |         if (parent != null) | ||||||
|         { |         { | ||||||
|             DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, parent.LocalID); |             BSPrim parentBefore = _linkset.LinksetRoot; | ||||||
|             BSPrim parentBefore = _linkset.Root; |  | ||||||
|             int childrenBefore = _linkset.NumberOfChildren; |             int childrenBefore = _linkset.NumberOfChildren; | ||||||
| 
 | 
 | ||||||
|             _linkset = parent.Linkset.AddMeToLinkset(this); |             _linkset = parent.Linkset.AddMeToLinkset(this); | ||||||
| 
 | 
 | ||||||
|             DetailLog("{0},BSPrim.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}",  |             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;  |         return;  | ||||||
|     } |     } | ||||||
|  | @ -248,16 +245,14 @@ public sealed class BSPrim : PhysicsActor | ||||||
|     public override void delink() { |     public override void delink() { | ||||||
|         // TODO: decide if this parent checking needs to happen at taint time |         // 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 |         // 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; |         int childrenBefore = _linkset.NumberOfChildren; | ||||||
|          |          | ||||||
|         _linkset = _linkset.RemoveMeFromLinkset(this); |         _linkset = _linkset.RemoveMeFromLinkset(this); | ||||||
| 
 | 
 | ||||||
|         DetailLog("{0},BSPrim.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ",  |         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;  |         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 |                 // 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 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. |                 // Tell the scene about the vehicle so it will get processing each frame. | ||||||
|                 _scene.VehicleInSceneTypeChanged(this, type); |                 _scene.VehicleInSceneTypeChanged(this, type); | ||||||
|             }); |             }); | ||||||
|  | @ -486,17 +481,17 @@ public sealed class BSPrim : PhysicsActor | ||||||
|     // No locking here because only called when it is safe |     // No locking here because only called when it is safe | ||||||
|     private void SetObjectDynamic() |     private void SetObjectDynamic() | ||||||
|     { |     { | ||||||
|         // RA: remove this for the moment. |         // If it's becoming dynamic, it will need hullness | ||||||
|         // The problem is that dynamic objects are hulls so if we are becoming physical |         VerifyCorrectPhysicalShape(); | ||||||
|         //    the shape has to be checked and possibly built. |  | ||||||
|         //    Maybe a VerifyCorrectPhysicalShape() routine? |  | ||||||
|         // RecreateGeomAndObject(); |  | ||||||
| 
 | 
 | ||||||
|         // Bullet wants static objects to have a mass of zero |         // Bullet wants static objects to have a mass of zero | ||||||
|         float mass = IsStatic ? 0f : _mass; |         float mass = IsStatic ? 0f : _mass; | ||||||
| 
 | 
 | ||||||
|         BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass); |         BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass); | ||||||
| 
 | 
 | ||||||
|  |         // recompute any linkset parameters | ||||||
|  |         _linkset.Refresh(this); | ||||||
|  | 
 | ||||||
|         CollisionFlags cf = BulletSimAPI.GetCollisionFlags2(Body.Ptr); |         CollisionFlags cf = BulletSimAPI.GetCollisionFlags2(Body.Ptr); | ||||||
|         DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, cf); |         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 |     // prims don't fly | ||||||
|     public override bool Flying {  |     public override bool Flying {  | ||||||
|         get { return _flying; }  |         get { return _flying; }  | ||||||
|         set { _flying = value; }  |         set { | ||||||
|  |             _flying = value; | ||||||
|  |         }  | ||||||
|     } |     } | ||||||
|     public override bool SetAlwaysRun {  |     public override bool SetAlwaysRun {  | ||||||
|         get { return _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 |     // No locking here because this is done when we know physics is not simulating | ||||||
|     private void CreateGeomMesh() |     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); |         ulong newMeshKey = (ulong)_pbs.GetMeshKey(_size, lod); | ||||||
|         // m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey); |         // 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 the hull hasn't changed, don't rebuild it | ||||||
|         if (newHullKey == _hullKey) return; |         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 |         // Since we're recreating new, get rid of any previously generated shape | ||||||
|         if (_hullKey != 0) |         if (_hullKey != 0) | ||||||
|         { |         { | ||||||
|             // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey); |             // 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); |             BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey); | ||||||
|             _hullKey = 0; |             _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; |         _hullKey = newHullKey; | ||||||
|         if (_meshKey != _hullKey) | 
 | ||||||
|         { |         // Make sure the underlying mesh exists and is correct | ||||||
|             // if the underlying mesh has changed, rebuild it |  | ||||||
|         CreateGeomMesh(); |         CreateGeomMesh(); | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         int[] indices = _mesh.getIndexListAsInt(); |         int[] indices = _mesh.getIndexListAsInt(); | ||||||
|         List<OMV.Vector3> vertices = _mesh.getVertexList(); |         List<OMV.Vector3> vertices = _mesh.getVertexList(); | ||||||
|  | @ -1142,7 +1139,7 @@ public sealed class BSPrim : PhysicsActor | ||||||
|         // create the hull into the _hulls variable |         // create the hull into the _hulls variable | ||||||
|         convexBuilder.process(dcomp); |         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 hull information is passed as a large floating point array.  | ||||||
|         // The format is: |         // The format is: | ||||||
|         //  convHulls[0] = number of hulls |         //  convHulls[0] = number of hulls | ||||||
|  | @ -1214,6 +1211,27 @@ public sealed class BSPrim : PhysicsActor | ||||||
|         return; |         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 |     // 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 |     // No locking here because this is done when the physics engine is not simulating | ||||||
|     // Returns 'true' if an object was actually created. |     // Returns 'true' if an object was actually created. | ||||||
|  | @ -1338,13 +1356,12 @@ public sealed class BSPrim : PhysicsActor | ||||||
|             _acceleration = entprop.Acceleration; |             _acceleration = entprop.Acceleration; | ||||||
|             _rotationalVelocity = entprop.RotationalVelocity; |             _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}", |             DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", | ||||||
|                     LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); |                     LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); | ||||||
| 
 | 
 | ||||||
|             base.RequestPhysicsterseUpdate(); |             base.RequestPhysicsterseUpdate(); | ||||||
|         } |         } | ||||||
|  |             /* | ||||||
|         else |         else | ||||||
|         { |         { | ||||||
|             // For debugging, we also report the movement of children |             // 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,  |                     LocalID, entprop.Position, entprop.Rotation, entprop.Velocity,  | ||||||
|                     entprop.Acceleration, entprop.RotationalVelocity); |                     entprop.Acceleration, entprop.RotationalVelocity); | ||||||
|         } |         } | ||||||
|  |              */ | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // I've collided with something |     // 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) |     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); |         // 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; |             _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 someone is subscribed to collision events.... | ||||||
|         if (_subscribedEventsMs != 0) { |         if (_subscribedEventsMs != 0) { | ||||||
|             // throttle the collisions to the number of milliseconds specified in the subscription |             // 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) |         if (collisionCollection != null && collisionCollection.Count > 0) | ||||||
|         { |         { | ||||||
|             base.SendCollisionUpdate(collisionCollection); |             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 ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||||||
|     private static readonly string LogHeader = "[BULLETS SCENE]"; |     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 = "?"; |     public string BulletSimVersion = "?"; | ||||||
| 
 | 
 | ||||||
|     private Dictionary<uint, BSCharacter> m_avatars = new Dictionary<uint, BSCharacter>(); |     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>(); |     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<BSCharacter> m_avatarsWithCollisions = new HashSet<BSCharacter>(); | ||||||
|     private HashSet<BSPrim> m_primsWithCollisions = new HashSet<BSPrim>(); |     private HashSet<BSPrim> m_primsWithCollisions = new HashSet<BSPrim>(); | ||||||
|  | 
 | ||||||
|     private List<BSPrim> m_vehicles = new List<BSPrim>(); |     private List<BSPrim> m_vehicles = new List<BSPrim>(); | ||||||
|  | 
 | ||||||
|     private float[] m_heightMap; |     private float[] m_heightMap; | ||||||
|     private float m_waterLevel; |     private float m_waterLevel; | ||||||
|     private uint m_worldID; |     private uint m_worldID; | ||||||
|  | @ -95,16 +102,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters | ||||||
|     private int m_detailedStatsStep = 0; |     private int m_detailedStatsStep = 0; | ||||||
| 
 | 
 | ||||||
|     public IMesher mesher; |     public IMesher mesher; | ||||||
|     private float m_meshLOD; |     // Level of Detail values kept as float because that's what the Meshmerizer wants | ||||||
|     public float MeshLOD |     public float MeshLOD { get; private set; } | ||||||
|     { |     public float MeshMegaPrimLOD { get; private set; } | ||||||
|         get { return m_meshLOD; } |     public float MeshMegaPrimThreshold { get; private set; } | ||||||
|     } |     public float SculptLOD { get; private set; } | ||||||
|     private float m_sculptLOD; |  | ||||||
|     public float SculptLOD |  | ||||||
|     { |  | ||||||
|         get { return m_sculptLOD; } |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     private BulletSim m_worldSim; |     private BulletSim m_worldSim; | ||||||
|     public BulletSim World |     public BulletSim World | ||||||
|  | @ -179,8 +181,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters | ||||||
|     ConfigurationParameters[] m_params; |     ConfigurationParameters[] m_params; | ||||||
|     GCHandle m_paramsHandle; |     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; |     private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle; | ||||||
| 
 | 
 | ||||||
|     // Sometimes you just have to log everything. |     // Sometimes you just have to log everything. | ||||||
|  | @ -196,6 +199,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters | ||||||
|     public BSScene(string identifier) |     public BSScene(string identifier) | ||||||
|     { |     { | ||||||
|         m_initialized = false; |         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) |     public override void Initialise(IMesher meshmerizer, IConfigSource config) | ||||||
|  | @ -281,10 +286,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters | ||||||
|                 // Very detailed logging for physics debugging |                 // Very detailed logging for physics debugging | ||||||
|                 m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false); |                 m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false); | ||||||
|                 m_physicsLoggingDir = pConfig.GetString("PhysicsLoggingDir", "."); |                 m_physicsLoggingDir = pConfig.GetString("PhysicsLoggingDir", "."); | ||||||
|                 m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-"); |                 m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-%REGIONNAME%-"); | ||||||
|                 m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5); |                 m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5); | ||||||
|                 // Very detailed logging for vehicle debugging |                 // Very detailed logging for vehicle debugging | ||||||
|                 m_vehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false); |                 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 |         // prevent simulation until we've been initialized | ||||||
|         if (!m_initialized) return 10.0f; |         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 |         // update the prim states while we know the physics engine is not busy | ||||||
|         ProcessTaints(); |         ProcessTaints(); | ||||||
|  | @ -434,8 +442,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters | ||||||
|         catch (Exception e) |         catch (Exception e) | ||||||
|         { |         { | ||||||
|             m_log.WarnFormat("{0},PhysicsStep Exception: substeps={1}, updates={2}, colliders={3}, e={4}", LogHeader, numSubSteps, updatedEntityCount, collidersCount, 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); |             // DetailLog("{0},PhysicsStepException,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount); | ||||||
|             // updatedEntityCount = 0; |             updatedEntityCount = 0; | ||||||
|             collidersCount = 0; |             collidersCount = 0; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -511,8 +519,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters | ||||||
|         // long simulateTotalTime = Util.EnvironmentTickCountSubtract(simulateStartTime); |         // long simulateTotalTime = Util.EnvironmentTickCountSubtract(simulateStartTime); | ||||||
|         // return (timeStep * (float)simulateTotalTime); |         // return (timeStep * (float)simulateTotalTime); | ||||||
| 
 | 
 | ||||||
|         // TODO: FIX THIS: fps calculation wrong. This calculation always returns about 1 in normal operation. |         // TODO: FIX THIS: fps calculation possibly wrong. | ||||||
|         return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f; |         // 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 |     // Something has collided | ||||||
|  | @ -529,6 +542,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters | ||||||
|         else if (m_avatars.ContainsKey(collidingWith)) |         else if (m_avatars.ContainsKey(collidingWith)) | ||||||
|             type = ActorTypes.Agent; |             type = ActorTypes.Agent; | ||||||
| 
 | 
 | ||||||
|  |         // DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith); | ||||||
|  | 
 | ||||||
|         BSPrim prim; |         BSPrim prim; | ||||||
|         if (m_prims.TryGetValue(localID, out prim)) { |         if (m_prims.TryGetValue(localID, out prim)) { | ||||||
|             prim.Collide(collidingWith, type, collidePoint, collideNormal, penitration); |             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 |         // make sure no stepping happens while we're deleting stuff | ||||||
|         m_initialized = false; |         m_initialized = false; | ||||||
| 
 | 
 | ||||||
|         if (m_constraintCollection != null) |  | ||||||
|         { |  | ||||||
|             m_constraintCollection.Dispose(); |  | ||||||
|             m_constraintCollection = null; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         foreach (KeyValuePair<uint, BSCharacter> kvp in m_avatars) |         foreach (KeyValuePair<uint, BSCharacter> kvp in m_avatars) | ||||||
|         { |         { | ||||||
|             kvp.Value.Destroy(); |             kvp.Value.Destroy(); | ||||||
|  | @ -608,6 +617,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters | ||||||
|         } |         } | ||||||
|         m_prims.Clear(); |         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 |         // Anything left in the unmanaged code should be cleaned out | ||||||
|         BulletSimAPI.Shutdown(WorldID); |         BulletSimAPI.Shutdown(WorldID); | ||||||
| 
 | 
 | ||||||
|  | @ -891,16 +907,26 @@ public class BSScene : PhysicsScene, IPhysicsParameters | ||||||
|             (s) => { return s.NumericBool(s._forceSimplePrimMeshing); }, |             (s) => { return s.NumericBool(s._forceSimplePrimMeshing); }, | ||||||
|             (s,p,l,v) => { s._forceSimplePrimMeshing = s.BoolNumeric(v); } ), |             (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, |             8f, | ||||||
|             (s,cf,p,v) => { s.m_meshLOD = cf.GetInt(p, (int)v); }, |             (s,cf,p,v) => { s.MeshLOD = (float)cf.GetInt(p, (int)v); }, | ||||||
|             (s) => { return (float)s.m_meshLOD; }, |             (s) => { return s.MeshLOD; }, | ||||||
|             (s,p,l,v) => { s.m_meshLOD = (int)v; } ), |             (s,p,l,v) => { s.MeshLOD = v; } ), | ||||||
|         new ParameterDefn("SculptLOD", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)", |         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, |             32f, | ||||||
|             (s,cf,p,v) => { s.m_sculptLOD = cf.GetInt(p, (int)v); }, |             (s,cf,p,v) => { s.SculptLOD = (float)cf.GetInt(p, (int)v); }, | ||||||
|             (s) => { return (float)s.m_sculptLOD; }, |             (s) => { return s.SculptLOD; }, | ||||||
|             (s,p,l,v) => { s.m_sculptLOD = (int)v; } ), |             (s,p,l,v) => { s.SculptLOD = v; } ), | ||||||
| 
 | 
 | ||||||
|         new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps", |         new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps", | ||||||
|             10f, |             10f, | ||||||
|  | @ -1131,12 +1157,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters | ||||||
|             (s,cf,p,v) => { s.m_detailedStatsStep = cf.GetInt(p, (int)v); }, |             (s,cf,p,v) => { s.m_detailedStatsStep = cf.GetInt(p, (int)v); }, | ||||||
|             (s) => { return (float)s.m_detailedStatsStep; }, |             (s) => { return (float)s.m_detailedStatsStep; }, | ||||||
|             (s,p,l,v) => { s.m_detailedStatsStep = (int)v; } ), |             (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 |     // 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, |                     Vector3 frame2loc, Quaternion frame2rot, | ||||||
|                     bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); |                     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] | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||||||
| public static extern bool SetLinearLimits2(IntPtr constrain, Vector3 low, Vector3 hi); | 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] | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||||||
| public static extern bool TranslationalLimitMotor2(IntPtr constrain, float enable, float targetVel, float maxMotorForce); | 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] | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||||||
| public static extern bool CalculateTransforms2(IntPtr constrain); | 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] | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||||||
| public static extern IntPtr ClearForces2(IntPtr obj); | 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] | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||||||
| public static extern bool SetMargin2(IntPtr obj, float val); | 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) |         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>(); |             List<SceneObjectPart> ret = new List<SceneObjectPart>(); | ||||||
|             ret.Add(m_host); |             ret.Add(part); | ||||||
| 
 | 
 | ||||||
|             switch (linkType) |             switch (linkType) | ||||||
|             { |             { | ||||||
|             case ScriptBaseClass.LINK_SET: |             case ScriptBaseClass.LINK_SET: | ||||||
|                 return new List<SceneObjectPart>(m_host.ParentGroup.Parts); |                 return new List<SceneObjectPart>(part.ParentGroup.Parts); | ||||||
| 
 | 
 | ||||||
|             case ScriptBaseClass.LINK_ROOT: |             case ScriptBaseClass.LINK_ROOT: | ||||||
|                 ret = new List<SceneObjectPart>(); |                 ret = new List<SceneObjectPart>(); | ||||||
|                 ret.Add(m_host.ParentGroup.RootPart); |                 ret.Add(part.ParentGroup.RootPart); | ||||||
|                 return ret; |                 return ret; | ||||||
| 
 | 
 | ||||||
|             case ScriptBaseClass.LINK_ALL_OTHERS: |             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)) |                 if (ret.Contains(part)) | ||||||
|                     ret.Remove(m_host); |                     ret.Remove(part); | ||||||
| 
 | 
 | ||||||
|                 return ret; |                 return ret; | ||||||
| 
 | 
 | ||||||
|             case ScriptBaseClass.LINK_ALL_CHILDREN: |             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)) |                 if (ret.Contains(part.ParentGroup.RootPart)) | ||||||
|                     ret.Remove(m_host.ParentGroup.RootPart); |                     ret.Remove(part.ParentGroup.RootPart); | ||||||
|                 return ret; |                 return ret; | ||||||
| 
 | 
 | ||||||
|             case ScriptBaseClass.LINK_THIS: |             case ScriptBaseClass.LINK_THIS: | ||||||
|  | @ -279,7 +284,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|                 if (linkType < 0) |                 if (linkType < 0) | ||||||
|                     return new List<SceneObjectPart>(); |                     return new List<SceneObjectPart>(); | ||||||
| 
 | 
 | ||||||
|                 SceneObjectPart target = m_host.ParentGroup.GetLinkNumPart(linkType); |                 SceneObjectPart target = part.ParentGroup.GetLinkNumPart(linkType); | ||||||
|                 if (target == null) |                 if (target == null) | ||||||
|                     return new List<SceneObjectPart>(); |                     return new List<SceneObjectPart>(); | ||||||
|                 ret = new List<SceneObjectPart>(); |                 ret = new List<SceneObjectPart>(); | ||||||
|  | @ -325,14 +330,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|             return key; |             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. |         //These are the implementations of the various ll-functions used by the LSL scripts. | ||||||
|         public LSL_Float llSin(double f) |         public LSL_Float llSin(double f) | ||||||
|         { |         { | ||||||
|  | @ -1092,9 +1089,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|         public LSL_Float llGround(LSL_Vector offset) |         public LSL_Float llGround(LSL_Vector offset) | ||||||
|         { |         { | ||||||
|             m_host.AddScriptLPS(1); |             m_host.AddScriptLPS(1); | ||||||
|             Vector3 pos = m_host.GetWorldPosition() + new Vector3((float)offset.x, |             Vector3 pos = m_host.GetWorldPosition() + (Vector3)offset; | ||||||
|                                                                   (float)offset.y, |  | ||||||
|                                                                   (float)offset.z); |  | ||||||
| 
 | 
 | ||||||
|             //Get the slope normal.  This gives us the equation of the plane tangent to the slope. |             //Get the slope normal.  This gives us the equation of the plane tangent to the slope. | ||||||
|             LSL_Vector vsn = llGroundNormal(offset); |             LSL_Vector vsn = llGroundNormal(offset); | ||||||
|  | @ -1338,31 +1333,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|             if (part == null || part.ParentGroup.IsDeleted) |             if (part == null || part.ParentGroup.IsDeleted) | ||||||
|                 return; |                 return; | ||||||
| 
 | 
 | ||||||
|             if (scale.x < 0.01) |             // First we need to check whether or not we need to clamp the size of a physics-enabled prim | ||||||
|                 scale.x = 0.01; |  | ||||||
|             if (scale.y < 0.01) |  | ||||||
|                 scale.y = 0.01; |  | ||||||
|             if (scale.z < 0.01) |  | ||||||
|                 scale.z = 0.01; |  | ||||||
| 
 |  | ||||||
|             PhysicsActor pa = part.ParentGroup.RootPart.PhysActor; |             PhysicsActor pa = part.ParentGroup.RootPart.PhysActor; | ||||||
| 
 |  | ||||||
|             if (pa != null && pa.IsPhysical) |             if (pa != null && pa.IsPhysical) | ||||||
|             { |             { | ||||||
|                 if (scale.x > World.m_maxPhys) |                 scale.x = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.x)); | ||||||
|                     scale.x = World.m_maxPhys; |                 scale.y = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.y)); | ||||||
|                 if (scale.y > World.m_maxPhys) |                 scale.z = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.z)); | ||||||
|                     scale.y = World.m_maxPhys; |  | ||||||
|                 if (scale.z > World.m_maxPhys) |  | ||||||
|                     scale.z = World.m_maxPhys; |  | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (scale.x > World.m_maxNonphys) |             // Next we clamp the scale to the non-physical min/max | ||||||
|                 scale.x = World.m_maxNonphys; |             scale.x = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.x)); | ||||||
|             if (scale.y > World.m_maxNonphys) |             scale.y = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.y)); | ||||||
|                 scale.y = World.m_maxNonphys; |             scale.z = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.z)); | ||||||
|             if (scale.z > World.m_maxNonphys) |  | ||||||
|                 scale.z = World.m_maxNonphys; |  | ||||||
| 
 | 
 | ||||||
|             Vector3 tmp = part.Scale; |             Vector3 tmp = part.Scale; | ||||||
|             tmp.X = (float)scale.x; |             tmp.X = (float)scale.x; | ||||||
|  | @ -1394,7 +1377,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|             if (face == ScriptBaseClass.ALL_SIDES) |             if (face == ScriptBaseClass.ALL_SIDES) | ||||||
|                 face = SceneObjectPart.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) |         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; |             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; |                 return 0; | ||||||
|             } |             } | ||||||
|  | @ -2041,13 +2025,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|                 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) |                 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) | ||||||
|                     targetPos.z = ground; |                     targetPos.z = ground; | ||||||
|                 SceneObjectGroup parent = part.ParentGroup; |                 SceneObjectGroup parent = part.ParentGroup; | ||||||
|                 LSL_Vector real_vec = !adjust ? targetPos : SetPosAdjust(currentPos, targetPos); |                 parent.UpdateGroupPosition(!adjust ? targetPos : | ||||||
|                 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z)); |                     SetPosAdjust(currentPos, targetPos)); | ||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|                 LSL_Vector rel_vec = !adjust ? targetPos : SetPosAdjust(currentPos, targetPos); |                 part.OffsetPosition = !adjust ? targetPos : | ||||||
|                 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z); |                     SetPosAdjust(currentPos, targetPos); | ||||||
|                 SceneObjectGroup parent = part.ParentGroup; |                 SceneObjectGroup parent = part.ParentGroup; | ||||||
|                 parent.HasGroupChanged = true; |                 parent.HasGroupChanged = true; | ||||||
|                 parent.ScheduleGroupForTerseUpdate(); |                 parent.ScheduleGroupForTerseUpdate(); | ||||||
|  | @ -2091,7 +2075,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
| 
 | 
 | ||||||
| //            m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); | //            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) |         public void llSetRot(LSL_Rotation rot) | ||||||
|  | @ -2102,7 +2086,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|             if (m_host.ParentID == 0) |             if (m_host.ParentID == 0) | ||||||
|             { |             { | ||||||
|                 // special case: If we are root, rotate complete SOG to new rotation |                 // special case: If we are root, rotate complete SOG to new rotation | ||||||
|                 SetRot(m_host, Rot2Quaternion(rot)); |                 SetRot(m_host, rot); | ||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|  | @ -2110,7 +2094,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|                 SceneObjectPart rootPart = m_host.ParentGroup.RootPart; |                 SceneObjectPart rootPart = m_host.ParentGroup.RootPart; | ||||||
|                 if (rootPart != null) // better safe than sorry |                 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) |         public void llSetLocalRot(LSL_Rotation rot) | ||||||
|         { |         { | ||||||
|             m_host.AddScriptLPS(1); |             m_host.AddScriptLPS(1); | ||||||
|             SetRot(m_host, Rot2Quaternion(rot)); |             SetRot(m_host, rot); | ||||||
|             ScriptSleep(200); |             ScriptSleep(200); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -2205,7 +2189,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|                 if (local != 0) |                 if (local != 0) | ||||||
|                     force *= llGetRot(); |                     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) |             if (!m_host.ParentGroup.IsDeleted) | ||||||
|             { |             { | ||||||
|                 Vector3 tmpForce = m_host.ParentGroup.RootPart.GetForce(); |                 force = m_host.ParentGroup.RootPart.GetForce(); | ||||||
|                 force.x = tmpForce.X; |  | ||||||
|                 force.y = tmpForce.Y; |  | ||||||
|                 force.z = tmpForce.Z; |  | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             return force; |             return force; | ||||||
|  | @ -2229,8 +2210,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|         public LSL_Integer llTarget(LSL_Vector position, double range) |         public LSL_Integer llTarget(LSL_Vector position, double range) | ||||||
|         { |         { | ||||||
|             m_host.AddScriptLPS(1); |             m_host.AddScriptLPS(1); | ||||||
|             return m_host.ParentGroup.registerTargetWaypoint( |             return m_host.ParentGroup.registerTargetWaypoint(position, | ||||||
|                 new Vector3((float)position.x, (float)position.y, (float)position.z), (float)range); |                 (float)range); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public void llTargetRemove(int number) |         public void llTargetRemove(int number) | ||||||
|  | @ -2242,8 +2223,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|         public LSL_Integer llRotTarget(LSL_Rotation rot, double error) |         public LSL_Integer llRotTarget(LSL_Rotation rot, double error) | ||||||
|         { |         { | ||||||
|             m_host.AddScriptLPS(1); |             m_host.AddScriptLPS(1); | ||||||
|             return m_host.ParentGroup.registerRotTargetWaypoint( |             return m_host.ParentGroup.registerRotTargetWaypoint(rot, (float)error); | ||||||
|                 new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s), (float)error); |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public void llRotTargetRemove(int number) |         public void llRotTargetRemove(int number) | ||||||
|  | @ -2255,7 +2235,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|         public void llMoveToTarget(LSL_Vector target, double tau) |         public void llMoveToTarget(LSL_Vector target, double tau) | ||||||
|         { |         { | ||||||
|             m_host.AddScriptLPS(1); |             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() |         public void llStopMoveToTarget() | ||||||
|  | @ -2268,7 +2248,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|         { |         { | ||||||
|             m_host.AddScriptLPS(1); |             m_host.AddScriptLPS(1); | ||||||
|             //No energy force yet |             //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) |             if (v.Length() > 20000.0f) | ||||||
|             { |             { | ||||||
|                 v.Normalize(); |                 v.Normalize(); | ||||||
|  | @ -2280,13 +2260,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|         public void llApplyRotationalImpulse(LSL_Vector force, int local) |         public void llApplyRotationalImpulse(LSL_Vector force, int local) | ||||||
|         { |         { | ||||||
|             m_host.AddScriptLPS(1); |             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) |         public void llSetTorque(LSL_Vector torque, int local) | ||||||
|         { |         { | ||||||
|             m_host.AddScriptLPS(1); |             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() |         public LSL_Vector llGetTorque() | ||||||
|  | @ -2837,13 +2817,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|                     return; |                     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 |                 // need the magnitude later | ||||||
|                 // float velmag = (float)Util.GetMagnitude(llvel); |                 // 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 either of these are null, then there was an unknown error. | ||||||
|                 if (new_group == null) |                 if (new_group == null) | ||||||
|  | @ -2864,10 +2841,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
| 
 | 
 | ||||||
|                 PhysicsActor pa = new_group.RootPart.PhysActor; |                 PhysicsActor pa = new_group.RootPart.PhysActor; | ||||||
| 
 | 
 | ||||||
|                 if (pa != null && pa.IsPhysical && llvel != Vector3.Zero) |                 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) | ||||||
|                 { |                 { | ||||||
|                     //Recoil. |                     //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) |                 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) | ||||||
|             }); |             }); | ||||||
|  | @ -2912,7 +2889,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|             } |             } | ||||||
|             else |             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 |             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) |         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() |         public LSL_Integer llGetStartParameter() | ||||||
|  | @ -3424,37 +3401,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
| 
 | 
 | ||||||
|             m_host.AddScriptLPS(1); |             m_host.AddScriptLPS(1); | ||||||
| 
 | 
 | ||||||
|  |             int implicitPerms = 0; | ||||||
|  | 
 | ||||||
|             if (m_host.ParentGroup.IsAttachment && (UUID)agent == m_host.ParentGroup.AttachedAvatar) |             if (m_host.ParentGroup.IsAttachment && (UUID)agent == m_host.ParentGroup.AttachedAvatar) | ||||||
|             { |             { | ||||||
|                 // When attached, certain permissions are implicit if requested from owner |                 // 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_TRIGGER_ANIMATION | | ||||||
|                         ScriptBaseClass.PERMISSION_CONTROL_CAMERA | |                         ScriptBaseClass.PERMISSION_CONTROL_CAMERA | | ||||||
|                         ScriptBaseClass.PERMISSION_ATTACH; |                         ScriptBaseClass.PERMISSION_ATTACH; | ||||||
| 
 |             } | ||||||
|                 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms |             else | ||||||
|             { |             { | ||||||
|                     lock (m_host.TaskInventory) |                 bool sitting = false; | ||||||
|  |                 if (m_host.SitTargetAvatar == agentID) | ||||||
|                 { |                 { | ||||||
|                         m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; |                     sitting = true; | ||||||
|                         m_host.TaskInventory[m_item.ItemID].PermsMask = perm; |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     foreach (SceneObjectPart p in m_host.ParentGroup.Parts) | ||||||
|  |                     { | ||||||
|  |                         if (p.SitTargetAvatar == agentID) | ||||||
|  |                             sitting = true; | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                     m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( |                 if (sitting) | ||||||
|                             "run_time_permissions", new Object[] { |  | ||||||
|                             new LSL_Integer(perm) }, |  | ||||||
|                             new DetectParams[0])); |  | ||||||
| 
 |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             else if (m_host.SitTargetAvatar == agentID) // Sitting avatar |  | ||||||
|                 { |                 { | ||||||
|                     // When agent is sitting, certain permissions are implicit if requested from sitting agent |                     // When agent is sitting, certain permissions are implicit if requested from sitting agent | ||||||
|                 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | |                     implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | | ||||||
|                         ScriptBaseClass.PERMISSION_CONTROL_CAMERA | |                         ScriptBaseClass.PERMISSION_CONTROL_CAMERA | | ||||||
|                         ScriptBaseClass.PERMISSION_TRACK_CAMERA | |                         ScriptBaseClass.PERMISSION_TRACK_CAMERA | | ||||||
|                         ScriptBaseClass.PERMISSION_TAKE_CONTROLS; |                         ScriptBaseClass.PERMISSION_TAKE_CONTROLS; | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     if (World.GetExtraSetting("auto_grant_attach_perms") == "true") | ||||||
|  |                         implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms |             if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms | ||||||
|             { |             { | ||||||
|  | @ -3471,7 +3457,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
| 
 | 
 | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|             } |  | ||||||
| 
 | 
 | ||||||
|             ScenePresence presence = World.GetScenePresence(agentID); |             ScenePresence presence = World.GetScenePresence(agentID); | ||||||
|             if (presence != null) |             if (presence != null) | ||||||
|  | @ -3587,7 +3572,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|             List<SceneObjectPart> parts = GetLinkParts(linknumber); |             List<SceneObjectPart> parts = GetLinkParts(linknumber); | ||||||
| 
 | 
 | ||||||
|             foreach (SceneObjectPart part in parts) |             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) |         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) |         public void llSetText(string text, LSL_Vector color, double alpha) | ||||||
|         { |         { | ||||||
|             m_host.AddScriptLPS(1); |             m_host.AddScriptLPS(1); | ||||||
|             Vector3 av3 = new Vector3(Util.Clip((float)color.x, 0.0f, 1.0f), |             Vector3 av3 = Util.Clip(color, 0.0f, 1.0f); | ||||||
|                                       Util.Clip((float)color.y, 0.0f, 1.0f), |  | ||||||
|                                       Util.Clip((float)color.z, 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.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.HasGroupChanged = true; | ||||||
|             //m_host.ParentGroup.ScheduleGroupForFullUpdate(); |             //m_host.ParentGroup.ScheduleGroupForFullUpdate(); | ||||||
|  | @ -4217,14 +4200,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|             ScriptSleep(5000); |             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); |             m_host.AddScriptLPS(1); | ||||||
|             UUID agentId = new UUID(); |             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)) |             if (UUID.TryParse(agent, out agentId)) | ||||||
|             { |             { | ||||||
|                 ScenePresence presence = World.GetScenePresence(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); |             m_host.AddScriptLPS(1); | ||||||
|             UUID agentId = new UUID(); |             UUID agentId = new UUID(); | ||||||
| 
 | 
 | ||||||
|             ulong regionHandle = Utils.UIntsToLong((uint)global_coords.x, (uint)global_coords.y); |             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)) |             if (UUID.TryParse(agent, out agentId)) | ||||||
|             { |             { | ||||||
|                 ScenePresence presence = World.GetScenePresence(agentId); |                 ScenePresence presence = World.GetScenePresence(agentId); | ||||||
|  | @ -4545,7 +4523,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|                     distance_attenuation = 1f / normalized_units; |                     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(); |                     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 |             //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. |             //the height of that point on the plane.  The resulting vector gives the slope. | ||||||
|             Vector3 vsl = new Vector3(); |             Vector3 vsl = vsn; | ||||||
|             vsl.X = (float)vsn.x; |  | ||||||
|             vsl.Y = (float)vsn.y; |  | ||||||
|             vsl.Z = (float)(((vsn.x * vsn.x) + (vsn.y * vsn.y)) / (-1 * vsn.z)); |             vsl.Z = (float)(((vsn.x * vsn.x) + (vsn.y * vsn.y)) / (-1 * vsn.z)); | ||||||
|             vsl.Normalize(); |             vsl.Normalize(); | ||||||
|             //Normalization might be overkill here |             //Normalization might be overkill here | ||||||
|  | @ -6057,9 +6033,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|         public LSL_Vector llGroundNormal(LSL_Vector offset) |         public LSL_Vector llGroundNormal(LSL_Vector offset) | ||||||
|         { |         { | ||||||
|             m_host.AddScriptLPS(1); |             m_host.AddScriptLPS(1); | ||||||
|             Vector3 pos = m_host.GetWorldPosition() + new Vector3((float)offset.x, |             Vector3 pos = m_host.GetWorldPosition() + (Vector3)offset; | ||||||
|                                                                 (float)offset.y, |  | ||||||
|                                                                 (float)offset.z); |  | ||||||
|             // Clamp to valid position |             // Clamp to valid position | ||||||
|             if (pos.X < 0) |             if (pos.X < 0) | ||||||
|                 pos.X = 0; |                 pos.X = 0; | ||||||
|  | @ -6512,8 +6486,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
| 
 | 
 | ||||||
|             if (!m_host.ParentGroup.IsDeleted) |             if (!m_host.ParentGroup.IsDeleted) | ||||||
|             { |             { | ||||||
|                 m_host.ParentGroup.RootPart.SetVehicleVectorParam(param, |                 m_host.ParentGroup.RootPart.SetVehicleVectorParam(param, vec); | ||||||
|                     new Vector3((float)vec.x, (float)vec.y, (float)vec.z)); |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -6525,7 +6498,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
| 
 | 
 | ||||||
|             if (!m_host.ParentGroup.IsDeleted) |             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) |         protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) | ||||||
|         { |         { | ||||||
|             // LSL quaternions can normalize to 0, normal Quaternions can't. |             part.SitTargetPosition = offset; | ||||||
|             if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0) |             part.SitTargetOrientation = rot; | ||||||
|                 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.ParentGroup.HasGroupChanged = true; |             part.ParentGroup.HasGroupChanged = true; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -6659,13 +6628,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|         public void llSetCameraEyeOffset(LSL_Vector offset) |         public void llSetCameraEyeOffset(LSL_Vector offset) | ||||||
|         { |         { | ||||||
|             m_host.AddScriptLPS(1); |             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) |         public void llSetCameraAtOffset(LSL_Vector offset) | ||||||
|         { |         { | ||||||
|             m_host.AddScriptLPS(1); |             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) |         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) |         public LSL_Integer llScriptDanger(LSL_Vector pos) | ||||||
|         { |         { | ||||||
|             m_host.AddScriptLPS(1); |             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) |             if (result) | ||||||
|             { |             { | ||||||
|                 return 1; |                 return 1; | ||||||
|  | @ -7246,7 +7215,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|         public void llSetPrimitiveParams(LSL_List rules) |         public void llSetPrimitiveParams(LSL_List rules) | ||||||
|         { |         { | ||||||
|             m_host.AddScriptLPS(1); |             m_host.AddScriptLPS(1); | ||||||
|             SetPrimParams(m_host, rules); | 
 | ||||||
|  |             setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules); | ||||||
| 
 | 
 | ||||||
|             ScriptSleep(200); |             ScriptSleep(200); | ||||||
|         } |         } | ||||||
|  | @ -7271,11 +7241,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|         { |         { | ||||||
|             List<SceneObjectPart> parts = GetLinkParts(linknumber); |             List<SceneObjectPart> parts = GetLinkParts(linknumber); | ||||||
| 
 | 
 | ||||||
|  |             LSL_List remaining = null; | ||||||
|  | 
 | ||||||
|             foreach (SceneObjectPart part in parts) |             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; |             int idx = 0; | ||||||
| 
 | 
 | ||||||
|  | @ -7298,7 +7280,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|                         case (int)ScriptBaseClass.PRIM_POSITION: |                         case (int)ScriptBaseClass.PRIM_POSITION: | ||||||
|                         case (int)ScriptBaseClass.PRIM_POS_LOCAL: |                         case (int)ScriptBaseClass.PRIM_POS_LOCAL: | ||||||
|                             if (remain < 1) |                             if (remain < 1) | ||||||
|                                 return; |                                 return null; | ||||||
| 
 | 
 | ||||||
|                             v=rules.GetVector3Item(idx++); |                             v=rules.GetVector3Item(idx++); | ||||||
|                             positionChanged = true; |                             positionChanged = true; | ||||||
|  | @ -7307,7 +7289,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|                             break; |                             break; | ||||||
|                         case (int)ScriptBaseClass.PRIM_SIZE: |                         case (int)ScriptBaseClass.PRIM_SIZE: | ||||||
|                             if (remain < 1) |                             if (remain < 1) | ||||||
|                                 return; |                                 return null; | ||||||
| 
 | 
 | ||||||
|                             v=rules.GetVector3Item(idx++); |                             v=rules.GetVector3Item(idx++); | ||||||
|                             SetScale(part, v); |                             SetScale(part, v); | ||||||
|  | @ -7315,27 +7297,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|                             break; |                             break; | ||||||
|                         case (int)ScriptBaseClass.PRIM_ROTATION: |                         case (int)ScriptBaseClass.PRIM_ROTATION: | ||||||
|                             if (remain < 1) |                             if (remain < 1) | ||||||
|                                 return; |                                 return null; | ||||||
| 
 | 
 | ||||||
|                             LSL_Rotation q = rules.GetQuaternionItem(idx++); |                             LSL_Rotation q = rules.GetQuaternionItem(idx++); | ||||||
|                             // try to let this work as in SL... |                             // try to let this work as in SL... | ||||||
|                             if (part.ParentID == 0) |                             if (part.ParentID == 0) | ||||||
|                             { |                             { | ||||||
|                                 // special case: If we are root, rotate complete SOG to new rotation |                                 // special case: If we are root, rotate complete SOG to new rotation | ||||||
|                                 SetRot(part, Rot2Quaternion(q)); |                                 SetRot(part, q); | ||||||
|                             } |                             } | ||||||
|                             else |                             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. |                                 // 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; |                                 SceneObjectPart rootPart = part.ParentGroup.RootPart; | ||||||
|                                 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q)); |                                 SetRot(part, rootPart.RotationOffset * (Quaternion)q); | ||||||
|                             } |                             } | ||||||
| 
 | 
 | ||||||
|                             break; |                             break; | ||||||
| 
 | 
 | ||||||
|                         case (int)ScriptBaseClass.PRIM_TYPE: |                         case (int)ScriptBaseClass.PRIM_TYPE: | ||||||
|                             if (remain < 3) |                             if (remain < 3) | ||||||
|                                 return; |                                 return null; | ||||||
| 
 | 
 | ||||||
|                             code = (int)rules.GetLSLIntegerItem(idx++); |                             code = (int)rules.GetLSLIntegerItem(idx++); | ||||||
| 
 | 
 | ||||||
|  | @ -7354,7 +7336,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|                             { |                             { | ||||||
|                                 case (int)ScriptBaseClass.PRIM_TYPE_BOX: |                                 case (int)ScriptBaseClass.PRIM_TYPE_BOX: | ||||||
|                                     if (remain < 6) |                                     if (remain < 6) | ||||||
|                                         return; |                                         return null; | ||||||
| 
 | 
 | ||||||
|                                     face = (int)rules.GetLSLIntegerItem(idx++); |                                     face = (int)rules.GetLSLIntegerItem(idx++); | ||||||
|                                     v = rules.GetVector3Item(idx++); // cut |                                     v = rules.GetVector3Item(idx++); // cut | ||||||
|  | @ -7369,7 +7351,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
| 
 | 
 | ||||||
|                                 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER: |                                 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER: | ||||||
|                                     if (remain < 6) |                                     if (remain < 6) | ||||||
|                                         return; |                                         return null; | ||||||
| 
 | 
 | ||||||
|                                     face = (int)rules.GetLSLIntegerItem(idx++); // holeshape |                                     face = (int)rules.GetLSLIntegerItem(idx++); // holeshape | ||||||
|                                     v = rules.GetVector3Item(idx++); // cut |                                     v = rules.GetVector3Item(idx++); // cut | ||||||
|  | @ -7383,7 +7365,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
| 
 | 
 | ||||||
|                                 case (int)ScriptBaseClass.PRIM_TYPE_PRISM: |                                 case (int)ScriptBaseClass.PRIM_TYPE_PRISM: | ||||||
|                                     if (remain < 6) |                                     if (remain < 6) | ||||||
|                                         return; |                                         return null; | ||||||
| 
 | 
 | ||||||
|                                     face = (int)rules.GetLSLIntegerItem(idx++); // holeshape |                                     face = (int)rules.GetLSLIntegerItem(idx++); // holeshape | ||||||
|                                     v = rules.GetVector3Item(idx++); //cut |                                     v = rules.GetVector3Item(idx++); //cut | ||||||
|  | @ -7397,7 +7379,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
| 
 | 
 | ||||||
|                                 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE: |                                 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE: | ||||||
|                                     if (remain < 5) |                                     if (remain < 5) | ||||||
|                                         return; |                                         return null; | ||||||
| 
 | 
 | ||||||
|                                     face = (int)rules.GetLSLIntegerItem(idx++); // holeshape |                                     face = (int)rules.GetLSLIntegerItem(idx++); // holeshape | ||||||
|                                     v = rules.GetVector3Item(idx++); // cut |                                     v = rules.GetVector3Item(idx++); // cut | ||||||
|  | @ -7410,7 +7392,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
| 
 | 
 | ||||||
|                                 case (int)ScriptBaseClass.PRIM_TYPE_TORUS: |                                 case (int)ScriptBaseClass.PRIM_TYPE_TORUS: | ||||||
|                                     if (remain < 11) |                                     if (remain < 11) | ||||||
|                                         return; |                                         return null; | ||||||
| 
 | 
 | ||||||
|                                     face = (int)rules.GetLSLIntegerItem(idx++); // holeshape |                                     face = (int)rules.GetLSLIntegerItem(idx++); // holeshape | ||||||
|                                     v = rules.GetVector3Item(idx++); //cut |                                     v = rules.GetVector3Item(idx++); //cut | ||||||
|  | @ -7429,7 +7411,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
| 
 | 
 | ||||||
|                                 case (int)ScriptBaseClass.PRIM_TYPE_TUBE: |                                 case (int)ScriptBaseClass.PRIM_TYPE_TUBE: | ||||||
|                                     if (remain < 11) |                                     if (remain < 11) | ||||||
|                                         return; |                                         return null; | ||||||
| 
 | 
 | ||||||
|                                     face = (int)rules.GetLSLIntegerItem(idx++); // holeshape |                                     face = (int)rules.GetLSLIntegerItem(idx++); // holeshape | ||||||
|                                     v = rules.GetVector3Item(idx++); //cut |                                     v = rules.GetVector3Item(idx++); //cut | ||||||
|  | @ -7448,7 +7430,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
| 
 | 
 | ||||||
|                                 case (int)ScriptBaseClass.PRIM_TYPE_RING: |                                 case (int)ScriptBaseClass.PRIM_TYPE_RING: | ||||||
|                                     if (remain < 11) |                                     if (remain < 11) | ||||||
|                                         return; |                                         return null; | ||||||
| 
 | 
 | ||||||
|                                     face = (int)rules.GetLSLIntegerItem(idx++); // holeshape |                                     face = (int)rules.GetLSLIntegerItem(idx++); // holeshape | ||||||
|                                     v = rules.GetVector3Item(idx++); //cut |                                     v = rules.GetVector3Item(idx++); //cut | ||||||
|  | @ -7467,7 +7449,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
| 
 | 
 | ||||||
|                                 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT: |                                 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT: | ||||||
|                                     if (remain < 2) |                                     if (remain < 2) | ||||||
|                                         return; |                                         return null; | ||||||
| 
 | 
 | ||||||
|                                     string map = rules.Data[idx++].ToString(); |                                     string map = rules.Data[idx++].ToString(); | ||||||
|                                     face = (int)rules.GetLSLIntegerItem(idx++); // type |                                     face = (int)rules.GetLSLIntegerItem(idx++); // type | ||||||
|  | @ -7479,7 +7461,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
| 
 | 
 | ||||||
|                         case (int)ScriptBaseClass.PRIM_TEXTURE: |                         case (int)ScriptBaseClass.PRIM_TEXTURE: | ||||||
|                             if (remain < 5) |                             if (remain < 5) | ||||||
|                                 return; |                                 return null; | ||||||
| 
 | 
 | ||||||
|                             face=(int)rules.GetLSLIntegerItem(idx++); |                             face=(int)rules.GetLSLIntegerItem(idx++); | ||||||
|                             string tex=rules.Data[idx++].ToString(); |                             string tex=rules.Data[idx++].ToString(); | ||||||
|  | @ -7496,20 +7478,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
| 
 | 
 | ||||||
|                         case (int)ScriptBaseClass.PRIM_COLOR: |                         case (int)ScriptBaseClass.PRIM_COLOR: | ||||||
|                             if (remain < 3) |                             if (remain < 3) | ||||||
|                                 return; |                                 return null; | ||||||
| 
 | 
 | ||||||
|                             face=(int)rules.GetLSLIntegerItem(idx++); |                             face=(int)rules.GetLSLIntegerItem(idx++); | ||||||
|                             LSL_Vector color=rules.GetVector3Item(idx++); |                             LSL_Vector color=rules.GetVector3Item(idx++); | ||||||
|                             double alpha=(double)rules.GetLSLFloatItem(idx++); |                             double alpha=(double)rules.GetLSLFloatItem(idx++); | ||||||
| 
 | 
 | ||||||
|                             part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); |                             part.SetFaceColorAlpha(face, color, alpha); | ||||||
|                             SetAlpha(part, alpha, face); |  | ||||||
| 
 | 
 | ||||||
|                             break; |                             break; | ||||||
| 
 | 
 | ||||||
|                         case (int)ScriptBaseClass.PRIM_FLEXIBLE: |                         case (int)ScriptBaseClass.PRIM_FLEXIBLE: | ||||||
|                             if (remain < 7) |                             if (remain < 7) | ||||||
|                                 return; |                                 return null; | ||||||
| 
 | 
 | ||||||
|                             bool flexi = rules.GetLSLIntegerItem(idx++); |                             bool flexi = rules.GetLSLIntegerItem(idx++); | ||||||
|                             int softness = rules.GetLSLIntegerItem(idx++); |                             int softness = rules.GetLSLIntegerItem(idx++); | ||||||
|  | @ -7525,7 +7506,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
| 
 | 
 | ||||||
|                         case (int)ScriptBaseClass.PRIM_POINT_LIGHT: |                         case (int)ScriptBaseClass.PRIM_POINT_LIGHT: | ||||||
|                             if (remain < 5) |                             if (remain < 5) | ||||||
|                                 return; |                                 return null; | ||||||
|                             bool light = rules.GetLSLIntegerItem(idx++); |                             bool light = rules.GetLSLIntegerItem(idx++); | ||||||
|                             LSL_Vector lightcolor = rules.GetVector3Item(idx++); |                             LSL_Vector lightcolor = rules.GetVector3Item(idx++); | ||||||
|                             float intensity = (float)rules.GetLSLFloatItem(idx++); |                             float intensity = (float)rules.GetLSLFloatItem(idx++); | ||||||
|  | @ -7538,7 +7519,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
| 
 | 
 | ||||||
|                         case (int)ScriptBaseClass.PRIM_GLOW: |                         case (int)ScriptBaseClass.PRIM_GLOW: | ||||||
|                             if (remain < 2) |                             if (remain < 2) | ||||||
|                                 return; |                                 return null; | ||||||
|                             face = rules.GetLSLIntegerItem(idx++); |                             face = rules.GetLSLIntegerItem(idx++); | ||||||
|                             float glow = (float)rules.GetLSLFloatItem(idx++); |                             float glow = (float)rules.GetLSLFloatItem(idx++); | ||||||
| 
 | 
 | ||||||
|  | @ -7548,7 +7529,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
| 
 | 
 | ||||||
|                         case (int)ScriptBaseClass.PRIM_BUMP_SHINY: |                         case (int)ScriptBaseClass.PRIM_BUMP_SHINY: | ||||||
|                             if (remain < 3) |                             if (remain < 3) | ||||||
|                                 return; |                                 return null; | ||||||
|                             face = (int)rules.GetLSLIntegerItem(idx++); |                             face = (int)rules.GetLSLIntegerItem(idx++); | ||||||
|                             int shiny = (int)rules.GetLSLIntegerItem(idx++); |                             int shiny = (int)rules.GetLSLIntegerItem(idx++); | ||||||
|                             Bumpiness bump = (Bumpiness)(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: |                          case (int)ScriptBaseClass.PRIM_FULLBRIGHT: | ||||||
|                              if (remain < 2) |                              if (remain < 2) | ||||||
|                                  return; |                                  return null; | ||||||
|                              face = rules.GetLSLIntegerItem(idx++); |                              face = rules.GetLSLIntegerItem(idx++); | ||||||
|                              bool st = rules.GetLSLIntegerItem(idx++); |                              bool st = rules.GetLSLIntegerItem(idx++); | ||||||
|                              SetFullBright(part, face , st); |                              SetFullBright(part, face , st); | ||||||
|  | @ -7567,17 +7548,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
| 
 | 
 | ||||||
|                          case (int)ScriptBaseClass.PRIM_MATERIAL: |                          case (int)ScriptBaseClass.PRIM_MATERIAL: | ||||||
|                              if (remain < 1) |                              if (remain < 1) | ||||||
|                                  return; |                                  return null; | ||||||
|                              int mat = rules.GetLSLIntegerItem(idx++); |                              int mat = rules.GetLSLIntegerItem(idx++); | ||||||
|                              if (mat < 0 || mat > 7) |                              if (mat < 0 || mat > 7) | ||||||
|                                  return; |                                  return null; | ||||||
| 
 | 
 | ||||||
|                              part.Material = Convert.ToByte(mat); |                              part.Material = Convert.ToByte(mat); | ||||||
|                              break; |                              break; | ||||||
| 
 | 
 | ||||||
|                          case (int)ScriptBaseClass.PRIM_PHANTOM: |                          case (int)ScriptBaseClass.PRIM_PHANTOM: | ||||||
|                              if (remain < 1) |                              if (remain < 1) | ||||||
|                                  return; |                                  return null; | ||||||
| 
 | 
 | ||||||
|                              string ph = rules.Data[idx++].ToString(); |                              string ph = rules.Data[idx++].ToString(); | ||||||
|                              m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); |                              m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); | ||||||
|  | @ -7586,7 +7567,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
| 
 | 
 | ||||||
|                          case (int)ScriptBaseClass.PRIM_PHYSICS: |                          case (int)ScriptBaseClass.PRIM_PHYSICS: | ||||||
|                             if (remain < 1) |                             if (remain < 1) | ||||||
|                                  return; |                                  return null; | ||||||
|                              string phy = rules.Data[idx++].ToString(); |                              string phy = rules.Data[idx++].ToString(); | ||||||
|                              bool physics; |                              bool physics; | ||||||
| 
 | 
 | ||||||
|  | @ -7600,7 +7581,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
| 
 | 
 | ||||||
|                         case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: |                         case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: | ||||||
|                             if (remain < 1) |                             if (remain < 1) | ||||||
|                                 return; |                                 return null; | ||||||
|                             string temp = rules.Data[idx++].ToString(); |                             string temp = rules.Data[idx++].ToString(); | ||||||
| 
 | 
 | ||||||
|                             m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); |                             m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); | ||||||
|  | @ -7609,7 +7590,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
| 
 | 
 | ||||||
|                         case (int)ScriptBaseClass.PRIM_TEXGEN: |                         case (int)ScriptBaseClass.PRIM_TEXGEN: | ||||||
|                             if (remain < 2) |                             if (remain < 2) | ||||||
|                                 return; |                                 return null; | ||||||
|                                 //face,type |                                 //face,type | ||||||
|                             face = rules.GetLSLIntegerItem(idx++); |                             face = rules.GetLSLIntegerItem(idx++); | ||||||
|                             int style = rules.GetLSLIntegerItem(idx++); |                             int style = rules.GetLSLIntegerItem(idx++); | ||||||
|  | @ -7617,53 +7598,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|                             break; |                             break; | ||||||
|                         case (int)ScriptBaseClass.PRIM_TEXT: |                         case (int)ScriptBaseClass.PRIM_TEXT: | ||||||
|                             if (remain < 3) |                             if (remain < 3) | ||||||
|                                 return; |                                 return null; | ||||||
|                             string primText = rules.GetLSLStringItem(idx++); |                             string primText = rules.GetLSLStringItem(idx++); | ||||||
|                             LSL_Vector primTextColor = rules.GetVector3Item(idx++); |                             LSL_Vector primTextColor = rules.GetVector3Item(idx++); | ||||||
|                             LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++); |                             LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++); | ||||||
|                             Vector3 av3 = new Vector3(Util.Clip((float)primTextColor.x, 0.0f, 1.0f), |                             Vector3 av3 = Util.Clip(primTextColor, 0.0f, 1.0f); | ||||||
|                                           Util.Clip((float)primTextColor.y, 0.0f, 1.0f), |  | ||||||
|                                           Util.Clip((float)primTextColor.z, 0.0f, 1.0f)); |  | ||||||
|                             part.SetText(primText, av3, Util.Clip((float)primTextAlpha, 0.0f, 1.0f)); |                             part.SetText(primText, av3, Util.Clip((float)primTextAlpha, 0.0f, 1.0f)); | ||||||
| 
 | 
 | ||||||
|                             break; |                             break; | ||||||
|                         case (int)ScriptBaseClass.PRIM_NAME: |                         case (int)ScriptBaseClass.PRIM_NAME: | ||||||
|                             if (remain < 1) |                             if (remain < 1) | ||||||
|                                 return; |                                 return null; | ||||||
|                             string primName = rules.GetLSLStringItem(idx++); |                             string primName = rules.GetLSLStringItem(idx++); | ||||||
|                             part.Name = primName; |                             part.Name = primName; | ||||||
|                             break; |                             break; | ||||||
|                         case (int)ScriptBaseClass.PRIM_DESC: |                         case (int)ScriptBaseClass.PRIM_DESC: | ||||||
|                             if (remain < 1) |                             if (remain < 1) | ||||||
|                                 return; |                                 return null; | ||||||
|                             string primDesc = rules.GetLSLStringItem(idx++); |                             string primDesc = rules.GetLSLStringItem(idx++); | ||||||
|                             part.Description = primDesc; |                             part.Description = primDesc; | ||||||
|                             break; |                             break; | ||||||
|                         case (int)ScriptBaseClass.PRIM_ROT_LOCAL: |                         case (int)ScriptBaseClass.PRIM_ROT_LOCAL: | ||||||
|                             if (remain < 1) |                             if (remain < 1) | ||||||
|                                 return; |                                 return null; | ||||||
|                             LSL_Rotation lr = rules.GetQuaternionItem(idx++); |                             SetRot(part, rules.GetQuaternionItem(idx++)); | ||||||
|                             SetRot(part, Rot2Quaternion(lr)); |  | ||||||
|                             break; |                             break; | ||||||
|                         case (int)ScriptBaseClass.PRIM_OMEGA: |                         case (int)ScriptBaseClass.PRIM_OMEGA: | ||||||
|                             if (remain < 3) |                             if (remain < 3) | ||||||
|                                 return; |                                 return null; | ||||||
|                             LSL_Vector axis = rules.GetVector3Item(idx++); |                             LSL_Vector axis = rules.GetVector3Item(idx++); | ||||||
|                             LSL_Float spinrate = rules.GetLSLFloatItem(idx++); |                             LSL_Float spinrate = rules.GetLSLFloatItem(idx++); | ||||||
|                             LSL_Float gain = rules.GetLSLFloatItem(idx++); |                             LSL_Float gain = rules.GetLSLFloatItem(idx++); | ||||||
|                             TargetOmega(part, axis, (double)spinrate, (double)gain); |                             TargetOmega(part, axis, (double)spinrate, (double)gain); | ||||||
|                             break; |                             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: |                         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. |                             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; |                                 return null; | ||||||
|                             LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++); |  | ||||||
|                             LSL_List new_rules = rules.GetSublist(idx, -1); |  | ||||||
|                             setLinkPrimParams((int)new_linknumber, new_rules); |  | ||||||
| 
 | 
 | ||||||
|                             return; |                             return rules.GetSublist(idx, -1); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |             catch (InvalidCastException e) | ||||||
|  |             { | ||||||
|  |                 ShoutError(e.Message); | ||||||
|  |             } | ||||||
|             finally |             finally | ||||||
|             { |             { | ||||||
|                 if (positionChanged) |                 if (positionChanged) | ||||||
|  | @ -7671,17 +7656,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|                     if (part.ParentGroup.RootPart == part) |                     if (part.ParentGroup.RootPart == part) | ||||||
|                     { |                     { | ||||||
|                         SceneObjectGroup parent = part.ParentGroup; |                         SceneObjectGroup parent = part.ParentGroup; | ||||||
|                         parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); |                         parent.UpdateGroupPosition(currentPosition); | ||||||
|                     } |                     } | ||||||
|                     else |                     else | ||||||
|                     { |                     { | ||||||
|                         part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z); |                         part.OffsetPosition = currentPosition; | ||||||
|                         SceneObjectGroup parent = part.ParentGroup; |                         SceneObjectGroup parent = part.ParentGroup; | ||||||
|                         parent.HasGroupChanged = true; |                         parent.HasGroupChanged = true; | ||||||
|                         parent.ScheduleGroupForTerseUpdate(); |                         parent.ScheduleGroupForTerseUpdate(); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |             return null; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public LSL_String llStringToBase64(string str) |         public LSL_String llStringToBase64(string str) | ||||||
|  | @ -7911,8 +7897,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|             if (part != null) |             if (part != null) | ||||||
|             { |             { | ||||||
|                 Vector3 halfSize = part.Scale / 2.0f; |                 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 lower = (new LSL_Vector(halfSize)) * -1.0f; | ||||||
|                 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); |                 LSL_Vector upper = new LSL_Vector(halfSize); | ||||||
|                 result.Add(lower); |                 result.Add(lower); | ||||||
|                 result.Add(upper); |                 result.Add(upper); | ||||||
|                 return result; |                 return result; | ||||||
|  | @ -8325,6 +8311,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|                     case (int)ScriptBaseClass.PRIM_POS_LOCAL: |                     case (int)ScriptBaseClass.PRIM_POS_LOCAL: | ||||||
|                         res.Add(new LSL_Vector(GetPartLocalPos(part))); |                         res.Add(new LSL_Vector(GetPartLocalPos(part))); | ||||||
|                         break; |                         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; |             return res; | ||||||
|  | @ -9913,9 +9908,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|             ScenePresence avatar = World.GetScenePresence(detectedParams.Key); |             ScenePresence avatar = World.GetScenePresence(detectedParams.Key); | ||||||
|             if (avatar != null) |             if (avatar != null) | ||||||
|             { |             { | ||||||
|                 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, simname, |                 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, | ||||||
|                                                                    new Vector3((float)pos.x, (float)pos.y, (float)pos.z), |                     simname, pos, lookAt); | ||||||
|                                                                    new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); |  | ||||||
|             } |             } | ||||||
|             ScriptSleep(1000); |             ScriptSleep(1000); | ||||||
|         } |         } | ||||||
|  | @ -10522,12 +10516,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|                                     else |                                     else | ||||||
|                                         rot = obj.GetWorldRotation(); |                                         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); |                                     ret.Add(objrot); | ||||||
|                                 } |                                 } | ||||||
|                                 break; |                                 break; | ||||||
|                             case ScriptBaseClass.OBJECT_VELOCITY: |                             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; |                                 break; | ||||||
|                             case ScriptBaseClass.OBJECT_OWNER: |                             case ScriptBaseClass.OBJECT_OWNER: | ||||||
|                                 ret.Add(new LSL_String(obj.OwnerID.ToString())); |                                 ret.Add(new LSL_String(obj.OwnerID.ToString())); | ||||||
|  | @ -10754,7 +10748,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|             if (obj.OwnerID != m_host.OwnerID) |             if (obj.OwnerID != m_host.OwnerID) | ||||||
|                 return; |                 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) |         public LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules) | ||||||
|  | @ -11104,8 +11107,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
| 
 | 
 | ||||||
|             m_host.AddScriptLPS(1); |             m_host.AddScriptLPS(1); | ||||||
| 
 | 
 | ||||||
|             Vector3 rayStart = new Vector3((float)start.x, (float)start.y, (float)start.z); |             Vector3 rayStart = start; | ||||||
|             Vector3 rayEnd = new Vector3((float)end.x, (float)end.y, (float)end.z); |             Vector3 rayEnd = end; | ||||||
|             Vector3 dir = rayEnd - rayStart; |             Vector3 dir = rayEnd - rayStart; | ||||||
| 
 | 
 | ||||||
|             float dist = Vector3.Mag(dir); |             float dist = Vector3.Mag(dir); | ||||||
|  |  | ||||||
|  | @ -304,7 +304,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|                     case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: |                     case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: | ||||||
|                         idx++; |                         idx++; | ||||||
|                         iV = rules.GetVector3Item(idx); |                         iV = rules.GetVector3Item(idx); | ||||||
|                         wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); |                         wl.cloudDetailXYDensity = iV; | ||||||
|                         break; |                         break; | ||||||
|                     case (int)ScriptBaseClass.WL_CLOUD_SCALE: |                     case (int)ScriptBaseClass.WL_CLOUD_SCALE: | ||||||
|                         idx++; |                         idx++; | ||||||
|  | @ -329,7 +329,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|                     case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: |                     case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: | ||||||
|                         idx++; |                         idx++; | ||||||
|                         iV = rules.GetVector3Item(idx); |                         iV = rules.GetVector3Item(idx); | ||||||
|                         wl.cloudXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); |                         wl.cloudXYDensity = iV; | ||||||
|                         break; |                         break; | ||||||
|                     case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: |                     case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: | ||||||
|                         idx++; |                         idx++; | ||||||
|  | @ -384,7 +384,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|                     case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: |                     case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: | ||||||
|                         idx++; |                         idx++; | ||||||
|                         iV = rules.GetVector3Item(idx); |                         iV = rules.GetVector3Item(idx); | ||||||
|                         wl.reflectionWaveletScale = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); |                         wl.reflectionWaveletScale = iV; | ||||||
|                         break; |                         break; | ||||||
|                     case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: |                     case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: | ||||||
|                         idx++; |                         idx++; | ||||||
|  | @ -422,7 +422,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|                     case (int)ScriptBaseClass.WL_WATER_COLOR: |                     case (int)ScriptBaseClass.WL_WATER_COLOR: | ||||||
|                         idx++; |                         idx++; | ||||||
|                         iV = rules.GetVector3Item(idx); |                         iV = rules.GetVector3Item(idx); | ||||||
|                         wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); |                         wl.waterColor = iV; | ||||||
|                         break; |                         break; | ||||||
|                     case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: |                     case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: | ||||||
|                         idx++; |                         idx++; | ||||||
|  |  | ||||||
|  | @ -333,8 +333,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|             { |             { | ||||||
|                 if (type == typeof(OpenMetaverse.Quaternion)) |                 if (type == typeof(OpenMetaverse.Quaternion)) | ||||||
|                 { |                 { | ||||||
|                     LSL_Rotation rot = (LSL_Rotation)lslparm; |                     return (OpenMetaverse.Quaternion)((LSL_Rotation)lslparm); | ||||||
|                     return new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s); |  | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  | @ -343,8 +342,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|             { |             { | ||||||
|                 if (type == typeof(OpenMetaverse.Vector3)) |                 if (type == typeof(OpenMetaverse.Vector3)) | ||||||
|                 { |                 { | ||||||
|                     LSL_Vector vect = (LSL_Vector)lslparm; |                     return (OpenMetaverse.Vector3)((LSL_Vector)lslparm); | ||||||
|                     return new OpenMetaverse.Vector3((float)vect.x,(float)vect.y,(float)vect.z); |  | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  | @ -367,13 +365,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|                             result[i] = new UUID((LSL_Key)plist[i]); |                             result[i] = new UUID((LSL_Key)plist[i]); | ||||||
|                         else if (plist[i] is LSL_Rotation) |                         else if (plist[i] is LSL_Rotation) | ||||||
|                         { |                         { | ||||||
|                             LSL_Rotation rot = (LSL_Rotation)plist[i]; |                             result[i] = (OpenMetaverse.Quaternion)( | ||||||
|                             result[i] = new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s); |                                 (LSL_Rotation)plist[i]); | ||||||
|                         } |                         } | ||||||
|                         else if (plist[i] is LSL_Vector) |                         else if (plist[i] is LSL_Vector) | ||||||
|                         { |                         { | ||||||
|                             LSL_Vector vect = (LSL_Vector)plist[i]; |                             result[i] = (OpenMetaverse.Vector3)( | ||||||
|                             result[i] = new OpenMetaverse.Vector3((float)vect.x,(float)vect.y,(float)vect.z); |                                 (LSL_Vector)plist[i]); | ||||||
|                         } |                         } | ||||||
|                         else |                         else | ||||||
|                             MODError("unknown LSL list element type"); |                             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 |                         // 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.                         |                         // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.                         | ||||||
|                         Util.FireAndForget( |                         Util.FireAndForget(o => World.RequestTeleportLocation( | ||||||
|                             o => World.RequestTeleportLocation(presence.ControllingClient, regionName, |                             presence.ControllingClient, regionName, position, | ||||||
|                                 new Vector3((float)position.x, (float)position.y, (float)position.z), |                             lookat, (uint)TPFlags.ViaLocation)); | ||||||
|                                 new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation)); |  | ||||||
| 
 | 
 | ||||||
|                         ScriptSleep(5000); |                         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 |                         // 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. |                         // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting. | ||||||
|                         Util.FireAndForget( |                         Util.FireAndForget(o => World.RequestTeleportLocation( | ||||||
|                             o => World.RequestTeleportLocation(presence.ControllingClient, regionHandle, |                             presence.ControllingClient, regionHandle,  | ||||||
|                                 new Vector3((float)position.x, (float)position.y, (float)position.z), |                             position, lookat, (uint)TPFlags.ViaLocation)); | ||||||
|                                 new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation)); |  | ||||||
| 
 | 
 | ||||||
|                         ScriptSleep(5000); |                         ScriptSleep(5000); | ||||||
| 
 | 
 | ||||||
|  | @ -2329,7 +2327,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|                     ownerID = m_host.OwnerID; |                     ownerID = m_host.OwnerID; | ||||||
|                 UUID x = module.CreateNPC(firstname, |                 UUID x = module.CreateNPC(firstname, | ||||||
|                                           lastname, |                                           lastname, | ||||||
|                                           new Vector3((float) position.x, (float) position.y, (float) position.z), |                                           position, | ||||||
|                                           ownerID, |                                           ownerID, | ||||||
|                                           senseAsAgent, |                                           senseAsAgent, | ||||||
|                                           World, |                                           World, | ||||||
|  | @ -2446,7 +2444,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|             return new LSL_Vector(0, 0, 0); |             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"); |             CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo"); | ||||||
|             m_host.AddScriptLPS(1); |             m_host.AddScriptLPS(1); | ||||||
|  | @ -2461,7 +2459,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|                 if (!module.CheckPermissions(npcId, m_host.OwnerID)) |                 if (!module.CheckPermissions(npcId, m_host.OwnerID)) | ||||||
|                     return; |                     return; | ||||||
|                  |                  | ||||||
|                 Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z); |  | ||||||
|                 module.MoveToTarget(npcId, World, pos, false, true, false); |                 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)) |                 if (!module.CheckPermissions(npcId, m_host.OwnerID)) | ||||||
|                     return; |                     return; | ||||||
| 
 | 
 | ||||||
|                 Vector3 pos = new Vector3((float)target.x, (float)target.y, (float)target.z); |  | ||||||
|                 module.MoveToTarget( |                 module.MoveToTarget( | ||||||
|                     new UUID(npc.m_string), |                     new UUID(npc.m_string), | ||||||
|                     World, |                     World, | ||||||
|                     pos, |                     target, | ||||||
|                     (options & ScriptBaseClass.OS_NPC_NO_FLY) != 0, |                     (options & ScriptBaseClass.OS_NPC_NO_FLY) != 0, | ||||||
|                     (options & ScriptBaseClass.OS_NPC_LAND_AT_TARGET) != 0, |                     (options & ScriptBaseClass.OS_NPC_LAND_AT_TARGET) != 0, | ||||||
|                     (options & ScriptBaseClass.OS_NPC_RUNNING) != 0); |                     (options & ScriptBaseClass.OS_NPC_RUNNING) != 0); | ||||||
|  | @ -2537,7 +2533,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|                 ScenePresence sp = World.GetScenePresence(npcId); |                 ScenePresence sp = World.GetScenePresence(npcId); | ||||||
| 
 | 
 | ||||||
|                 if (sp != null) |                 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; |                 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"); |             CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar"); | ||||||
|             m_host.AddScriptLPS(1); |             m_host.AddScriptLPS(1); | ||||||
|  | @ -2895,7 +2891,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|                         sp.ControllingClient.Kick(alert); |                         sp.ControllingClient.Kick(alert); | ||||||
| 
 | 
 | ||||||
|                     // ...and close on our side |                     // ...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; |                 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); |             LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); | ||||||
|             double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); |             double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); | ||||||
| 
 | 
 | ||||||
|  | @ -428,9 +428,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | ||||||
|                             try |                             try | ||||||
|                             { |                             { | ||||||
|                                 Vector3 diff = toRegionPos - fromRegionPos; |                                 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, diff); | ||||||
|                                 double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir); |                                 double mag_obj = LSL_Types.Vector3.Mag(diff); | ||||||
|                                 double mag_obj = LSL_Types.Vector3.Mag(obj_dir); |  | ||||||
|                                 ang_obj = Math.Acos(dot / (mag_fwd * mag_obj)); |                                 ang_obj = Math.Acos(dot / (mag_fwd * mag_obj)); | ||||||
|                             } |                             } | ||||||
|                             catch |                             catch | ||||||
|  | @ -479,7 +478,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | ||||||
|                 q = avatar.Rotation * q; |                 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); |             LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); | ||||||
|             double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); |             double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); | ||||||
|             bool attached = (SensePoint.ParentGroup.AttachmentPoint != 0); |             bool attached = (SensePoint.ParentGroup.AttachmentPoint != 0); | ||||||
|  | @ -560,8 +559,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | ||||||
|                         double ang_obj = 0; |                         double ang_obj = 0; | ||||||
|                         try |                         try | ||||||
|                         { |                         { | ||||||
|                             Vector3 diff = toRegionPos - fromRegionPos; |                             LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3( | ||||||
|                             LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(diff.X, diff.Y, diff.Z); |                                 toRegionPos - fromRegionPos); | ||||||
|                             double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir); |                             double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir); | ||||||
|                             double mag_obj = LSL_Types.Vector3.Mag(obj_dir); |                             double mag_obj = LSL_Types.Vector3.Mag(obj_dir); | ||||||
|                             ang_obj = Math.Acos(dot / (mag_fwd * mag_obj)); |                             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_BELLY = 28; | ||||||
|         public const int ATTACH_RPEC = 29; |         public const int ATTACH_RPEC = 29; | ||||||
|         public const int ATTACH_LPEC = 30; |         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_CENTER_2 = 31; | ||||||
|         public const int ATTACH_HUD_TOP_RIGHT = 32; |         public const int ATTACH_HUD_TOP_RIGHT = 32; | ||||||
|         public const int ATTACH_HUD_TOP_CENTER = 33; |         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_OMEGA = 32; | ||||||
|         public const int PRIM_POS_LOCAL = 33; |         public const int PRIM_POS_LOCAL = 33; | ||||||
|         public const int PRIM_LINK_TARGET = 34; |         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_DEFAULT = 0; | ||||||
|         public const int PRIM_TEXGEN_PLANAR = 1; |         public const int PRIM_TEXGEN_PLANAR = 1; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -546,6 +546,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | ||||||
|                     "OpenSim.Region.ScriptEngine.Shared.dll")); |                     "OpenSim.Region.ScriptEngine.Shared.dll")); | ||||||
|             parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, |             parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, | ||||||
|                     "OpenSim.Region.ScriptEngine.Shared.Api.Runtime.dll")); |                     "OpenSim.Region.ScriptEngine.Shared.Api.Runtime.dll")); | ||||||
|  |             parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, | ||||||
|  |                     "OpenMetaverseTypes.dll")); | ||||||
| 
 | 
 | ||||||
|             if (lang == enumCompileType.yp) |             if (lang == enumCompileType.yp) | ||||||
|             { |             { | ||||||
|  |  | ||||||
|  | @ -160,11 +160,11 @@ namespace OpenSim.Region.ScriptEngine.Shared | ||||||
|                 else |                 else | ||||||
|                 { |                 { | ||||||
|                     // Set the values from the touch data provided by the client |                     // 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); |                     touchST = new LSL_Types.Vector3(value.STCoord); | ||||||
|                     touchUV = new LSL_Types.Vector3(value.UVCoord.X, value.UVCoord.Y, value.UVCoord.Z); |                     touchUV = new LSL_Types.Vector3(value.UVCoord); | ||||||
|                     touchNormal = new LSL_Types.Vector3(value.Normal.X, value.Normal.Y, value.Normal.Z); |                     touchNormal = new LSL_Types.Vector3(value.Normal); | ||||||
|                     touchBinormal = new LSL_Types.Vector3(value.Binormal.X, value.Binormal.Y, value.Binormal.Z); |                     touchBinormal = new LSL_Types.Vector3(value.Binormal); | ||||||
|                     touchPos = new LSL_Types.Vector3(value.Position.X, value.Position.Y, value.Position.Z); |                     touchPos = new LSL_Types.Vector3(value.Position); | ||||||
|                     touchFace = value.FaceIndex; |                     touchFace = value.FaceIndex; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  | @ -181,19 +181,13 @@ namespace OpenSim.Region.ScriptEngine.Shared | ||||||
| 
 | 
 | ||||||
|                 Name = presence.Firstname + " " + presence.Lastname; |                 Name = presence.Firstname + " " + presence.Lastname; | ||||||
|                 Owner = Key; |                 Owner = Key; | ||||||
|                 Position = new LSL_Types.Vector3( |                 Position = new LSL_Types.Vector3(presence.AbsolutePosition); | ||||||
|                         presence.AbsolutePosition.X, |  | ||||||
|                         presence.AbsolutePosition.Y, |  | ||||||
|                         presence.AbsolutePosition.Z); |  | ||||||
|                 Rotation = new LSL_Types.Quaternion( |                 Rotation = new LSL_Types.Quaternion( | ||||||
|                         presence.Rotation.X, |                         presence.Rotation.X, | ||||||
|                         presence.Rotation.Y, |                         presence.Rotation.Y, | ||||||
|                         presence.Rotation.Z, |                         presence.Rotation.Z, | ||||||
|                         presence.Rotation.W); |                         presence.Rotation.W); | ||||||
|                 Velocity = new LSL_Types.Vector3( |                 Velocity = new LSL_Types.Vector3(presence.Velocity); | ||||||
|                         presence.Velocity.X, |  | ||||||
|                         presence.Velocity.Y, |  | ||||||
|                         presence.Velocity.Z); |  | ||||||
| 
 | 
 | ||||||
|                 if (presence.PresenceType != PresenceType.Npc) |                 if (presence.PresenceType != PresenceType.Npc) | ||||||
|                 { |                 { | ||||||
|  | @ -241,16 +235,12 @@ namespace OpenSim.Region.ScriptEngine.Shared | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             Position = new LSL_Types.Vector3(part.AbsolutePosition.X, |             Position = new LSL_Types.Vector3(part.AbsolutePosition); | ||||||
|                                              part.AbsolutePosition.Y, |  | ||||||
|                                              part.AbsolutePosition.Z); |  | ||||||
| 
 | 
 | ||||||
|             Quaternion wr = part.ParentGroup.GroupRotation; |             Quaternion wr = part.ParentGroup.GroupRotation; | ||||||
|             Rotation = new LSL_Types.Quaternion(wr.X, wr.Y, wr.Z, wr.W); |             Rotation = new LSL_Types.Quaternion(wr.X, wr.Y, wr.Z, wr.W); | ||||||
| 
 | 
 | ||||||
|             Velocity = new LSL_Types.Vector3(part.Velocity.X, |             Velocity = new LSL_Types.Vector3(part.Velocity); | ||||||
|                                              part.Velocity.Y, |  | ||||||
|                                              part.Velocity.Z); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -31,6 +31,11 @@ using System.Globalization; | ||||||
| using System.Text.RegularExpressions; | using System.Text.RegularExpressions; | ||||||
| using OpenSim.Framework; | 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 | namespace OpenSim.Region.ScriptEngine.Shared | ||||||
| { | { | ||||||
|     [Serializable] |     [Serializable] | ||||||
|  | @ -54,6 +59,20 @@ namespace OpenSim.Region.ScriptEngine.Shared | ||||||
|                 z = (float)vector.z; |                 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) |             public Vector3(double X, double Y, double Z) | ||||||
|             { |             { | ||||||
|                 x = X; |                 x = X; | ||||||
|  | @ -109,6 +128,26 @@ namespace OpenSim.Region.ScriptEngine.Shared | ||||||
|                 return new list(new object[] { vec }); |                 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) |             public static bool operator ==(Vector3 lhs, Vector3 rhs) | ||||||
|             { |             { | ||||||
|                 return (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z); |                 return (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z); | ||||||
|  | @ -322,6 +361,14 @@ namespace OpenSim.Region.ScriptEngine.Shared | ||||||
|                     s = 1; |                     s = 1; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |             public Quaternion(OMV_Quaternion rot) | ||||||
|  |             { | ||||||
|  |                 x = rot.X; | ||||||
|  |                 y = rot.Y; | ||||||
|  |                 z = rot.Z; | ||||||
|  |                 s = rot.W; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             #endregion |             #endregion | ||||||
| 
 | 
 | ||||||
|             #region Overriders |             #region Overriders | ||||||
|  | @ -368,6 +415,21 @@ namespace OpenSim.Region.ScriptEngine.Shared | ||||||
|                 return new list(new object[] { r }); |                 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) |             public static bool operator ==(Quaternion lhs, Quaternion rhs) | ||||||
|             { |             { | ||||||
|                 // Return true if the fields match: |                 // Return true if the fields match: | ||||||
|  | @ -560,12 +622,23 @@ namespace OpenSim.Region.ScriptEngine.Shared | ||||||
|                 else if (m_data[itemIndex] is LSL_Types.LSLString) |                 else if (m_data[itemIndex] is LSL_Types.LSLString) | ||||||
|                     return new LSLInteger(m_data[itemIndex].ToString()); |                     return new LSLInteger(m_data[itemIndex].ToString()); | ||||||
|                 else |                 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) |             public LSL_Types.Vector3 GetVector3Item(int itemIndex) | ||||||
|             { |             { | ||||||
|  |                 if(m_data[itemIndex] is LSL_Types.Vector3) | ||||||
|                     return (LSL_Types.Vector3)m_data[itemIndex]; |                     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) |             public LSL_Types.Quaternion GetQuaternionItem(int itemIndex) | ||||||
|  |  | ||||||
|  | @ -152,9 +152,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | ||||||
|             det[0] = new DetectParams(); |             det[0] = new DetectParams(); | ||||||
|             det[0].Key = remoteClient.AgentId; |             det[0].Key = remoteClient.AgentId; | ||||||
|             det[0].Populate(myScriptEngine.World); |             det[0].Populate(myScriptEngine.World); | ||||||
|             det[0].OffsetPos = new LSL_Types.Vector3(offsetPos.X, |             det[0].OffsetPos = offsetPos; | ||||||
|                                                      offsetPos.Y, |  | ||||||
|                                                      offsetPos.Z); |  | ||||||
| 
 | 
 | ||||||
|             if (originalID == 0) |             if (originalID == 0) | ||||||
|             { |             { | ||||||
|  | @ -298,9 +296,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | ||||||
|             foreach (DetectedObject detobj in col.Colliders) |             foreach (DetectedObject detobj in col.Colliders) | ||||||
|             { |             { | ||||||
|                 DetectParams d = new DetectParams(); |                 DetectParams d = new DetectParams(); | ||||||
|                 d.Position = new LSL_Types.Vector3(detobj.posVector.X, |                 d.Position = detobj.posVector; | ||||||
|                     detobj.posVector.Y, |  | ||||||
|                     detobj.posVector.Z); |  | ||||||
|                 d.Populate(myScriptEngine.World); |                 d.Populate(myScriptEngine.World); | ||||||
|                 det.Add(d); |                 det.Add(d); | ||||||
|                 myScriptEngine.PostObjectEvent(localID, new EventParams( |                 myScriptEngine.PostObjectEvent(localID, new EventParams( | ||||||
|  | @ -318,9 +314,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | ||||||
|             foreach (DetectedObject detobj in col.Colliders) |             foreach (DetectedObject detobj in col.Colliders) | ||||||
|             { |             { | ||||||
|                 DetectParams d = new DetectParams(); |                 DetectParams d = new DetectParams(); | ||||||
|                 d.Position = new LSL_Types.Vector3(detobj.posVector.X, |                 d.Position = detobj.posVector; | ||||||
|                     detobj.posVector.Y, |  | ||||||
|                     detobj.posVector.Z); |  | ||||||
|                 d.Populate(myScriptEngine.World); |                 d.Populate(myScriptEngine.World); | ||||||
|                 det.Add(d); |                 det.Add(d); | ||||||
|                 myScriptEngine.PostObjectEvent(localID, new EventParams( |                 myScriptEngine.PostObjectEvent(localID, new EventParams( | ||||||
|  | @ -337,9 +331,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | ||||||
|             foreach (DetectedObject detobj in col.Colliders) |             foreach (DetectedObject detobj in col.Colliders) | ||||||
|             { |             { | ||||||
|                 DetectParams d = new DetectParams(); |                 DetectParams d = new DetectParams(); | ||||||
|                 d.Position = new LSL_Types.Vector3(detobj.posVector.X, |                 d.Position = detobj.posVector; | ||||||
|                     detobj.posVector.Y, |  | ||||||
|                     detobj.posVector.Z); |  | ||||||
|                 d.Populate(myScriptEngine.World); |                 d.Populate(myScriptEngine.World); | ||||||
|                 det.Add(d); |                 det.Add(d); | ||||||
|                 myScriptEngine.PostObjectEvent(localID, new EventParams( |                 myScriptEngine.PostObjectEvent(localID, new EventParams( | ||||||
|  | @ -381,8 +373,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | ||||||
|             myScriptEngine.PostObjectEvent(localID, new EventParams( |             myScriptEngine.PostObjectEvent(localID, new EventParams( | ||||||
|                     "at_target", new object[] { |                     "at_target", new object[] { | ||||||
|                     new LSL_Types.LSLInteger(handle), |                     new LSL_Types.LSLInteger(handle), | ||||||
|                     new LSL_Types.Vector3(targetpos.X,targetpos.Y,targetpos.Z), |                     new LSL_Types.Vector3(targetpos), | ||||||
|                     new LSL_Types.Vector3(atpos.X,atpos.Y,atpos.Z) }, |                     new LSL_Types.Vector3(atpos) }, | ||||||
|                     new DetectParams[0])); |                     new DetectParams[0])); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -399,8 +391,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | ||||||
|             myScriptEngine.PostObjectEvent(localID, new EventParams( |             myScriptEngine.PostObjectEvent(localID, new EventParams( | ||||||
|                     "at_rot_target", new object[] { |                     "at_rot_target", new object[] { | ||||||
|                     new LSL_Types.LSLInteger(handle), |                     new LSL_Types.LSLInteger(handle), | ||||||
|                     new LSL_Types.Quaternion(targetrot.X,targetrot.Y,targetrot.Z,targetrot.W), |                     new LSL_Types.Quaternion(targetrot), | ||||||
|                     new LSL_Types.Quaternion(atrot.X,atrot.Y,atrot.Z,atrot.W) }, |                     new LSL_Types.Quaternion(atrot) }, | ||||||
|                     new DetectParams[0])); |                     new DetectParams[0])); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -982,10 +982,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine | ||||||
|                 return false; |                 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})", |             UUID assetID = item.AssetID; | ||||||
|             //        item.Name, itemID.ToString(), part.ParentGroup.RootPart.Name); |  | ||||||
| 
 | 
 | ||||||
|             ScenePresence presence = m_Scene.GetScenePresence(item.OwnerID); |             ScenePresence presence = m_Scene.GetScenePresence(item.OwnerID); | ||||||
| 
 | 
 | ||||||
|  | @ -1164,10 +1166,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine | ||||||
|                                                   stateSource, m_MaxScriptQueue); |                                                   stateSource, m_MaxScriptQueue); | ||||||
| 
 | 
 | ||||||
| //                    if (DebugLevel >= 1) | //                    if (DebugLevel >= 1) | ||||||
|                     m_log.DebugFormat( | //                    m_log.DebugFormat( | ||||||
|                         "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", | //                        "[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.Name, item.Name, itemID, part.UUID, | ||||||
|                         part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | //                        part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | ||||||
| 
 | 
 | ||||||
|                     if (presence != null) |                     if (presence != null) | ||||||
|                     { |                     { | ||||||
|  | @ -1465,9 +1467,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine | ||||||
|                 else if (p[i] is string) |                 else if (p[i] is string) | ||||||
|                     lsl_p[i] = new LSL_Types.LSLString((string)p[i]); |                     lsl_p[i] = new LSL_Types.LSLString((string)p[i]); | ||||||
|                 else if (p[i] is Vector3) |                 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) |                 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) |                 else if (p[i] is float) | ||||||
|                     lsl_p[i] = new LSL_Types.LSLFloat((float)p[i]); |                     lsl_p[i] = new LSL_Types.LSLFloat((float)p[i]); | ||||||
|                 else |                 else | ||||||
|  | @ -1491,9 +1493,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine | ||||||
|                 else if (p[i] is string) |                 else if (p[i] is string) | ||||||
|                     lsl_p[i] = new LSL_Types.LSLString((string)p[i]); |                     lsl_p[i] = new LSL_Types.LSLString((string)p[i]); | ||||||
|                 else if (p[i] is Vector3) |                 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) |                 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) |                 else if (p[i] is float) | ||||||
|                     lsl_p[i] = new LSL_Types.LSLFloat((float)p[i]); |                     lsl_p[i] = new LSL_Types.LSLFloat((float)p[i]); | ||||||
|                 else |                 else | ||||||
|  |  | ||||||
|  | @ -164,5 +164,19 @@ namespace OpenSim.Services.Connectors | ||||||
|             m_database.RemoveRegionEnvironmentSettings(regionUUID); |             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); |             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> |     /// <summary> | ||||||
|  | @ -318,5 +331,18 @@ namespace OpenSim.Data.Null | ||||||
|         public void Shutdown() |         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() |         public void Close() | ||||||
|  |         { | ||||||
|  |             Close(false); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public void Close(bool force) | ||||||
|         { |         { | ||||||
|             // Fire the callback for this connection closing |             // Fire the callback for this connection closing | ||||||
|             // This is necesary to get the presence detector to notice that a client has logged out. |             // 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. |     ;; from the selected region_info_source. | ||||||
|     ; allow_regionless = false |     ; 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 |     ;# {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!). |     ;; Maximum size for non-physical prims.  Affects resizing of existing prims.  This can be overriden in the region config file (as NonphysicalPrimMax!). | ||||||
|     ; NonphysicalPrimMax = 256 |     ; 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 |     ;# {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. |     ;; Maximum size where a prim can be physical.  Affects resizing of existing prims.  This can be overriden in the region config file. | ||||||
|     ; PhysicalPrimMax = 10 |     ; PhysicalPrimMax = 10 | ||||||
|  | @ -675,7 +683,9 @@ | ||||||
|     ;; Maximum number of events to queue for a script (excluding timers) |     ;; Maximum number of events to queue for a script (excluding timers) | ||||||
|     ; MaxScriptEventQueue = 300 |     ; 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 |     ; ThreadStackSize = 262144 | ||||||
| 
 | 
 | ||||||
|     ;# {DeleteScriptsOnStartup} {} {Delete previously compiled script DLLs on startup?} (true false) true |     ;# {DeleteScriptsOnStartup} {} {Delete previously compiled script DLLs on startup?} (true false) true | ||||||
|  |  | ||||||
|  | @ -894,7 +894,7 @@ | ||||||
|     AvatarDensity = 60.0 |     AvatarDensity = 60.0 | ||||||
|     AvatarCapsuleRadius = 0.37 |     AvatarCapsuleRadius = 0.37 | ||||||
|     AvatarCapsuleHeight = 1.5 |     AvatarCapsuleHeight = 1.5 | ||||||
|     AvatarContactProcessingThreshold = 0.1; |     AvatarContactProcessingThreshold = 0.1 | ||||||
| 
 | 
 | ||||||
|     MaxObjectMass = 10000.01 |     MaxObjectMass = 10000.01 | ||||||
| 
 | 
 | ||||||
|  | @ -908,19 +908,19 @@ | ||||||
|     CcdSweptSphereRadius = 0.0 |     CcdSweptSphereRadius = 0.0 | ||||||
|     ContactProcessingThreshold = 0.1 |     ContactProcessingThreshold = 0.1 | ||||||
|     ; If setting a pool size, also disable dynamic allocation (default pool size is 4096 with dynamic alloc) |     ; If setting a pool size, also disable dynamic allocation (default pool size is 4096 with dynamic alloc) | ||||||
|     MaxPersistantManifoldPoolSize = 0; |     MaxPersistantManifoldPoolSize = 0 | ||||||
|     ShouldDisableContactPoolDynamicAllocation = False; |     ShouldDisableContactPoolDynamicAllocation = False | ||||||
|     ShouldForceUpdateAllAabbs = False; |     ShouldForceUpdateAllAabbs = False | ||||||
|     ShouldRandomizeSolverOrder = False; |     ShouldRandomizeSolverOrder = False | ||||||
|     ShouldSplitSimulationIslands = False; |     ShouldSplitSimulationIslands = False | ||||||
|     ShouldEnableFrictionCaching = False; |     ShouldEnableFrictionCaching = False | ||||||
|     NumberOfSolverIterations = 0;    |     NumberOfSolverIterations = 0;    | ||||||
| 
 | 
 | ||||||
|     ; Linkset constraint parameters |     ; Linkset constraint parameters | ||||||
|     LinkConstraintUseFrameOffset = False; |     LinkConstraintUseFrameOffset = False | ||||||
|     LinkConstraintEnableTransMotor = True; |     LinkConstraintEnableTransMotor = True | ||||||
|     LinkConstraintTransMotorMaxVel = 5.0; |     LinkConstraintTransMotorMaxVel = 5.0 | ||||||
|     LinkConstraintTransMotorMaxForce = 0.1; |     LinkConstraintTransMotorMaxForce = 0.1 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     ; Whether to mesh sculpties |     ; Whether to mesh sculpties | ||||||
|  | @ -931,16 +931,24 @@ | ||||||
| 
 | 
 | ||||||
|     ; level of detail for physical meshes. 32,16,8 or 4 with 32 being full detail |     ; level of detail for physical meshes. 32,16,8 or 4 with 32 being full detail | ||||||
|     MeshLevelOfDetail = 8 |     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 |     ; number^2 non-physical level of detail of the sculpt texture.  32x32 - 1024 verticies | ||||||
|     SculptLevelOfDetail = 32 |     SculptLevelOfDetail = 32 | ||||||
| 
 | 
 | ||||||
|     ; Bullet step parameters |     ; Bullet step parameters | ||||||
|     MaxSubSteps = 10; |     MaxSubSteps = 10 | ||||||
|     FixedTimeStep = .01667 |     FixedTimeStep = .01667 | ||||||
| 
 | 
 | ||||||
|     MaxCollisionsPerFrame = 2048 |     MaxCollisionsPerFrame = 2048 | ||||||
|     MaxUpdatesPerFrame = 8192 |     MaxUpdatesPerFrame = 8192 | ||||||
| 
 | 
 | ||||||
|  |     ; Detailed physics debug logging | ||||||
|  |     PhysicsLoggingEnabled = False | ||||||
|  |     PhysicsLoggingDir = "." | ||||||
|  |     VehicleLoggingEnabled = False | ||||||
|  | 
 | ||||||
| [RemoteAdmin] | [RemoteAdmin] | ||||||
|     enabled = false |     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.Core"/> | ||||||
|       <Reference name="System.Xml"/> |       <Reference name="System.Xml"/> | ||||||
|       <Reference name="Mono.Addins" path="../../../bin/"/> |       <Reference name="Mono.Addins" path="../../../bin/"/> | ||||||
|  |       <Reference name="NDesk.Options" path="../../../bin/"/> | ||||||
|       <Reference name="OpenMetaverseTypes" path="../../../bin/"/> |       <Reference name="OpenMetaverseTypes" path="../../../bin/"/> | ||||||
|       <Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/> |       <Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/> | ||||||
|       <Reference name="OpenMetaverse" path="../../../bin/"/> |       <Reference name="OpenMetaverse" path="../../../bin/"/> | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 BlueWall
						BlueWall