diff --git a/OpenSim/ApplicationPlugins/Rest/Inventory/RestAppearanceServices.cs b/OpenSim/ApplicationPlugins/Rest/Inventory/RestAppearanceServices.cs index 0188eb716e..3cda98442e 100644 --- a/OpenSim/ApplicationPlugins/Rest/Inventory/RestAppearanceServices.cs +++ b/OpenSim/ApplicationPlugins/Rest/Inventory/RestAppearanceServices.cs @@ -488,11 +488,11 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory rdata.userAppearance.AvatarHeight = (float) Convert.ToDouble(xml.Value); indata = true; } - if (xml.MoveToAttribute("Owner")) - { - rdata.userAppearance.Owner = (UUID)xml.Value; - indata = true; - } +// if (xml.MoveToAttribute("Owner")) +// { +// rdata.userAppearance.Owner = (UUID)xml.Value; +// indata = true; +// } if (xml.MoveToAttribute("Serial")) { rdata.userAppearance.Serial = Convert.ToInt32(xml.Value); @@ -747,8 +747,8 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory rdata.writer.WriteStartElement("Appearance"); rdata.writer.WriteAttributeString("Height", rdata.userAppearance.AvatarHeight.ToString()); - if (rdata.userAppearance.Owner != UUID.Zero) - rdata.writer.WriteAttributeString("Owner", rdata.userAppearance.Owner.ToString()); +// if (rdata.userAppearance.Owner != UUID.Zero) +// rdata.writer.WriteAttributeString("Owner", rdata.userAppearance.Owner.ToString()); rdata.writer.WriteAttributeString("Serial", rdata.userAppearance.Serial.ToString()); /* diff --git a/OpenSim/ApplicationPlugins/Rest/Inventory/tests/Remote.cs b/OpenSim/ApplicationPlugins/Rest/Inventory/tests/Remote.cs index 4333ef14eb..de2049f6e6 100644 --- a/OpenSim/ApplicationPlugins/Rest/Inventory/tests/Remote.cs +++ b/OpenSim/ApplicationPlugins/Rest/Inventory/tests/Remote.cs @@ -168,8 +168,8 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests float x = Convert.ToSingle(rdata.Parameters[PARM_MOVE_X]); float y = Convert.ToSingle(rdata.Parameters[PARM_MOVE_Y]); float z = Convert.ToSingle(rdata.Parameters[PARM_MOVE_Z]); - Vector3 vector = new Vector3(x,y,z); - presence.DoAutoPilot(0,vector,presence.ControllingClient); + Vector3 vector = new Vector3(x, y, z); + presence.MoveToTarget(vector); } catch (Exception e) { diff --git a/OpenSim/Framework/AgentCircuitData.cs b/OpenSim/Framework/AgentCircuitData.cs index 125910e5bc..12c8ac0c15 100644 --- a/OpenSim/Framework/AgentCircuitData.cs +++ b/OpenSim/Framework/AgentCircuitData.cs @@ -296,11 +296,12 @@ namespace OpenSim.Framework if (args["start_pos"] != null) Vector3.TryParse(args["start_pos"].AsString(), out startpos); - m_log.InfoFormat("[AGENTCIRCUITDATA] agentid={0}, child={1}, startpos={2}",AgentID,child,startpos.ToString()); + m_log.InfoFormat("[AGENTCIRCUITDATA]: agentid={0}, child={1}, startpos={2}", AgentID, child, startpos); - try { + try + { // Unpack various appearance elements - Appearance = new AvatarAppearance(AgentID); + Appearance = new AvatarAppearance(); // Eventually this code should be deprecated, use full appearance // packing in packed_appearance @@ -313,7 +314,9 @@ namespace OpenSim.Framework m_log.InfoFormat("[AGENTCIRCUITDATA] unpacked appearance"); } else - m_log.Warn("[AGENTCIRCUITDATA] failed to find a valid packed_appearance"); + { + m_log.Warn("[AGENTCIRCUITDATA]: failed to find a valid packed_appearance"); + } } catch (Exception e) { diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs index 716baab300..73b068d026 100644 --- a/OpenSim/Framework/AvatarAppearance.cs +++ b/OpenSim/Framework/AvatarAppearance.cs @@ -47,7 +47,6 @@ namespace OpenSim.Framework public readonly static int TEXTURE_COUNT = 21; public readonly static byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; - protected UUID m_owner; protected int m_serial = 0; protected byte[] m_visualparams; protected Primitive.TextureEntry m_texture; @@ -56,12 +55,6 @@ namespace OpenSim.Framework protected float m_avatarHeight = 0; protected float m_hipOffset = 0; - public virtual UUID Owner - { - get { return m_owner; } - set { m_owner = value; } - } - public virtual int Serial { get { return m_serial; } @@ -77,7 +70,11 @@ namespace OpenSim.Framework public virtual Primitive.TextureEntry Texture { get { return m_texture; } - set { m_texture = value; } + set + { +// m_log.DebugFormat("[AVATAR APPEARANCE]: Set TextureEntry to {0}", value); + m_texture = value; + } } public virtual AvatarWearable[] Wearables @@ -97,38 +94,31 @@ namespace OpenSim.Framework get { return m_hipOffset; } } - public AvatarAppearance() : this(UUID.Zero) {} - - public AvatarAppearance(UUID owner) + public AvatarAppearance() { -// m_log.WarnFormat("[AVATAR APPEARANCE]: create empty appearance for {0}",owner); +// m_log.WarnFormat("[AVATAR APPEARANCE]: create empty appearance"); m_serial = 0; - m_owner = owner; - SetDefaultWearables(); SetDefaultTexture(); SetDefaultParams(); SetHeight(); - m_attachments = new Dictionary>(); } - public AvatarAppearance(UUID avatarID, OSDMap map) + public AvatarAppearance(OSDMap map) { -// m_log.WarnFormat("[AVATAR APPEARANCE]: create appearance for {0} from OSDMap",avatarID); +// m_log.WarnFormat("[AVATAR APPEARANCE]: create appearance from OSDMap"); - m_owner = avatarID; Unpack(map); SetHeight(); } - public AvatarAppearance(UUID avatarID, AvatarWearable[] wearables, Primitive.TextureEntry textureEntry, byte[] visualParams) + public AvatarAppearance(AvatarWearable[] wearables, Primitive.TextureEntry textureEntry, byte[] visualParams) { -// m_log.WarnFormat("[AVATAR APPEARANCE] create initialized appearance for {0}",avatarID); +// m_log.WarnFormat("[AVATAR APPEARANCE] create initialized appearance"); m_serial = 0; - m_owner = avatarID; if (wearables != null) m_wearables = wearables; @@ -161,24 +151,21 @@ namespace OpenSim.Framework if (appearance == null) { m_serial = 0; - m_owner = UUID.Zero; - SetDefaultWearables(); SetDefaultTexture(); SetDefaultParams(); SetHeight(); - m_attachments = new Dictionary>(); return; } m_serial = appearance.Serial; - m_owner = appearance.Owner; m_wearables = new AvatarWearable[AvatarWearable.MAX_WEARABLES]; for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) m_wearables[i] = new AvatarWearable(); + if (copyWearables && (appearance.Wearables != null)) { for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index 710a57dad5..613db1c55a 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs @@ -593,7 +593,7 @@ namespace OpenSim.Framework // AgentTextures[i++] = o.AsUUID(); //} - Appearance = new AvatarAppearance(AgentID); + Appearance = new AvatarAppearance(); // The code to unpack textures, visuals, wearables and attachments // should be removed; packed appearance contains the full appearance @@ -635,7 +635,7 @@ namespace OpenSim.Framework // end of code to remove if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map) - Appearance = new AvatarAppearance(AgentID,(OSDMap)args["packed_appearance"]); + Appearance = new AvatarAppearance((OSDMap)args["packed_appearance"]); else m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance"); diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index f6e29771d8..481e1bb798 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -935,7 +935,7 @@ namespace OpenSim.Framework event ScriptReset OnScriptReset; event GetScriptRunning OnGetScriptRunning; event SetScriptRunning OnSetScriptRunning; - event UpdateVector OnAutoPilotGo; + event Action OnAutoPilotGo; event TerrainUnacked OnUnackedTerrain; event ActivateGesture OnActivateGesture; @@ -1395,7 +1395,7 @@ namespace OpenSim.Framework void SendGroupTransactionsSummaryDetails(IClientAPI sender,UUID groupID, UUID transactionID, UUID sessionID,int amt); void SendChangeUserRights(UUID agentID, UUID friendID, int rights); - void SendTextBoxRequest(string message, int chatChannel, string objectname, string ownerFirstName, string ownerLastName, UUID objectId); + void SendTextBoxRequest(string message, int chatChannel, string objectname, UUID ownerID, string ownerFirstName, string ownerLastName, UUID objectId); void StopFlying(ISceneEntity presence); diff --git a/OpenSim/Framework/InventoryFolderImpl.cs b/OpenSim/Framework/InventoryFolderImpl.cs index 29c7682c2b..139776bb39 100644 --- a/OpenSim/Framework/InventoryFolderImpl.cs +++ b/OpenSim/Framework/InventoryFolderImpl.cs @@ -27,13 +27,15 @@ using System; using System.Collections.Generic; +using System.Reflection; +using log4net; using OpenMetaverse; namespace OpenSim.Framework { public class InventoryFolderImpl : InventoryFolderBase { - //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); public static readonly string PATH_DELIMITER = "/"; @@ -402,6 +404,10 @@ namespace OpenSim.Framework { foreach (InventoryItemBase item in Items.Values) { +// m_log.DebugFormat( +// "[INVENTORY FOLDER IMPL]: Returning item {0} {1}, OwnerPermissions {2:X}", +// item.Name, item.ID, item.CurrentPermissions); + itemList.Add(item); } } diff --git a/OpenSim/Framework/PacketPool.cs b/OpenSim/Framework/PacketPool.cs index 7e2860e07d..41d17c54f2 100644 --- a/OpenSim/Framework/PacketPool.cs +++ b/OpenSim/Framework/PacketPool.cs @@ -144,6 +144,7 @@ namespace OpenSim.Framework m_log.WarnFormat("[PACKETPOOL]: Failed to get packet of type {0}", type); else packet.FromBytes(bytes, ref i, ref packetEnd, zeroBuffer); + return packet; } @@ -160,19 +161,18 @@ namespace OpenSim.Framework case PacketType.ObjectUpdate: ObjectUpdatePacket oup = (ObjectUpdatePacket)packet; - foreach (ObjectUpdatePacket.ObjectDataBlock oupod in - oup.ObjectData) + foreach (ObjectUpdatePacket.ObjectDataBlock oupod in oup.ObjectData) ReturnDataBlock(oupod); + oup.ObjectData = null; break; case PacketType.ImprovedTerseObjectUpdate: - ImprovedTerseObjectUpdatePacket itoup = - (ImprovedTerseObjectUpdatePacket)packet; + ImprovedTerseObjectUpdatePacket itoup = (ImprovedTerseObjectUpdatePacket)packet; - foreach (ImprovedTerseObjectUpdatePacket.ObjectDataBlock - itoupod in itoup.ObjectData) + foreach (ImprovedTerseObjectUpdatePacket.ObjectDataBlock itoupod in itoup.ObjectData) ReturnDataBlock(itoupod); + itoup.ObjectData = null; break; } @@ -194,6 +194,7 @@ namespace OpenSim.Framework { pool[type] = new Stack(); } + if ((pool[type]).Count < 50) { (pool[type]).Push(packet); @@ -223,6 +224,7 @@ namespace OpenSim.Framework { DataBlocks[typeof(T)] = new Stack(); } + return new T(); } } @@ -234,6 +236,9 @@ namespace OpenSim.Framework lock (DataBlocks) { + if (!DataBlocks.ContainsKey(typeof(T))) + DataBlocks[typeof(T)] = new Stack(); + if (DataBlocks[typeof(T)].Count < 50) DataBlocks[typeof(T)].Push(block); } diff --git a/OpenSim/Framework/TaskInventoryDictionary.cs b/OpenSim/Framework/TaskInventoryDictionary.cs index 25ae6b05c6..421bd5ddcf 100644 --- a/OpenSim/Framework/TaskInventoryDictionary.cs +++ b/OpenSim/Framework/TaskInventoryDictionary.cs @@ -59,7 +59,7 @@ namespace OpenSim.Framework clone.Add(uuid, (TaskInventoryItem) this[uuid].Clone()); } } - + return clone; } diff --git a/OpenSim/Framework/Tests/AgentCircuitDataTest.cs b/OpenSim/Framework/Tests/AgentCircuitDataTest.cs index 05d8469728..0dce414772 100644 --- a/OpenSim/Framework/Tests/AgentCircuitDataTest.cs +++ b/OpenSim/Framework/Tests/AgentCircuitDataTest.cs @@ -64,7 +64,7 @@ namespace OpenSim.Framework.Tests SecureSessionId = UUID.Random(); SessionId = UUID.Random(); - AvAppearance = new AvatarAppearance(AgentId); + AvAppearance = new AvatarAppearance(); VisualParams = new byte[218]; //body diff --git a/OpenSim/Framework/Tests/AgentCircuitManagerTests.cs b/OpenSim/Framework/Tests/AgentCircuitManagerTests.cs index 6c988976a7..9615f1b6ca 100644 --- a/OpenSim/Framework/Tests/AgentCircuitManagerTests.cs +++ b/OpenSim/Framework/Tests/AgentCircuitManagerTests.cs @@ -68,7 +68,7 @@ namespace OpenSim.Framework.Tests m_agentCircuitData1 = new AgentCircuitData(); m_agentCircuitData1.AgentID = AgentId1; - m_agentCircuitData1.Appearance = new AvatarAppearance(AgentId1); + m_agentCircuitData1.Appearance = new AvatarAppearance(); m_agentCircuitData1.BaseFolder = BaseFolder; m_agentCircuitData1.CapsPath = CapsPath; m_agentCircuitData1.child = false; @@ -83,7 +83,7 @@ namespace OpenSim.Framework.Tests m_agentCircuitData2 = new AgentCircuitData(); m_agentCircuitData2.AgentID = AgentId2; - m_agentCircuitData2.Appearance = new AvatarAppearance(AgentId2); + m_agentCircuitData2.Appearance = new AvatarAppearance(); m_agentCircuitData2.BaseFolder = BaseFolder; m_agentCircuitData2.CapsPath = CapsPath; m_agentCircuitData2.child = false; diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index fce8999912..984a7a81f7 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -1499,25 +1499,30 @@ namespace OpenSim.Framework public static void FireAndForget(System.Threading.WaitCallback callback, object obj) { + // When OpenSim interacts with a database or sends data over the wire, it must send this in en_US culture + // so that we don't encounter problems where, for instance, data is saved with a culture that uses commas + // for decimals places but is read by a culture that treats commas as number seperators. + WaitCallback realCallback = delegate(object o) { Culture.SetCurrentCulture(); callback(o); }; + switch (FireAndForgetMethod) { case FireAndForgetMethod.UnsafeQueueUserWorkItem: - ThreadPool.UnsafeQueueUserWorkItem(callback, obj); + ThreadPool.UnsafeQueueUserWorkItem(realCallback, obj); break; case FireAndForgetMethod.QueueUserWorkItem: - ThreadPool.QueueUserWorkItem(callback, obj); + ThreadPool.QueueUserWorkItem(realCallback, obj); break; case FireAndForgetMethod.BeginInvoke: FireAndForgetWrapper wrapper = FireAndForgetWrapper.Instance; - wrapper.FireAndForget(callback, obj); + wrapper.FireAndForget(realCallback, obj); break; case FireAndForgetMethod.SmartThreadPool: if (m_ThreadPool == null) m_ThreadPool = new SmartThreadPool(2000, 15, 2); - m_ThreadPool.QueueWorkItem(SmartThreadPoolCallback, new object[] { callback, obj }); + m_ThreadPool.QueueWorkItem(SmartThreadPoolCallback, new object[] { realCallback, obj }); break; case FireAndForgetMethod.Thread: - Thread thread = new Thread(delegate(object o) { callback(o); }); + Thread thread = new Thread(delegate(object o) { realCallback(o); }); thread.Start(obj); break; default: diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs index 3b261e77dd..c1300380cf 100644 --- a/OpenSim/Region/Application/Application.cs +++ b/OpenSim/Region/Application/Application.cs @@ -73,6 +73,7 @@ namespace OpenSim AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); + // Add the arguments supplied when running the application to the configuration ArgvConfigSource configSource = new ArgvConfigSource(args); @@ -91,6 +92,9 @@ namespace OpenSim m_log.Info("[OPENSIM MAIN]: configured log4net using default OpenSim.exe.config"); } + m_log.DebugFormat( + "[OPENSIM MAIN]: System Locale is {0}", System.Threading.Thread.CurrentThread.CurrentCulture); + // Increase the number of IOCP threads available. Mono defaults to a tragically low number int workerThreads, iocpThreads; System.Threading.ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads); diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 8add2afb66..259d7536e4 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -130,7 +130,9 @@ namespace OpenSim //m_log.InfoFormat("[OPENSIM MAIN]: GC Latency Mode: {0}", GCSettings.LatencyMode.ToString()); if (m_gui) // Driven by external GUI + { m_console = new CommandConsole("Region"); + } else { switch (m_consoleType) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs index 14160ae7cd..66b865f676 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs @@ -48,8 +48,8 @@ namespace OpenSim.Region.ClientStack.Linden [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class BunchOfCapsModule : 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; diff --git a/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs index 29a9199664..18c7eaeb59 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs @@ -48,8 +48,8 @@ namespace OpenSim.Region.ClientStack.Linden [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class MeshUploadFlagModule : INonSharedRegionModule { - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = +// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); /// /// Is this module enabled? diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index a34ad62545..4a36b5db47 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -231,7 +231,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP public event ScriptReset OnScriptReset; public event GetScriptRunning OnGetScriptRunning; public event SetScriptRunning OnSetScriptRunning; - public event UpdateVector OnAutoPilotGo; + public event Action OnAutoPilotGo; public event TerrainUnacked OnUnackedTerrain; public event ActivateGesture OnActivateGesture; public event DeactivateGesture OnDeactivateGesture; @@ -5266,6 +5266,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); + + AddGenericPacketHandler("autopilot", HandleAutopilot); } #region Packet Handlers @@ -5308,7 +5310,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP ); } else + { update = true; + } // These should be ordered from most-likely to // least likely to change. I've made an initial @@ -5316,6 +5320,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (update) { +// m_log.DebugFormat("[LLCLIENTVIEW]: Triggered AgentUpdate for {0}", sener.Name); + AgentUpdateArgs arg = new AgentUpdateArgs(); arg.AgentID = x.AgentID; arg.BodyRotation = x.BodyRotation; @@ -11609,55 +11615,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP return false; } - /// - /// Breaks down the genericMessagePacket into specific events - /// - /// - /// - /// - public void DecipherGenericMessage(string gmMethod, UUID gmInvoice, GenericMessagePacket.ParamListBlock[] gmParams) + protected void HandleAutopilot(Object sender, string method, List args) { - switch (gmMethod) - { - case "autopilot": - float locx; - float locy; - float locz; + float locx = 0; + float locy = 0; + float locz = 0; + uint regionX = 0; + uint regionY = 0; - try - { - uint regionX; - uint regionY; - Utils.LongToUInts(Scene.RegionInfo.RegionHandle, out regionX, out regionY); - locx = Convert.ToSingle(Utils.BytesToString(gmParams[0].Parameter)) - regionX; - locy = Convert.ToSingle(Utils.BytesToString(gmParams[1].Parameter)) - regionY; - locz = Convert.ToSingle(Utils.BytesToString(gmParams[2].Parameter)); - } - catch (InvalidCastException) - { - m_log.Error("[CLIENT]: Invalid autopilot request"); - return; - } + Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out regionX, out regionY); + locx = Convert.ToSingle(args[0]) - (float)regionX; + locy = Convert.ToSingle(args[1]) - (float)regionY; + locz = Convert.ToSingle(args[2]); - UpdateVector handlerAutoPilotGo = OnAutoPilotGo; - if (handlerAutoPilotGo != null) - { - handlerAutoPilotGo(0, new Vector3(locx, locy, locz), this); - } - m_log.InfoFormat("[CLIENT]: Client Requests autopilot to position <{0},{1},{2}>", locx, locy, locz); - - - break; - default: - m_log.Debug("[CLIENT]: Unknown Generic Message, Method: " + gmMethod + ". Invoice: " + gmInvoice + ". Dumping Params:"); - for (int hi = 0; hi < gmParams.Length; hi++) - { - Console.WriteLine(gmParams[hi].ToString()); - } - //gmpack.MethodData. - break; - - } + Action handlerAutoPilotGo = OnAutoPilotGo; + if (handlerAutoPilotGo != null) + handlerAutoPilotGo(new Vector3(locx, locy, locz)); } /// @@ -12083,7 +12056,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(packet, ThrottleOutPacketType.Task); } - public void SendTextBoxRequest(string message, int chatChannel, string objectname, string ownerFirstName, string ownerLastName, UUID objectId) + public void SendTextBoxRequest(string message, int chatChannel, string objectname, UUID ownerID, string ownerFirstName, string ownerLastName, UUID objectId) { ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog); dialog.Data.ObjectID = objectId; @@ -12099,6 +12072,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP buttons[0] = new ScriptDialogPacket.ButtonsBlock(); buttons[0].ButtonLabel = Util.StringToBytes256("!!llTextBox!!"); dialog.Buttons = buttons; + + dialog.OwnerData = new ScriptDialogPacket.OwnerDataBlock[1]; + dialog.OwnerData[0] = new ScriptDialogPacket.OwnerDataBlock(); + dialog.OwnerData[0].OwnerID = ownerID; + OutPacket(dialog, ThrottleOutPacketType.Task); } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index aff90c5259..f2388cdf54 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -160,6 +160,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP public Socket Server { get { return null; } } + private int m_malformedCount = 0; // Guard against a spamming attack + public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager) : base(listenIP, (int)port) { @@ -612,6 +614,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP #region Decoding + if (buffer.DataLength < 7) + return; // Drop undersizd packet + + int headerLen = 7; + if (buffer.Data[6] == 0xFF) + { + if (buffer.Data[7] == 0xFF) + headerLen = 10; + else + headerLen = 8; + } + + if (buffer.DataLength < headerLen) + return; // Malformed header + try { packet = Packet.BuildPacket(buffer.Data, ref packetEnd, @@ -621,6 +638,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP catch (MalformedDataException) { } + catch (IndexOutOfRangeException) + { + return; // Drop short packet + } + catch(Exception e) + { + if (m_malformedCount < 100) + m_log.DebugFormat("[LLUDPSERVER]: Dropped malformed packet: " + e.ToString()); + m_malformedCount++; + if ((m_malformedCount % 100000) == 0) + m_log.DebugFormat("[LLUDPSERVER]: Received {0} malformed packets so far, probable network attack.", m_malformedCount); + } // Fail-safe check if (packet == null) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs index 29fd1a409a..4c33db55c2 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs @@ -44,7 +44,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static Int32 m_counter = 0; - private Int32 m_identifier; +// private Int32 m_identifier; /// /// Number of ticks (ms) per quantum, drip rate and max burst @@ -173,7 +173,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// second. If zero, the bucket always remains full public TokenBucket(TokenBucket parent, Int64 dripRate) { - m_identifier = m_counter++; +// m_identifier = m_counter++; + m_counter++; Parent = parent; RequestedDripRate = dripRate; @@ -320,7 +321,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP public class AdaptiveTokenBucket : TokenBucket { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); /// /// The minimum rate for flow control. Minimum drip rate is one diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index 2b3f7f5b85..da39202318 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -301,7 +301,9 @@ namespace Flotsam.RegionModules.AssetCache } catch (Exception e) { - LogException(e); + m_log.ErrorFormat( + "[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}", + asset.ID, e.Message, e.StackTrace); } } @@ -361,7 +363,9 @@ namespace Flotsam.RegionModules.AssetCache } catch (System.Runtime.Serialization.SerializationException e) { - LogException(e); + m_log.ErrorFormat( + "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}", + filename, id, e.Message, e.StackTrace); // If there was a problem deserializing the asset, the asset may // either be corrupted OR was serialized under an old format @@ -371,7 +375,9 @@ namespace Flotsam.RegionModules.AssetCache } catch (Exception e) { - LogException(e); + m_log.ErrorFormat( + "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}", + filename, id, e.Message, e.StackTrace); } finally { @@ -380,7 +386,6 @@ namespace Flotsam.RegionModules.AssetCache } } - #if WAIT_ON_INPROGRESS_REQUESTS // Check if we're already downloading this asset. If so, try to wait for it to // download. @@ -403,7 +408,6 @@ namespace Flotsam.RegionModules.AssetCache m_RequestsForInprogress++; } #endif - return asset; } @@ -415,7 +419,7 @@ namespace Flotsam.RegionModules.AssetCache if (m_MemoryCacheEnabled) asset = GetFromMemoryCache(id); - else if (m_FileCacheEnabled) + if (asset == null && m_FileCacheEnabled) asset = GetFromFileCache(id); if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0)) @@ -432,7 +436,6 @@ namespace Flotsam.RegionModules.AssetCache } m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0} unnessesary requests due to requests for assets that are currently downloading.", m_RequestsForInprogress); - } return asset; @@ -446,7 +449,7 @@ namespace Flotsam.RegionModules.AssetCache public void Expire(string id) { if (m_LogLevel >= 2) - m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Expiring Asset {0}.", id); + m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Expiring Asset {0}", id); try { @@ -464,7 +467,9 @@ namespace Flotsam.RegionModules.AssetCache } catch (Exception e) { - LogException(e); + m_log.ErrorFormat( + "[FLOTSAM ASSET CACHE]: Failed to expire cached file {0}. Exception {1} {2}", + id, e.Message, e.StackTrace); } } @@ -602,7 +607,9 @@ namespace Flotsam.RegionModules.AssetCache } catch (Exception e) { - LogException(e); + m_log.ErrorFormat( + "[FLOTSAM ASSET CACHE]: Failed to write asset {0} to cache. Directory {1}, tempname {2}, filename {3}. Exception {4} {5}.", + asset.ID, directory, tempname, filename, e.Message, e.StackTrace); } finally { @@ -632,15 +639,6 @@ namespace Flotsam.RegionModules.AssetCache } } - private static void LogException(Exception e) - { - string[] text = e.ToString().Split(new char[] { '\n' }); - foreach (string t in text) - { - m_log.ErrorFormat("[FLOTSAM ASSET CACHE]: {0} ", t); - } - } - /// /// Scan through the file cache, and return number of assets currently cached. /// @@ -693,8 +691,7 @@ namespace Flotsam.RegionModules.AssetCache s.ForEachSOG(delegate(SceneObjectGroup e) { gatherer.GatherAssetUuids(e, assets); - } - ); + }); } foreach (UUID assetID in assets.Keys) @@ -727,7 +724,9 @@ namespace Flotsam.RegionModules.AssetCache } catch (Exception e) { - LogException(e); + m_log.ErrorFormat( + "[FLOTSAM ASSET CACHE]: Couldn't clear asset cache directory {0} from {1}. Exception {2} {3}", + dir, m_CacheDirectory, e.Message, e.StackTrace); } } @@ -739,7 +738,9 @@ namespace Flotsam.RegionModules.AssetCache } catch (Exception e) { - LogException(e); + m_log.ErrorFormat( + "[FLOTSAM ASSET CACHE]: Couldn't clear asset cache file {0} from {1}. Exception {1} {2}", + file, m_CacheDirectory, e.Message, e.StackTrace); } } } @@ -765,7 +766,7 @@ namespace Flotsam.RegionModules.AssetCache foreach (string s in Directory.GetFiles(m_CacheDirectory, "*.fac")) { - m_log.Info("[FLOTSAM ASSET CACHE]: Deep Scans were performed on the following regions:"); + m_log.Info("[FLOTSAM ASSET CACHE]: Deep scans have previously been performed on the following regions:"); string RegionID = s.Remove(0,s.IndexOf("_")).Replace(".fac",""); DateTime RegionDeepScanTMStamp = File.GetLastWriteTime(s); @@ -836,7 +837,6 @@ namespace Flotsam.RegionModules.AssetCache Util.FireAndForget(delegate { int assetsCached = CacheScenes(); m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Completed Scene Caching, {0} assets found.", assetsCached); - }); break; @@ -891,7 +891,6 @@ namespace Flotsam.RegionModules.AssetCache #region IAssetService Members - public AssetMetadata GetMetadata(string id) { AssetBase asset = Get(id); @@ -921,7 +920,6 @@ namespace Flotsam.RegionModules.AssetCache Cache(asset); return asset.ID; - } public bool UpdateContent(string id, byte[] data) diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 995a552bb6..e3e34523a8 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -151,6 +151,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory if (face == null) continue; +// m_log.DebugFormat( +// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", +// face.TextureID, idx, client.Name, client.AgentId); + // if the texture is one of the "defaults" then skip it // this should probably be more intelligent (skirt texture doesnt matter // if the avatar isnt wearing a skirt) but if any of the main baked @@ -305,6 +309,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory private void HandleAppearanceSave(UUID agentid) { + // We must set appearance parameters in the en_US culture in order to avoid issues where values are saved + // in a culture where decimal points are commas and then reloaded in a culture which just treats them as + // number seperators. + Culture.SetCurrentCulture(); + ScenePresence sp = m_scene.GetScenePresence(agentid); if (sp == null) { diff --git a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs index 0db31eb48f..36fe040327 100644 --- a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs @@ -141,10 +141,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog { UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, ownerid); string ownerFirstName, ownerLastName; + UUID ownerID = UUID.Zero; if (account != null) { ownerFirstName = account.FirstName; ownerLastName = account.LastName; + ownerID = account.PrincipalID; } else { @@ -155,7 +157,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog ScenePresence sp = m_scene.GetScenePresence(avatarid); if (sp != null) - sp.ControllingClient.SendTextBoxRequest(message, chatChannel, name, ownerFirstName, ownerLastName, objectid); + sp.ControllingClient.SendTextBoxRequest(message, chatChannel, name, ownerID, ownerFirstName, ownerLastName, objectid); } public void SendNotificationToUsersInRegion( diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index b714f2b6ab..493314700c 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -984,11 +984,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess public virtual bool CanGetAgentInventoryItem(IClientAPI remoteClient, UUID itemID, UUID requestID) { InventoryItemBase assetRequestItem = GetItem(remoteClient.AgentId, itemID); + if (assetRequestItem == null) { ILibraryService lib = m_Scene.RequestModuleInterface(); + if (lib != null) assetRequestItem = lib.LibraryRootFolder.FindItem(itemID); + if (assetRequestItem == null) return false; } @@ -1019,6 +1022,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess m_log.WarnFormat( "[CLIENT]: {0} requested asset {1} from item {2} but this does not match item's asset {3}", Name, requestID, itemID, assetRequestItem.AssetID); + return false; } diff --git a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs index d570608369..3155ce7cc9 100644 --- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs @@ -185,6 +185,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, "/", iarFileName, false); archread.Execute(); } + foreach (InventoryNodeBase node in nodes) FixPerms(node); } @@ -197,18 +198,19 @@ namespace OpenSim.Region.CoreModules.Framework.Library archread.Close(); } } - } private void FixPerms(InventoryNodeBase node) { + m_log.DebugFormat("[LIBRARY MODULE]: Fixing perms for {0} {1}", node.Name, node.ID); + if (node is InventoryItemBase) { InventoryItemBase item = (InventoryItemBase)node; - item.BasePermissions = 0x7FFFFFFF; - item.EveryOnePermissions = 0x7FFFFFFF; - item.CurrentPermissions = 0x7FFFFFFF; - item.NextPermissions = 0x7FFFFFFF; + item.BasePermissions = (uint)PermissionMask.All; + item.EveryOnePermissions = (uint)PermissionMask.All - (uint)PermissionMask.Modify; + item.CurrentPermissions = (uint)PermissionMask.All; + item.NextPermissions = (uint)PermissionMask.All; } } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs index 85a1ac3b64..18a7177b6f 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs @@ -39,8 +39,7 @@ using OpenMetaverse; namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization { - public class LocalAuthorizationServicesConnector : - ISharedRegionModule, IAuthorizationService + public class LocalAuthorizationServicesConnector : ISharedRegionModule, IAuthorizationService { private static readonly ILog m_log = LogManager.GetLogger( @@ -127,15 +126,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization if (!m_Enabled) return; - m_log.InfoFormat("[AUTHORIZATION CONNECTOR]: Enabled local authorization for region {0}", scene.RegionInfo.RegionName); - - + m_log.InfoFormat( + "[AUTHORIZATION CONNECTOR]: Enabled local authorization for region {0}", + scene.RegionInfo.RegionName); } - public bool IsAuthorizedForRegion(string userID, string regionID, out string message) + public bool IsAuthorizedForRegion( + string userID, string firstName, string lastName, string regionID, out string message) { - return m_AuthorizationService.IsAuthorizedForRegion(userID, regionID, out message); + return m_AuthorizationService.IsAuthorizedForRegion(userID, firstName, lastName, regionID, out message); } - } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs index 66994facff..5fa27b8704 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs @@ -117,12 +117,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization } - public bool IsAuthorizedForRegion(string userID, string regionID, out string message) + public bool IsAuthorizedForRegion( + string userID, string firstName, string lastName, string regionID, out string message) { - m_log.InfoFormat("[REMOTE AUTHORIZATION CONNECTOR]: IsAuthorizedForRegion checking {0} for region {1}", userID, regionID); + m_log.InfoFormat( + "[REMOTE AUTHORIZATION CONNECTOR]: IsAuthorizedForRegion checking {0} for region {1}", userID, regionID); bool isAuthorized = true; message = String.Empty; + string mail = String.Empty; // get the scene this call is being made for Scene scene = null; @@ -140,17 +143,22 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization if (scene != null) { UserAccount account = scene.UserAccountService.GetUserAccount(UUID.Zero, new UUID(userID)); - isAuthorized = IsAuthorizedForRegion(userID, account.FirstName, account.LastName, - account.Email, scene.RegionInfo.RegionName, regionID, out message); + + if (account != null) + mail = account.Email; + + isAuthorized + = IsAuthorizedForRegion( + userID, firstName, lastName, account.Email, scene.RegionInfo.RegionName, regionID, out message); } else { - m_log.ErrorFormat("[REMOTE AUTHORIZATION CONNECTOR] IsAuthorizedForRegion, can't find scene to match region id of {0} ",regionID); + m_log.ErrorFormat( + "[REMOTE AUTHORIZATION CONNECTOR] IsAuthorizedForRegion, can't find scene to match region id of {0}", + regionID); } - return isAuthorized; - } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs index c044407d99..cd7d6bc71c 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs @@ -64,10 +64,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests } /// - /// Test saving a V0.2 OpenSim Region Archive. + /// Test region registration. /// [Test] - public void TestRegisterRegionV0_2() + public void TestRegisterRegion() { SetUp(); @@ -123,6 +123,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests m_LocalConnector.RegisterRegion(UUID.Zero, r1); GridRegion result = m_LocalConnector.GetRegionByName(UUID.Zero, "Test"); + Assert.IsNull(result, "Retrieved GetRegionByName \"Test\" is not null"); + + result = m_LocalConnector.GetRegionByName(UUID.Zero, "Test Region 1"); Assert.IsNotNull(result, "Retrieved GetRegionByName is null"); Assert.That(result.RegionName, Is.EqualTo("Test Region 1"), "Retrieved region's name does not match"); diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 63dec1516f..7554e12531 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -470,53 +470,48 @@ namespace OpenSim.Region.CoreModules.World.Land SendLandUpdate(avatar, false); } - public void EventManagerOnSignificantClientMovement(IClientAPI remote_client) + public void EventManagerOnSignificantClientMovement(ScenePresence clientAvatar) { - ScenePresence clientAvatar = m_scene.GetScenePresence(remote_client.AgentId); - - if (clientAvatar != null) + SendLandUpdate(clientAvatar); + SendOutNearestBanLine(clientAvatar.ControllingClient); + ILandObject parcel = GetLandObject(clientAvatar.AbsolutePosition.X, clientAvatar.AbsolutePosition.Y); + if (parcel != null) { - SendLandUpdate(clientAvatar); - SendOutNearestBanLine(remote_client); - ILandObject parcel = GetLandObject(clientAvatar.AbsolutePosition.X, clientAvatar.AbsolutePosition.Y); - if (parcel != null) + if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT && + clientAvatar.sentMessageAboutRestrictedParcelFlyingDown) { - if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT && - clientAvatar.sentMessageAboutRestrictedParcelFlyingDown) + EventManagerOnAvatarEnteringNewParcel(clientAvatar, parcel.LandData.LocalID, + m_scene.RegionInfo.RegionID); + //They are going under the safety line! + if (!parcel.IsBannedFromLand(clientAvatar.UUID)) { - EventManagerOnAvatarEnteringNewParcel(clientAvatar, parcel.LandData.LocalID, - m_scene.RegionInfo.RegionID); - //They are going under the safety line! - if (!parcel.IsBannedFromLand(clientAvatar.UUID)) - { - clientAvatar.sentMessageAboutRestrictedParcelFlyingDown = false; - } + clientAvatar.sentMessageAboutRestrictedParcelFlyingDown = false; } - else if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT && - parcel.IsBannedFromLand(clientAvatar.UUID)) + } + else if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT && + parcel.IsBannedFromLand(clientAvatar.UUID)) + { + //once we've sent the message once, keep going toward the target until we are done + if (forcedPosition.ContainsKey(clientAvatar.ControllingClient.AgentId)) { - //once we've sent the message once, keep going toward the target until we are done - if (forcedPosition.ContainsKey(clientAvatar.ControllingClient.AgentId)) - { - SendYouAreBannedNotice(clientAvatar); - ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar)); - } + SendYouAreBannedNotice(clientAvatar); + ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar)); } - else if (parcel.IsRestrictedFromLand(clientAvatar.UUID)) + } + else if (parcel.IsRestrictedFromLand(clientAvatar.UUID)) + { + //once we've sent the message once, keep going toward the target until we are done + if (forcedPosition.ContainsKey(clientAvatar.ControllingClient.AgentId)) { - //once we've sent the message once, keep going toward the target until we are done - if (forcedPosition.ContainsKey(clientAvatar.ControllingClient.AgentId)) - { - SendYouAreRestrictedNotice(clientAvatar); - ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar)); - } - } - else - { - //when we are finally in a safe place, lets release the forced position lock - forcedPosition.Remove(clientAvatar.ControllingClient.AgentId); + SendYouAreRestrictedNotice(clientAvatar); + ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar)); } } + else + { + //when we are finally in a safe place, lets release the forced position lock + forcedPosition.Remove(clientAvatar.ControllingClient.AgentId); + } } } diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index a40517cf3e..7cb375180e 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -146,7 +146,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions = ParseUserSetConfigSetting(myConfig, "allowed_script_editors", m_allowedScriptEditors); if (m_bypassPermissions) - m_log.Info("[PERMISSIONS]: serviceside_object_permissions = false in ini file so disabling all region service permission checks"); + m_log.Info("[PERMISSIONS]: serverside_object_permissions = false in ini file so disabling all region service permission checks"); else m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks"); diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs index 2e3b21fac4..3804017589 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs @@ -96,16 +96,7 @@ m_log.DebugFormat("MAP NAME=({0})", mapName); // try to fetch from GridServer List regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); - if (regionInfos == null) - { - m_log.Warn("[MAPSEARCHMODULE]: RequestNamedRegions returned null. Old gridserver?"); - // service wasn't available; maybe still an old GridServer. Try the old API, though it will return only one region - regionInfos = new List(); - GridRegion info = m_scene.GridService.GetRegionByName(m_scene.RegionInfo.ScopeID, mapName); - if (info != null) - regionInfos.Add(info); - } - else if (regionInfos.Count == 0) + if (regionInfos.Count == 0) remoteClient.SendAlertMessage("Hyperlink could not be established."); m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions. Flags={2}", mapName, regionInfos.Count, flags); diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index 56b46d7f44..4f58ab01c5 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs @@ -222,7 +222,7 @@ namespace OpenSim.Region.Examples.SimpleModule public event ScriptReset OnScriptReset; public event GetScriptRunning OnGetScriptRunning; public event SetScriptRunning OnSetScriptRunning; - public event UpdateVector OnAutoPilotGo; + public event Action OnAutoPilotGo; public event TerrainUnacked OnUnackedTerrain; @@ -1152,7 +1152,7 @@ namespace OpenSim.Region.Examples.SimpleModule { } - public void SendTextBoxRequest(string message, int chatChannel, string objectname, string ownerFirstName, string ownerLastName, UUID objectId) + public void SendTextBoxRequest(string message, int chatChannel, string objectname, UUID ownerID, string ownerFirstName, string ownerLastName, UUID objectId) { } diff --git a/OpenSim/Region/Framework/Interfaces/INPCModule.cs b/OpenSim/Region/Framework/Interfaces/INPCModule.cs index 21a755f29a..fa8d6b69b4 100644 --- a/OpenSim/Region/Framework/Interfaces/INPCModule.cs +++ b/OpenSim/Region/Framework/Interfaces/INPCModule.cs @@ -32,9 +32,39 @@ namespace OpenSim.Region.Framework.Interfaces { public interface INPCModule { + /// + /// Create an NPC + /// + /// + /// + /// + /// + /// The UUID of the avatar from which to clone the NPC's appearance from. + /// The UUID of the ScenePresence created. UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, UUID cloneAppearanceFrom); - void Autopilot(UUID agentID, Scene scene, Vector3 pos); + + /// + /// Move an NPC to a target over time. + /// + /// The UUID of the NPC + /// + /// + void MoveToTarget(UUID agentID, Scene scene, Vector3 pos); + + /// + /// Get the NPC to say something. + /// + /// The UUID of the NPC + /// + /// void Say(UUID agentID, Scene scene, string text); + + + /// + /// Delete an NPC. + /// + /// The UUID of the NPC + /// void DeleteNPC(UUID agentID, Scene scene); } } \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index 4865481904..4ab818f423 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -27,6 +27,8 @@ using System; using System.Collections.Generic; +using System.Reflection; +using log4net; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; @@ -40,6 +42,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation /// public class ScenePresenceAnimator { +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + public AnimationSet Animations { get { return m_animations; } @@ -262,7 +266,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation m_animTickFall = 0; - if (move.Z > 0f) + if (move.Z > 0.2f) { // Jumping if (!jumping) @@ -295,7 +299,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation if (move.X != 0f || move.Y != 0f) { // Walking / crouchwalking / running - if (move.Z < 0f) + if (move.Z < 0) return "CROUCHWALK"; else if (m_scenePresence.SetAlwaysRun) return "RUN"; @@ -305,7 +309,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation else { // Not walking - if (move.Z < 0f) + if (move.Z < 0) return "CROUCH"; else return "STAND"; @@ -323,6 +327,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation public void UpdateMovementAnimations() { m_movementAnimation = GetMovementAnimation(); +// m_log.DebugFormat( +// "[SCENE PRESENCE ANIMATOR]: Got animation {0} for {1}", m_movementAnimation, m_scenePresence.Name); TrySetMovementAnimation(m_movementAnimation); } diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index b67937dfc6..96da2c392c 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -165,8 +165,7 @@ namespace OpenSim.Region.Framework.Scenes public delegate void AvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID); public event AvatarEnteringNewParcel OnAvatarEnteringNewParcel; - public delegate void SignificantClientMovement(IClientAPI remote_client); - public event SignificantClientMovement OnSignificantClientMovement; + public event Action OnSignificantClientMovement; public delegate void IncomingInstantMessage(GridInstantMessage message); public event IncomingInstantMessage OnIncomingInstantMessage; @@ -1592,16 +1591,16 @@ namespace OpenSim.Region.Framework.Scenes } } - public void TriggerSignificantClientMovement(IClientAPI client) + public void TriggerSignificantClientMovement(ScenePresence presence) { - SignificantClientMovement handlerSignificantClientMovement = OnSignificantClientMovement; + Action handlerSignificantClientMovement = OnSignificantClientMovement; if (handlerSignificantClientMovement != null) { - foreach (SignificantClientMovement d in handlerSignificantClientMovement.GetInvocationList()) + foreach (Action d in handlerSignificantClientMovement.GetInvocationList()) { try { - d(client); + d(presence); } catch (Exception e) { diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 30421d4224..afc1a4fce4 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -724,7 +724,10 @@ namespace OpenSim.Region.Framework.Scenes newName = item.Name; } - if (remoteClient.AgentId == oldAgentID || (LibraryService != null && LibraryService.LibraryRootFolder != null && oldAgentID == LibraryService.LibraryRootFolder.Owner)) + if (remoteClient.AgentId == oldAgentID + || (LibraryService != null + && LibraryService.LibraryRootFolder != null + && oldAgentID == LibraryService.LibraryRootFolder.Owner)) { CreateNewInventoryItem( remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType, diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 32a288724a..b3b6cbc3a4 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3079,7 +3079,7 @@ namespace OpenSim.Region.Framework.Scenes if (aCircuit == null) { m_log.DebugFormat("[APPEARANCE] Client did not supply a circuit. Non-Linden? Creating default appearance."); - appearance = new AvatarAppearance(client.AgentId); + appearance = new AvatarAppearance(); return; } @@ -3087,7 +3087,7 @@ namespace OpenSim.Region.Framework.Scenes if (appearance == null) { m_log.DebugFormat("[APPEARANCE]: Appearance not found in {0}, returning default", RegionInfo.RegionName); - appearance = new AvatarAppearance(client.AgentId); + appearance = new AvatarAppearance(); } } @@ -3553,11 +3553,12 @@ namespace OpenSim.Region.Framework.Scenes if (AuthorizationService != null) { - if (!AuthorizationService.IsAuthorizedForRegion(agent.AgentID.ToString(), RegionInfo.RegionID.ToString(),out reason)) + if (!AuthorizationService.IsAuthorizedForRegion( + agent.AgentID.ToString(), agent.firstname, agent.lastname, RegionInfo.RegionID.ToString(), out reason)) { m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region", agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); - //reason = String.Format("You are not currently on the access list for {0}",RegionInfo.RegionName); + return false; } } @@ -3880,8 +3881,11 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Tries to teleport agent to other region. + /// Tries to teleport agent to another region. /// + /// + /// The region name must exactly match that given. + /// /// /// /// @@ -3890,15 +3894,16 @@ namespace OpenSim.Region.Framework.Scenes public void RequestTeleportLocation(IClientAPI remoteClient, string regionName, Vector3 position, Vector3 lookat, uint teleportFlags) { - List regions = GridService.GetRegionsByName(RegionInfo.ScopeID, regionName, 1); - if (regions == null || regions.Count == 0) + GridRegion region = GridService.GetRegionByName(RegionInfo.ScopeID, regionName); + + if (region == null) { // can't find the region: Tell viewer and abort remoteClient.SendTeleportFailed("The region '" + regionName + "' could not be found."); return; } - RequestTeleportLocation(remoteClient, regions[0].RegionHandle, position, lookat, teleportFlags); + RequestTeleportLocation(remoteClient, region.RegionHandle, position, lookat, teleportFlags); } /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index b6fb5a449e..57baa997fd 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1650,16 +1650,7 @@ namespace OpenSim.Region.Framework.Scenes ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar); if (avatar != null) { - List coords = new List(); - uint regionX = 0; - uint regionY = 0; - Utils.LongToUInts(Scene.RegionInfo.RegionHandle, out regionX, out regionY); - target.X += regionX; - target.Y += regionY; - coords.Add(target.X.ToString()); - coords.Add(target.Y.ToString()); - coords.Add(target.Z.ToString()); - avatar.DoMoveToPosition(avatar, "", coords); + avatar.MoveToTarget(target); } } else diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 4629757de3..90ad34e29d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1038,7 +1038,7 @@ namespace OpenSim.Region.Framework.Scenes { actor.Size = m_shape.Scale; - if (((OpenMetaverse.SculptType)Shape.SculptType) == SculptType.Mesh) + if (Shape.SculptEntry) CheckSculptAndLoad(); else ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); @@ -1751,95 +1751,110 @@ namespace OpenSim.Region.Framework.Scenes return part; } + /// + /// Do a physics property update for a NINJA joint. + /// + /// + /// + protected void DoPhysicsPropertyUpdateForNinjaJoint(bool UsePhysics, bool isNew) + { + if (UsePhysics) + { + // by turning a joint proxy object physical, we cause creation of a joint in the ODE scene. + // note that, as a special case, joints have no bodies or geoms in the physics scene, even though they are physical. + + PhysicsJointType jointType; + if (IsHingeJoint()) + { + jointType = PhysicsJointType.Hinge; + } + else if (IsBallJoint()) + { + jointType = PhysicsJointType.Ball; + } + else + { + jointType = PhysicsJointType.Ball; + } + + List bodyNames = new List(); + string RawParams = Description; + string[] jointParams = RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries); + string trackedBodyName = null; + if (jointParams.Length >= 2) + { + for (int iBodyName = 0; iBodyName < 2; iBodyName++) + { + string bodyName = jointParams[iBodyName]; + bodyNames.Add(bodyName); + if (bodyName != "NULL") + { + if (trackedBodyName == null) + { + trackedBodyName = bodyName; + } + } + } + } + + SceneObjectPart trackedBody = m_parentGroup.Scene.GetSceneObjectPart(trackedBodyName); // FIXME: causes a sequential lookup + Quaternion localRotation = Quaternion.Identity; + if (trackedBody != null) + { + localRotation = Quaternion.Inverse(trackedBody.RotationOffset) * this.RotationOffset; + } + else + { + // error, output it below + } + + PhysicsJoint joint; + + joint = m_parentGroup.Scene.PhysicsScene.RequestJointCreation(Name, jointType, + AbsolutePosition, + this.RotationOffset, + Description, + bodyNames, + trackedBodyName, + localRotation); + + if (trackedBody == null) + { + ParentGroup.Scene.jointErrorMessage(joint, "warning: tracked body name not found! joint location will not be updated properly. joint: " + Name); + } + } + else + { + if (isNew) + { + // if the joint proxy is new, and it is not physical, do nothing. There is no joint in ODE to + // delete, and if we try to delete it, due to asynchronous processing, the deletion request + // will get processed later at an indeterminate time, which could cancel a later-arriving + // joint creation request. + } + else + { + // here we turn off the joint object, so remove the joint from the physics scene + m_parentGroup.Scene.PhysicsScene.RequestJointDeletion(Name); // FIXME: what if the name changed? + + // make sure client isn't interpolating the joint proxy object + Velocity = Vector3.Zero; + AngularVelocity = Vector3.Zero; + Acceleration = Vector3.Zero; + } + } + } + + /// + /// Do a physics propery update for this part. + /// + /// + /// public void DoPhysicsPropertyUpdate(bool UsePhysics, bool isNew) { if (IsJoint()) { - if (UsePhysics) - { - // by turning a joint proxy object physical, we cause creation of a joint in the ODE scene. - // note that, as a special case, joints have no bodies or geoms in the physics scene, even though they are physical. - - PhysicsJointType jointType; - if (IsHingeJoint()) - { - jointType = PhysicsJointType.Hinge; - } - else if (IsBallJoint()) - { - jointType = PhysicsJointType.Ball; - } - else - { - jointType = PhysicsJointType.Ball; - } - - List bodyNames = new List(); - string RawParams = Description; - string[] jointParams = RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries); - string trackedBodyName = null; - if (jointParams.Length >= 2) - { - for (int iBodyName = 0; iBodyName < 2; iBodyName++) - { - string bodyName = jointParams[iBodyName]; - bodyNames.Add(bodyName); - if (bodyName != "NULL") - { - if (trackedBodyName == null) - { - trackedBodyName = bodyName; - } - } - } - } - - SceneObjectPart trackedBody = m_parentGroup.Scene.GetSceneObjectPart(trackedBodyName); // FIXME: causes a sequential lookup - Quaternion localRotation = Quaternion.Identity; - if (trackedBody != null) - { - localRotation = Quaternion.Inverse(trackedBody.RotationOffset) * this.RotationOffset; - } - else - { - // error, output it below - } - - PhysicsJoint joint; - - joint = m_parentGroup.Scene.PhysicsScene.RequestJointCreation(Name, jointType, - AbsolutePosition, - this.RotationOffset, - Description, - bodyNames, - trackedBodyName, - localRotation); - - if (trackedBody == null) - { - ParentGroup.Scene.jointErrorMessage(joint, "warning: tracked body name not found! joint location will not be updated properly. joint: " + Name); - } - } - else - { - if (isNew) - { - // if the joint proxy is new, and it is not physical, do nothing. There is no joint in ODE to - // delete, and if we try to delete it, due to asynchronous processing, the deletion request - // will get processed later at an indeterminate time, which could cancel a later-arriving - // joint creation request. - } - else - { - // here we turn off the joint object, so remove the joint from the physics scene - m_parentGroup.Scene.PhysicsScene.RequestJointDeletion(Name); // FIXME: what if the name changed? - - // make sure client isn't interpolating the joint proxy object - Velocity = Vector3.Zero; - AngularVelocity = Vector3.Zero; - Acceleration = Vector3.Zero; - } - } + DoPhysicsPropertyUpdateForNinjaJoint(UsePhysics, isNew); } else { @@ -1906,7 +1921,7 @@ namespace OpenSim.Region.Framework.Scenes // If this part is a sculpt then delay the physics update until we've asynchronously loaded the // mesh data. - if (((OpenMetaverse.SculptType)Shape.SculptType) == SculptType.Mesh) + if (Shape.SculptEntry) CheckSculptAndLoad(); else m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); @@ -4821,7 +4836,6 @@ namespace OpenSim.Region.Framework.Scenes { PhysActor.OnCollisionUpdate += PhysicsCollision; PhysActor.SubscribeEvents(1000); - } } else diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 83b761c7a2..d354c0a39f 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -89,6 +89,13 @@ namespace OpenSim.Region.Framework.Scenes /// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); + /// + /// Movement updates for agents in neighboring regions are sent directly to clients. + /// This value only affects how often agent positions are sent to neighbor regions + /// for things such as distance-based update prioritization + /// + public static readonly float SIGNIFICANT_MOVEMENT = 2.0f; + public UUID currentParcelUUID = UUID.Zero; private ISceneViewer m_sceneViewer; @@ -116,7 +123,7 @@ namespace OpenSim.Region.Framework.Scenes private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO; private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO; private bool MouseDown = false; - private SceneObjectGroup proxyObjectGroup; +// private SceneObjectGroup proxyObjectGroup; //private SceneObjectPart proxyObjectPart = null; public Vector3 lastKnownAllowedPosition; public bool sentMessageAboutRestrictedParcelFlyingDown; @@ -210,8 +217,8 @@ namespace OpenSim.Region.Framework.Scenes private string m_nextSitAnimation = String.Empty; //PauPaw:Proper PID Controler for autopilot************ - private bool m_moveToPositionInProgress; - private Vector3 m_moveToPositionTarget; + public bool MovingToTarget { get; private set; } + public Vector3 MoveToPositionTarget { get; private set; } private bool m_followCamAuto; @@ -779,8 +786,7 @@ namespace OpenSim.Region.Framework.Scenes m_controllingClient.OnStartAnim += HandleStartAnim; m_controllingClient.OnStopAnim += HandleStopAnim; m_controllingClient.OnForceReleaseControls += HandleForceReleaseControls; - m_controllingClient.OnAutoPilotGo += DoAutoPilot; - m_controllingClient.AddGenericPacketHandler("autopilot", DoMoveToPosition); + m_controllingClient.OnAutoPilotGo += MoveToTarget; // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); @@ -916,7 +922,7 @@ namespace OpenSim.Region.Framework.Scenes { m_log.ErrorFormat("[SCENE PRESENCE]: null appearance in MakeRoot in {0}", Scene.RegionInfo.RegionName); // emergency; this really shouldn't happen - m_appearance = new AvatarAppearance(UUID); + m_appearance = new AvatarAppearance(); } AddToPhysicalScene(isFlying); @@ -1076,13 +1082,6 @@ namespace OpenSim.Region.Framework.Scenes SendTerseUpdateToAllClients(); } - /// - /// - /// - public void StopMovement() - { - } - public void StopFlying() { ControllingClient.StopFlying(this); @@ -1378,15 +1377,15 @@ namespace OpenSim.Region.Framework.Scenes { return; } - - bool update_movementflag = false; if (m_allowMovement && !SitGround) { + bool update_movementflag = false; + if (agentData.UseClientAgentPosition) { - m_moveToPositionInProgress = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f; - m_moveToPositionTarget = agentData.ClientAgentPosition; + MovingToTarget = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f; + MoveToPositionTarget = agentData.ClientAgentPosition; } int i = 0; @@ -1417,7 +1416,6 @@ namespace OpenSim.Region.Framework.Scenes if (m_parentID == 0) { bool bAllowUpdateMoveToPosition = false; - bool bResetMoveToPosition = false; Vector3[] dirVectors; @@ -1430,13 +1428,14 @@ namespace OpenSim.Region.Framework.Scenes // The fact that m_movementflag is a byte needs to be fixed // it really should be a uint + // A DIR_CONTROL_FLAG occurs when the user is trying to move in a particular direction. uint nudgehack = 250; foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) { if (((uint)flags & (uint)DCF) != 0) { - bResetMoveToPosition = true; DCFlagKeyPressed = true; + try { agent_control_v3 += dirVectors[i]; @@ -1480,97 +1479,22 @@ namespace OpenSim.Region.Framework.Scenes bAllowUpdateMoveToPosition = true; } } + i++; } - //Paupaw:Do Proper PID for Autopilot here - if (bResetMoveToPosition) + if (MovingToTarget) { - m_moveToPositionTarget = Vector3.Zero; - m_moveToPositionInProgress = false; - update_movementflag = true; - bAllowUpdateMoveToPosition = false; - } - - if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving)) - { - //Check the error term of the current position in relation to the target position - if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f) + // If the user has pressed a key then we want to cancel any move to target. + if (DCFlagKeyPressed) { - // we are close enough to the target - m_moveToPositionTarget = Vector3.Zero; - m_moveToPositionInProgress = false; + ResetMoveToTarget(); update_movementflag = true; } - else + else if (bAllowUpdateMoveToPosition) { - try - { - // move avatar in 2D at one meter/second towards target, in avatar coordinate frame. - // This movement vector gets added to the velocity through AddNewMovement(). - // Theoretically we might need a more complex PID approach here if other - // unknown forces are acting on the avatar and we need to adaptively respond - // to such forces, but the following simple approach seems to works fine. - Vector3 LocalVectorToTarget3D = - (m_moveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords - * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords - // Ignore z component of vector - Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); - LocalVectorToTarget2D.Normalize(); - agent_control_v3 += LocalVectorToTarget2D; - - // update avatar movement flags. the avatar coordinate system is as follows: - // - // +X (forward) - // - // ^ - // | - // | - // | - // | - // (left) +Y <--------o--------> -Y - // avatar - // | - // | - // | - // | - // v - // -X - // - - // based on the above avatar coordinate system, classify the movement into - // one of left/right/back/forward. - if (LocalVectorToTarget2D.Y > 0)//MoveLeft - { - m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; - //AgentControlFlags - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; - update_movementflag = true; - } - else if (LocalVectorToTarget2D.Y < 0) //MoveRight - { - m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; - update_movementflag = true; - } - if (LocalVectorToTarget2D.X < 0) //MoveBack - { - m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; - update_movementflag = true; - } - else if (LocalVectorToTarget2D.X > 0) //Move Forward - { - m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; - update_movementflag = true; - } - } - catch (Exception e) - { - //Avoid system crash, can be slower but... - m_log.DebugFormat("Crash! {0}", e.ToString()); - } + if (HandleMoveToTargetUpdate(ref agent_control_v3, bodyRotation)) + update_movementflag = true; } } } @@ -1608,74 +1532,208 @@ namespace OpenSim.Region.Framework.Scenes // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); AddNewMovement(agent_control_v3, q); - - } - } - if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) - Animator.UpdateMovementAnimations(); + if (update_movementflag + && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) + && (m_parentID == 0) + && !SitGround) + Animator.UpdateMovementAnimations(); + } m_scene.EventManager.TriggerOnClientMovement(this); m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); } - public void DoAutoPilot(uint not_used, Vector3 Pos, IClientAPI remote_client) + /// + /// Calculate an update to move the presence to the set target. + /// + /// + /// This doesn't actually perform the movement. Instead, it adds its vector to agent_control_v3. + /// + /// Cumulative agent movement that this method will update. + /// New body rotation of the avatar. + /// True if movement has been updated in some way. False otherwise. + public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3, Quaternion bodyRotation) { - m_autopilotMoving = true; - m_autoPilotTarget = Pos; - m_sitAtAutoTarget = false; - PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; - //proxy.PCode = (byte)PCode.ParticleSystem; +// m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name); - proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); - proxyObjectGroup.AttachToScene(m_scene); - - // Commented out this code since it could never have executed, but might still be informative. -// if (proxyObjectGroup != null) -// { - proxyObjectGroup.SendGroupFullUpdate(); - remote_client.SendSitResponse(proxyObjectGroup.UUID, Vector3.Zero, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false); - m_scene.DeleteSceneObject(proxyObjectGroup, false); -// } -// else -// { -// m_autopilotMoving = false; -// m_autoPilotTarget = Vector3.Zero; -// ControllingClient.SendAlertMessage("Autopilot cancelled"); -// } + bool updated = false; + +// m_log.DebugFormat( +// "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", +// allowUpdate, m_moveToPositionInProgress, m_autopilotMoving); + + if (!m_autopilotMoving) + { + double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget); +// m_log.DebugFormat( +// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", +// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget); + + // Check the error term of the current position in relation to the target position + if (distanceToTarget <= 1) + { + // We are close enough to the target + AbsolutePosition = MoveToPositionTarget; + ResetMoveToTarget(); + updated = true; + } + else + { + try + { + // move avatar in 3D at one meter/second towards target, in avatar coordinate frame. + // This movement vector gets added to the velocity through AddNewMovement(). + // Theoretically we might need a more complex PID approach here if other + // unknown forces are acting on the avatar and we need to adaptively respond + // to such forces, but the following simple approach seems to works fine. + Vector3 LocalVectorToTarget3D = + (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords + * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords + // Ignore z component of vector +// Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); + LocalVectorToTarget3D.Normalize(); + + // update avatar movement flags. the avatar coordinate system is as follows: + // + // +X (forward) + // + // ^ + // | + // | + // | + // | + // (left) +Y <--------o--------> -Y + // avatar + // | + // | + // | + // | + // v + // -X + // + + // based on the above avatar coordinate system, classify the movement into + // one of left/right/back/forward. + if (LocalVectorToTarget3D.X < 0) //MoveBack + { + m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; + AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; + updated = true; + } + else if (LocalVectorToTarget3D.X > 0) //Move Forward + { + m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; + AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; + updated = true; + } + + if (LocalVectorToTarget3D.Y > 0) //MoveLeft + { + m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; + AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; + updated = true; + } + else if (LocalVectorToTarget3D.Y < 0) //MoveRight + { + m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; + AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; + updated = true; + } + + if (LocalVectorToTarget3D.Z > 0) //Up + { + // Don't set these flags for up or down - doing so will make the avatar crouch or + // keep trying to jump even if walking along level ground + //m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP; + //AgentControlFlags + //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP; + updated = true; + } + else if (LocalVectorToTarget3D.Z < 0) //Down + { + //m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN; + //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN; + updated = true; + } + +// m_log.DebugFormat( +// "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}", +// LocalVectorToTarget3D, agent_control_v3, Name); + + agent_control_v3 += LocalVectorToTarget3D; + } + catch (Exception e) + { + //Avoid system crash, can be slower but... + m_log.DebugFormat("Crash! {0}", e.ToString()); + } + } + } + + return updated; } - public void DoMoveToPosition(Object sender, string method, List args) + /// + /// Move to the given target over time. + /// + /// + public void MoveToTarget(Vector3 pos) { - try - { - float locx = 0f; - float locy = 0f; - float locz = 0f; - uint regionX = 0; - uint regionY = 0; - try - { - Utils.LongToUInts(Scene.RegionInfo.RegionHandle, out regionX, out regionY); - locx = Convert.ToSingle(args[0]) - (float)regionX; - locy = Convert.ToSingle(args[1]) - (float)regionY; - locz = Convert.ToSingle(args[2]); - } - catch (InvalidCastException) - { - m_log.Error("[CLIENT]: Invalid autopilot request"); - return; - } - m_moveToPositionInProgress = true; - m_moveToPositionTarget = new Vector3(locx, locy, locz); - } - catch (Exception ex) - { - //Why did I get this error? - m_log.Error("[SCENEPRESENCE]: DoMoveToPosition" + ex); - } +// m_log.DebugFormat( +// "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}", +// Name, pos, m_scene.RegionInfo.RegionName); + + if (pos.X < 0 || pos.X >= Constants.RegionSize + || pos.Y < 0 || pos.Y >= Constants.RegionSize + || pos.Z < 0) + return; + +// Vector3 heightAdjust = new Vector3(0, 0, Appearance.AvatarHeight / 2); +// pos += heightAdjust; +// +// // Anti duck-walking measure +// if (Math.Abs(pos.Z - AbsolutePosition.Z) < 0.2f) +// { +//// m_log.DebugFormat("[SCENE PRESENCE]: Adjusting MoveToPosition from {0} to {1}", pos, AbsolutePosition); +// pos.Z = AbsolutePosition.Z; +// } + + float terrainHeight = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; + pos.Z = Math.Max(terrainHeight, pos.Z); + + // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is + // always slightly higher than the actual terrain height. + // FIXME: This constrains NOC movements as well, so should be somewhere else. + if (pos.Z - terrainHeight < 0.2) + pos.Z = terrainHeight; + + m_log.DebugFormat( + "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}", + Name, pos, terrainHeight, m_scene.RegionInfo.RegionName); + + if (pos.Z > terrainHeight) + PhysicsActor.Flying = true; + + MovingToTarget = true; + MoveToPositionTarget = pos; + + Vector3 agent_control_v3 = new Vector3(); + HandleMoveToTargetUpdate(ref agent_control_v3, Rotation); + AddNewMovement(agent_control_v3, Rotation); + } + + /// + /// Reset the move to target. + /// + public void ResetMoveToTarget() + { + m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); + + MovingToTarget = false; + MoveToPositionTarget = Vector3.Zero; } private void CheckAtSitTarget() @@ -1832,7 +1890,7 @@ namespace OpenSim.Region.Framework.Scenes bool forceMouselook = false; //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); - SceneObjectPart part = FindNextAvailableSitTarget(targetID); + SceneObjectPart part = FindNextAvailableSitTarget(targetID); if (part != null) { // TODO: determine position to sit at based on scene geometry; don't trust offset from client @@ -1908,14 +1966,23 @@ namespace OpenSim.Region.Framework.Scenes HandleAgentSit(remoteClient, UUID); } + // public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset, string sitAnimation) public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset) { if (m_parentID != 0) { StandUp(); } + +// if (!String.IsNullOrEmpty(sitAnimation)) +// { +// m_nextSitAnimation = sitAnimation; +// } +// else +// { m_nextSitAnimation = "SIT"; - +// } + //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); SceneObjectPart part = FindNextAvailableSitTarget(targetID); @@ -1940,7 +2007,6 @@ namespace OpenSim.Region.Framework.Scenes } else { - m_log.Warn("Sit requested on unknown object: " + targetID.ToString()); } @@ -2138,44 +2204,7 @@ namespace OpenSim.Region.Framework.Scenes SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); } */ - public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset, string sitAnimation) - { - if (m_parentID != 0) - { - StandUp(); - } - if (!String.IsNullOrEmpty(sitAnimation)) - { - m_nextSitAnimation = sitAnimation; - } - else - { - m_nextSitAnimation = "SIT"; - } - //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); - SceneObjectPart part = FindNextAvailableSitTarget(targetID); - if (part != null) - { - m_requestedSitTargetID = part.LocalId; - //m_requestedSitOffset = offset; - m_requestedSitTargetUUID = targetID; - - m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset); - - if (m_scene.PhysicsScene.SupportsRayCast()) - { - //SitRayCastAvatarPosition(part); - //return; - } - } - else - { - m_log.Warn("Sit requested on unknown object: " + targetID); - } - - SendSitResponse(remoteClient, targetID, offset, Quaternion.Identity); - } public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) { @@ -2647,10 +2676,11 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendAppearanceToAgent(ScenePresence avatar) { -// m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); +// m_log.DebugFormat( +// "[SCENE PRESENCE] Send appearance from {0} {1} to {2} {3}", Name, m_uuid, avatar.Name, avatar.UUID); avatar.ControllingClient.SendAppearance( - m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); + UUID, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); } // Because appearance setting is in a module, we actually need @@ -2659,7 +2689,11 @@ namespace OpenSim.Region.Framework.Scenes public AvatarAppearance Appearance { get { return m_appearance; } - set { m_appearance = value; } + set + { + m_appearance = value; +// m_log.DebugFormat("[SCENE PRESENCE]: Set appearance for {0} to {1}", Name, value); + } } #endregion @@ -2671,15 +2705,10 @@ namespace OpenSim.Region.Framework.Scenes /// protected void CheckForSignificantMovement() { - // Movement updates for agents in neighboring regions are sent directly to clients. - // This value only affects how often agent positions are sent to neighbor regions - // for things such as distance-based update prioritization - const float SIGNIFICANT_MOVEMENT = 2.0f; - if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > SIGNIFICANT_MOVEMENT) { posLastSignificantMove = AbsolutePosition; - m_scene.EventManager.TriggerSignificantClientMovement(m_controllingClient); + m_scene.EventManager.TriggerSignificantClientMovement(this); } // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index 393f42d840..d34d8e55ae 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs @@ -35,7 +35,7 @@ namespace OpenSim.Region.Framework.Scenes { public class UndoState { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); public Vector3 Position = Vector3.Zero; public Vector3 Scale = Vector3.Zero; diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 88db20ef8a..a0c1ab1fee 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -806,7 +806,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server public event ScriptReset OnScriptReset; public event GetScriptRunning OnGetScriptRunning; public event SetScriptRunning OnSetScriptRunning; - public event UpdateVector OnAutoPilotGo; + public event Action OnAutoPilotGo; public event TerrainUnacked OnUnackedTerrain; public event ActivateGesture OnActivateGesture; public event DeactivateGesture OnDeactivateGesture; @@ -1678,7 +1678,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server { } - public void SendTextBoxRequest(string message, int chatChannel, string objectname, string ownerFirstName, string ownerLastName, UUID objectId) + public void SendTextBoxRequest(string message, int chatChannel, string objectname, UUID ownerID, string ownerFirstName, string ownerLastName, UUID objectId) { } diff --git a/OpenSim/Region/OptionalModules/Framework/Monitoring/MonitorServicesModule.cs b/OpenSim/Region/OptionalModules/Framework/Monitoring/MonitorServicesModule.cs index d49face7ad..a25e0345ba 100644 --- a/OpenSim/Region/OptionalModules/Framework/Monitoring/MonitorServicesModule.cs +++ b/OpenSim/Region/OptionalModules/Framework/Monitoring/MonitorServicesModule.cs @@ -47,7 +47,7 @@ namespace OpenSim.Region.OptionalModules.Framework.Monitoring { protected Scene m_scene; - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); public string Name { get { return "Services Health Monitoring Module"; } } diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 15bc1b7644..dfc624d294 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -99,6 +99,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC { } + public void SendSitResponse(UUID TargetID, Vector3 OffsetPos, Quaternion SitOrientation, bool autopilot, Vector3 CameraAtOffset, Vector3 CameraEyeOffset, bool ForceMouseLook) { @@ -327,7 +328,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC public event ScriptReset OnScriptReset; public event GetScriptRunning OnGetScriptRunning; public event SetScriptRunning OnSetScriptRunning; - public event UpdateVector OnAutoPilotGo; + public event Action OnAutoPilotGo; public event TerrainUnacked OnUnackedTerrain; @@ -1157,7 +1158,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC { } - public void SendTextBoxRequest(string message, int chatChannel, string objectname, string ownerFirstName, string ownerLastName, UUID objectId) + public void SendTextBoxRequest(string message, int chatChannel, string objectname, UUID ownerID, string ownerFirstName, string ownerLastName, UUID objectId) { } diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 3cdd06d52c..4f21d9d4ec 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -44,14 +44,75 @@ namespace OpenSim.Region.OptionalModules.World.NPC { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - // private const bool m_enabled = false; - - private Dictionary m_avatars = new Dictionary(); - private Dictionary m_appearanceCache = new Dictionary(); + private Dictionary m_avatars = new Dictionary(); + private Dictionary m_appearanceCache = new Dictionary(); public void Initialise(Scene scene, IConfigSource source) { - scene.RegisterModuleInterface(this); + IConfig config = source.Configs["NPC"]; + + if (config != null && config.GetBoolean("Enabled", false)) + { + scene.RegisterModuleInterface(this); + scene.EventManager.OnSignificantClientMovement += HandleOnSignificantClientMovement; + } + } + + public void HandleOnSignificantClientMovement(ScenePresence presence) + { + lock (m_avatars) + { + if (m_avatars.ContainsKey(presence.UUID) && presence.MovingToTarget) + { + double distanceToTarget = Util.GetDistanceTo(presence.AbsolutePosition, presence.MoveToPositionTarget); +// m_log.DebugFormat( +// "[NPC MODULE]: Abs pos of {0} is {1}, target {2}, distance {3}", +// presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget, distanceToTarget); + + // Check the error term of the current position in relation to the target position + if (distanceToTarget <= ScenePresence.SIGNIFICANT_MOVEMENT) + { + // We are close enough to the target + m_log.DebugFormat("[NPC MODULE]: Stopping movement of npc {0}", presence.Name); + + if (presence.PhysicsActor.Flying) + { + Vector3 targetPos = presence.MoveToPositionTarget; + float terrainHeight = (float)presence.Scene.Heightmap[(int)targetPos.X, (int)targetPos.Y]; + if (targetPos.Z - terrainHeight < 0.2) + { + presence.PhysicsActor.Flying = false; + } + } + + presence.Velocity = Vector3.Zero; + presence.AbsolutePosition = presence.MoveToPositionTarget; + presence.ResetMoveToTarget(); + + // FIXME: This doesn't work + if (presence.PhysicsActor.Flying) + presence.Animator.TrySetMovementAnimation("HOVER"); + else + presence.Animator.TrySetMovementAnimation("STAND"); + } + else + { + m_log.DebugFormat( + "[NPC MODULE]: Updating npc {0} at {1} for next movement to {2}", + presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget); + + Vector3 agent_control_v3 = new Vector3(); + presence.HandleMoveToTargetUpdate(ref agent_control_v3, presence.Rotation); + presence.AddNewMovement(agent_control_v3, presence.Rotation); + } +// +//// presence.DoMoveToPositionUpdate((0, presence.MoveToPositionTarget, null); + +// +// + + } + } } private AvatarAppearance GetAppearance(UUID target, Scene scene) @@ -59,14 +120,21 @@ namespace OpenSim.Region.OptionalModules.World.NPC if (m_appearanceCache.ContainsKey(target)) return m_appearanceCache[target]; - AvatarAppearance appearance = scene.AvatarService.GetAppearance(target); - if (appearance != null) - { - m_appearanceCache.Add(target, appearance); - return appearance; - } + ScenePresence originalPresence = scene.GetScenePresence(target); - return new AvatarAppearance(); + if (originalPresence != null) + { + AvatarAppearance originalAppearance = originalPresence.Appearance; + m_appearanceCache.Add(target, originalAppearance); + return originalAppearance; + } + else + { + m_log.DebugFormat( + "[NPC MODULE]: Avatar {0} is not in the scene for us to grab baked textures from them. Using defaults.", target); + + return new AvatarAppearance(); + } } public UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, UUID cloneAppearanceFrom) @@ -88,6 +156,13 @@ namespace OpenSim.Region.OptionalModules.World.NPC AvatarAppearance npcAppearance = new AvatarAppearance(originalAppearance, true); acd.Appearance = npcAppearance; +// for (int i = 0; i < acd.Appearance.Texture.FaceTextures.Length; i++) +// { +// m_log.DebugFormat( +// "[NPC MODULE]: NPC avatar {0} has texture id {1} : {2}", +// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]); +// } + scene.AuthenticateHandler.AddNewCircuit(npcAvatar.CircuitCode, acd); scene.AddNewClient(npcAvatar); @@ -118,7 +193,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC return npcAvatar.AgentId; } - public void Autopilot(UUID agentID, Scene scene, Vector3 pos) + public void MoveToTarget(UUID agentID, Scene scene, Vector3 pos) { lock (m_avatars) { @@ -126,7 +201,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC { ScenePresence sp; scene.TryGetScenePresence(agentID, out sp); - sp.DoAutoPilot(0, pos, m_avatars[agentID]); + + m_log.DebugFormat( + "[NPC MODULE]: Moving {0} to {1} in {2}", sp.Name, pos, scene.RegionInfo.RegionName); + + sp.MoveToTarget(pos); } } } diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index 899e721767..c9dddbace8 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -27,11 +27,13 @@ using System; using System.Reflection; +using log4net; using Nini.Config; using NUnit.Framework; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Communications; +using OpenSim.Region.CoreModules.Avatar.AvatarFactory; using OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -51,21 +53,104 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests // log4net.Config.XmlConfigurator.Configure(); IConfigSource config = new IniConfigSource(); + config.AddConfig("NPC"); + config.Configs["NPC"].Set("Enabled", "true"); - config.AddConfig("Modules"); - config.Configs["Modules"].Set("AvatarServices", "LocalAvatarServicesConnector"); - config.AddConfig("AvatarService"); - config.Configs["AvatarService"].Set("LocalServiceModule", "OpenSim.Services.AvatarService.dll:AvatarService"); - config.Configs["AvatarService"].Set("StorageProvider", "OpenSim.Data.Null.dll"); - + AvatarFactoryModule afm = new AvatarFactoryModule(); TestScene scene = SceneSetupHelpers.SetupScene(); - SceneSetupHelpers.SetupSceneModules(scene, config, new NPCModule(), new LocalAvatarServicesConnector()); + SceneSetupHelpers.SetupSceneModules(scene, config, afm, new NPCModule()); + TestClient originalClient = SceneSetupHelpers.AddClient(scene, TestHelper.ParseTail(0x1)); +// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); + + // 8 is the index of the first baked texture in AvatarAppearance + UUID originalFace8TextureId = TestHelper.ParseTail(0x10); + Primitive.TextureEntry originalTe = new Primitive.TextureEntry(UUID.Zero); + Primitive.TextureEntryFace originalTef = originalTe.CreateFace(8); + originalTef.TextureID = originalFace8TextureId; + + // We also need to add the texture to the asset service, otherwise the AvatarFactoryModule will tell + // ScenePresence.SendInitialData() to reset our entire appearance. + scene.AssetService.Store(AssetHelpers.CreateAsset(originalFace8TextureId)); + + afm.SetAppearance(originalClient, originalTe, null); INPCModule npcModule = scene.RequestModuleInterface(); - UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, UUID.Zero); + UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, originalClient.AgentId); ScenePresence npc = scene.GetScenePresence(npcId); + Assert.That(npc, Is.Not.Null); + Assert.That(npc.Appearance.Texture.FaceTextures[8].TextureID, Is.EqualTo(originalFace8TextureId)); + } + + [Test] + public void TestMove() + { + TestHelper.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + IConfigSource config = new IniConfigSource(); + + config.AddConfig("NPC"); + config.Configs["NPC"].Set("Enabled", "true"); + + TestScene scene = SceneSetupHelpers.SetupScene(); + SceneSetupHelpers.SetupSceneModules(scene, config, new NPCModule()); + TestClient originalClient = SceneSetupHelpers.AddClient(scene, TestHelper.ParseTail(0x1)); +// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); + + Vector3 startPos = new Vector3(128, 128, 30); + INPCModule npcModule = scene.RequestModuleInterface(); + UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, scene, originalClient.AgentId); + + ScenePresence npc = scene.GetScenePresence(npcId); + Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); + + // For now, we'll make the scene presence fly to simplify this test, but this needs to change. + npc.PhysicsActor.Flying = true; + + scene.Update(); + Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); + + Vector3 targetPos = startPos + new Vector3(0, 0, 10); + npcModule.MoveToTarget(npc.UUID, scene, targetPos); + + Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); + + scene.Update(); + + // We should really check the exact figure. + Assert.That(npc.AbsolutePosition.X, Is.EqualTo(startPos.X)); + Assert.That(npc.AbsolutePosition.Y, Is.EqualTo(startPos.Y)); + Assert.That(npc.AbsolutePosition.Z, Is.GreaterThan(startPos.Z)); + Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.Z)); + + for (int i = 0; i < 10; i++) + scene.Update(); + + double distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos); + Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on first move"); + Assert.That(npc.AbsolutePosition, Is.EqualTo(targetPos)); + + // Try a second movement + startPos = npc.AbsolutePosition; + targetPos = startPos + new Vector3(10, 0, 0); + npcModule.MoveToTarget(npc.UUID, scene, targetPos); + + scene.Update(); + + // We should really check the exact figure. + Assert.That(npc.AbsolutePosition.X, Is.GreaterThan(startPos.X)); + Assert.That(npc.AbsolutePosition.X, Is.LessThan(targetPos.X)); + Assert.That(npc.AbsolutePosition.Y, Is.EqualTo(startPos.Y)); + Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); + + for (int i = 0; i < 10; i++) + scene.Update(); + + distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos); + Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on second move"); + Assert.That(npc.AbsolutePosition, Is.EqualTo(targetPos)); } } } \ No newline at end of file diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs index 6c9d9aba1d..1ceed1a91d 100644 --- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs @@ -123,11 +123,15 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin actorPosition.X = ((int)Constants.RegionSize - 0.1f); } - float height = _heightMap[(int)actor.Position.Y * Constants.RegionSize + (int)actor.Position.X] + actor.Size.Z; + float terrainHeight = 0; + if (_heightMap != null) + terrainHeight = _heightMap[(int)actor.Position.Y * Constants.RegionSize + (int)actor.Position.X]; + + float height = terrainHeight + actor.Size.Z; + if (actor.Flying) { - if (actor.Position.Z + (actor.Velocity.Z*timeStep) < - _heightMap[(int)actor.Position.Y * Constants.RegionSize + (int)actor.Position.X] + 2) + if (actor.Position.Z + (actor.Velocity.Z * timeStep) < terrainHeight + 2) { actorPosition.Z = height; actorVelocity.Z = 0; @@ -135,7 +139,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin } else { - actorPosition.Z += actor.Velocity.Z*timeStep; + actorPosition.Z += actor.Velocity.Z * timeStep; actor.IsColliding = false; } } diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs index 3870411427..04efc1dca1 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs @@ -86,6 +86,10 @@ namespace OpenSim.Region.Physics.Manager public abstract void RemoveAvatar(PhysicsActor actor); + /// + /// Remove a prim from the physics scene. + /// + /// public abstract void RemovePrim(PhysicsActor prim); public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 5413aa8bc7..e81b98238d 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -301,20 +301,22 @@ namespace OpenSim.Region.Physics.Meshing } } + /// + /// Create a physics mesh from data that comes with the prim. The actual data used depends on the prim type. + /// + /// + /// + /// + /// + /// private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod) { // m_log.DebugFormat( // "[MESH]: Creating physics proxy for {0}, shape {1}", // primName, (OpenMetaverse.SculptType)primShape.SculptType); - PrimMesh primMesh; - PrimMesher.SculptMesh sculptMesh; - - List coords = new List(); - List faces = new List(); - - Image idata = null; - string decodedSculptFileName = ""; + List coords; + List faces; if (primShape.SculptEntry) { @@ -323,312 +325,19 @@ namespace OpenSim.Region.Physics.Meshing if (!useMeshiesPhysicsMesh) return null; - m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName); - - OSD meshOsd = null; - - if (primShape.SculptData.Length <= 0) - { - m_log.Error("[MESH]: asset data is zero length"); + if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, size, out coords, out faces)) return null; - } - - long start = 0; - using (MemoryStream data = new MemoryStream(primShape.SculptData)) - { - try - { - OSD osd = OSDParser.DeserializeLLSDBinary(data); - if (osd is OSDMap) - meshOsd = (OSDMap)osd; - else - { - m_log.Warn("[Mesh}: unable to cast mesh asset to OSDMap"); - return null; - } - } - catch (Exception e) - { - m_log.Error("[MESH]: Exception deserializing mesh asset header:" + e.ToString()); - } - - start = data.Position; - } - - if (meshOsd is OSDMap) - { - OSDMap physicsParms = null; - OSDMap map = (OSDMap)meshOsd; - if (map.ContainsKey("physics_shape")) - physicsParms = (OSDMap)map["physics_shape"]; // old asset format - else if (map.ContainsKey("physics_mesh")) - physicsParms = (OSDMap)map["physics_mesh"]; // new asset format - - if (physicsParms == null) - { - m_log.Warn("[MESH]: no recognized physics mesh found in mesh asset"); - return null; - } - - int physOffset = physicsParms["offset"].AsInteger() + (int)start; - int physSize = physicsParms["size"].AsInteger(); - - if (physOffset < 0 || physSize == 0) - return null; // no mesh data in asset - - OSD decodedMeshOsd = new OSD(); - byte[] meshBytes = new byte[physSize]; - System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize); -// byte[] decompressed = new byte[physSize * 5]; - try - { - using (MemoryStream inMs = new MemoryStream(meshBytes)) - { - using (MemoryStream outMs = new MemoryStream()) - { - using (ZOutputStream zOut = new ZOutputStream(outMs)) - { - byte[] readBuffer = new byte[2048]; - int readLen = 0; - while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0) - { - zOut.Write(readBuffer, 0, readLen); - } - zOut.Flush(); - outMs.Seek(0, SeekOrigin.Begin); - - byte[] decompressedBuf = outMs.GetBuffer(); - - decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf); - } - } - } - } - catch (Exception e) - { - m_log.Error("[MESH]: exception decoding physical mesh: " + e.ToString()); - return null; - } - - OSDArray decodedMeshOsdArray = null; - - // physics_shape is an array of OSDMaps, one for each submesh - if (decodedMeshOsd is OSDArray) - { -// Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd)); - - decodedMeshOsdArray = (OSDArray)decodedMeshOsd; - foreach (OSD subMeshOsd in decodedMeshOsdArray) - { - if (subMeshOsd is OSDMap) - AddSubMesh(subMeshOsd as OSDMap, size, coords, faces); - } - } - } } else { - if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero) - { - decodedSculptFileName = System.IO.Path.Combine(decodedSculptMapPath, "smap_" + primShape.SculptTexture.ToString()); - try - { - if (File.Exists(decodedSculptFileName)) - { - idata = Image.FromFile(decodedSculptFileName); - } - } - catch (Exception e) - { - m_log.Error("[SCULPT]: unable to load cached sculpt map " + decodedSculptFileName + " " + e.Message); - - } - //if (idata != null) - // m_log.Debug("[SCULPT]: loaded cached map asset for map ID: " + primShape.SculptTexture.ToString()); - } - - if (idata == null) - { - if (primShape.SculptData == null || primShape.SculptData.Length == 0) - return null; - - try - { - OpenMetaverse.Imaging.ManagedImage unusedData; - OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(primShape.SculptData, out unusedData, out idata); - unusedData = null; - - //idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData); - - if (cacheSculptMaps && idata != null) - { - try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); } - catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); } - } - } - catch (DllNotFoundException) - { - m_log.Error("[PHYSICS]: OpenJpeg is not installed correctly on this system. Physics Proxy generation failed. Often times this is because of an old version of GLIBC. You must have version 2.4 or above!"); - return null; - } - catch (IndexOutOfRangeException) - { - m_log.Error("[PHYSICS]: OpenJpeg was unable to decode this. Physics Proxy generation failed"); - return null; - } - catch (Exception ex) - { - m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " + ex.Message); - return null; - } - } - - PrimMesher.SculptMesh.SculptType sculptType; - switch ((OpenMetaverse.SculptType)primShape.SculptType) - { - case OpenMetaverse.SculptType.Cylinder: - sculptType = PrimMesher.SculptMesh.SculptType.cylinder; - break; - case OpenMetaverse.SculptType.Plane: - sculptType = PrimMesher.SculptMesh.SculptType.plane; - break; - case OpenMetaverse.SculptType.Torus: - sculptType = PrimMesher.SculptMesh.SculptType.torus; - break; - case OpenMetaverse.SculptType.Sphere: - sculptType = PrimMesher.SculptMesh.SculptType.sphere; - break; - default: - sculptType = PrimMesher.SculptMesh.SculptType.plane; - break; - } - - bool mirror = ((primShape.SculptType & 128) != 0); - bool invert = ((primShape.SculptType & 64) != 0); - - sculptMesh = new PrimMesher.SculptMesh((Bitmap)idata, sculptType, (int)lod, false, mirror, invert); - - idata.Dispose(); - - sculptMesh.DumpRaw(baseDir, primName, "primMesh"); - - sculptMesh.Scale(size.X, size.Y, size.Z); - - coords = sculptMesh.coords; - faces = sculptMesh.faces; + if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, size, lod, out coords, out faces)) + return null; } } else { - float pathShearX = primShape.PathShearX < 128 ? (float)primShape.PathShearX * 0.01f : (float)(primShape.PathShearX - 256) * 0.01f; - float pathShearY = primShape.PathShearY < 128 ? (float)primShape.PathShearY * 0.01f : (float)(primShape.PathShearY - 256) * 0.01f; - float pathBegin = (float)primShape.PathBegin * 2.0e-5f; - float pathEnd = 1.0f - (float)primShape.PathEnd * 2.0e-5f; - float pathScaleX = (float)(primShape.PathScaleX - 100) * 0.01f; - float pathScaleY = (float)(primShape.PathScaleY - 100) * 0.01f; - - float profileBegin = (float)primShape.ProfileBegin * 2.0e-5f; - float profileEnd = 1.0f - (float)primShape.ProfileEnd * 2.0e-5f; - float profileHollow = (float)primShape.ProfileHollow * 2.0e-5f; - if (profileHollow > 0.95f) - profileHollow = 0.95f; - - int sides = 4; - if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle) - sides = 3; - else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle) - sides = 24; - else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle) - { // half circle, prim is a sphere - sides = 24; - - profileBegin = 0.5f * profileBegin + 0.5f; - profileEnd = 0.5f * profileEnd + 0.5f; - } - - int hollowSides = sides; - if (primShape.HollowShape == HollowShape.Circle) - hollowSides = 24; - else if (primShape.HollowShape == HollowShape.Square) - hollowSides = 4; - else if (primShape.HollowShape == HollowShape.Triangle) - hollowSides = 3; - - primMesh = new PrimMesh(sides, profileBegin, profileEnd, profileHollow, hollowSides); - - if (primMesh.errorMessage != null) - if (primMesh.errorMessage.Length > 0) - m_log.Error("[ERROR] " + primMesh.errorMessage); - - primMesh.topShearX = pathShearX; - primMesh.topShearY = pathShearY; - primMesh.pathCutBegin = pathBegin; - primMesh.pathCutEnd = pathEnd; - - if (primShape.PathCurve == (byte)Extrusion.Straight || primShape.PathCurve == (byte) Extrusion.Flexible) - { - primMesh.twistBegin = primShape.PathTwistBegin * 18 / 10; - primMesh.twistEnd = primShape.PathTwist * 18 / 10; - primMesh.taperX = pathScaleX; - primMesh.taperY = pathScaleY; - - if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f) - { - ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh); - if (profileBegin < 0.0f) profileBegin = 0.0f; - if (profileEnd > 1.0f) profileEnd = 1.0f; - } -#if SPAM - m_log.Debug("****** PrimMesh Parameters (Linear) ******\n" + primMesh.ParamsToDisplayString()); -#endif - try - { - primMesh.ExtrudeLinear(); - } - catch (Exception ex) - { - ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh); - return null; - } - } - else - { - primMesh.holeSizeX = (200 - primShape.PathScaleX) * 0.01f; - primMesh.holeSizeY = (200 - primShape.PathScaleY) * 0.01f; - primMesh.radius = 0.01f * primShape.PathRadiusOffset; - primMesh.revolutions = 1.0f + 0.015f * primShape.PathRevolutions; - primMesh.skew = 0.01f * primShape.PathSkew; - primMesh.twistBegin = primShape.PathTwistBegin * 36 / 10; - primMesh.twistEnd = primShape.PathTwist * 36 / 10; - primMesh.taperX = primShape.PathTaperX * 0.01f; - primMesh.taperY = primShape.PathTaperY * 0.01f; - - if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f) - { - ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh); - if (profileBegin < 0.0f) profileBegin = 0.0f; - if (profileEnd > 1.0f) profileEnd = 1.0f; - } -#if SPAM - m_log.Debug("****** PrimMesh Parameters (Circular) ******\n" + primMesh.ParamsToDisplayString()); -#endif - try - { - primMesh.ExtrudeCircular(); - } - catch (Exception ex) - { - ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh); - return null; - } - } - - primMesh.DumpRaw(baseDir, primName, "primMesh"); - - primMesh.Scale(size.X, size.Y, size.Z); - - coords = primMesh.coords; - faces = primMesh.faces; + if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, out coords, out faces)) + return null; } // Remove the reference to any JPEG2000 sculpt data so it can be GCed @@ -656,6 +365,376 @@ namespace OpenSim.Region.Physics.Meshing return mesh; } + /// + /// Generate the co-ords and faces necessary to construct a mesh from the mesh data the accompanies a prim. + /// + /// + /// + /// + /// Coords are added to this list by the method. + /// Faces are added to this list by the method. + /// true if coords and faces were successfully generated, false if not + private bool GenerateCoordsAndFacesFromPrimMeshData( + string primName, PrimitiveBaseShape primShape, Vector3 size, out List coords, out List faces) + { + m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName); + + coords = new List(); + faces = new List(); + OSD meshOsd = null; + + if (primShape.SculptData.Length <= 0) + { + m_log.Error("[MESH]: asset data is zero length"); + return false; + } + + long start = 0; + using (MemoryStream data = new MemoryStream(primShape.SculptData)) + { + try + { + OSD osd = OSDParser.DeserializeLLSDBinary(data); + if (osd is OSDMap) + meshOsd = (OSDMap)osd; + else + { + m_log.Warn("[Mesh}: unable to cast mesh asset to OSDMap"); + return false; + } + } + catch (Exception e) + { + m_log.Error("[MESH]: Exception deserializing mesh asset header:" + e.ToString()); + } + + start = data.Position; + } + + if (meshOsd is OSDMap) + { + OSDMap physicsParms = null; + OSDMap map = (OSDMap)meshOsd; + if (map.ContainsKey("physics_shape")) + physicsParms = (OSDMap)map["physics_shape"]; // old asset format + else if (map.ContainsKey("physics_mesh")) + physicsParms = (OSDMap)map["physics_mesh"]; // new asset format + + if (physicsParms == null) + { + m_log.Warn("[MESH]: no recognized physics mesh found in mesh asset"); + return false; + } + + int physOffset = physicsParms["offset"].AsInteger() + (int)start; + int physSize = physicsParms["size"].AsInteger(); + + if (physOffset < 0 || physSize == 0) + return false; // no mesh data in asset + + OSD decodedMeshOsd = new OSD(); + byte[] meshBytes = new byte[physSize]; + System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize); +// byte[] decompressed = new byte[physSize * 5]; + try + { + using (MemoryStream inMs = new MemoryStream(meshBytes)) + { + using (MemoryStream outMs = new MemoryStream()) + { + using (ZOutputStream zOut = new ZOutputStream(outMs)) + { + byte[] readBuffer = new byte[2048]; + int readLen = 0; + while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0) + { + zOut.Write(readBuffer, 0, readLen); + } + zOut.Flush(); + outMs.Seek(0, SeekOrigin.Begin); + + byte[] decompressedBuf = outMs.GetBuffer(); + + decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf); + } + } + } + } + catch (Exception e) + { + m_log.Error("[MESH]: exception decoding physical mesh: " + e.ToString()); + return false; + } + + OSDArray decodedMeshOsdArray = null; + + // physics_shape is an array of OSDMaps, one for each submesh + if (decodedMeshOsd is OSDArray) + { +// Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd)); + + decodedMeshOsdArray = (OSDArray)decodedMeshOsd; + foreach (OSD subMeshOsd in decodedMeshOsdArray) + { + if (subMeshOsd is OSDMap) + AddSubMesh(subMeshOsd as OSDMap, size, coords, faces); + } + } + } + + return true; + } + + /// + /// Generate the co-ords and faces necessary to construct a mesh from the sculpt data the accompanies a prim. + /// + /// + /// + /// + /// + /// Coords are added to this list by the method. + /// Faces are added to this list by the method. + /// true if coords and faces were successfully generated, false if not + private bool GenerateCoordsAndFacesFromPrimSculptData( + string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, out List coords, out List faces) + { + coords = new List(); + faces = new List(); + PrimMesher.SculptMesh sculptMesh; + Image idata = null; + string decodedSculptFileName = ""; + + if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero) + { + decodedSculptFileName = System.IO.Path.Combine(decodedSculptMapPath, "smap_" + primShape.SculptTexture.ToString()); + try + { + if (File.Exists(decodedSculptFileName)) + { + idata = Image.FromFile(decodedSculptFileName); + } + } + catch (Exception e) + { + m_log.Error("[SCULPT]: unable to load cached sculpt map " + decodedSculptFileName + " " + e.Message); + + } + //if (idata != null) + // m_log.Debug("[SCULPT]: loaded cached map asset for map ID: " + primShape.SculptTexture.ToString()); + } + + if (idata == null) + { + if (primShape.SculptData == null || primShape.SculptData.Length == 0) + return false; + + try + { + OpenMetaverse.Imaging.ManagedImage unusedData; + OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(primShape.SculptData, out unusedData, out idata); + + if (idata == null) + { + // In some cases it seems that the decode can return a null bitmap without throwing + // an exception + m_log.WarnFormat("[PHYSICS]: OpenJPEG decoded sculpt data for {0} to a null bitmap. Ignoring.", primName); + + return false; + } + + unusedData = null; + + //idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData); + + if (cacheSculptMaps) + { + try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); } + catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); } + } + } + catch (DllNotFoundException) + { + m_log.Error("[PHYSICS]: OpenJpeg is not installed correctly on this system. Physics Proxy generation failed. Often times this is because of an old version of GLIBC. You must have version 2.4 or above!"); + return false; + } + catch (IndexOutOfRangeException) + { + m_log.Error("[PHYSICS]: OpenJpeg was unable to decode this. Physics Proxy generation failed"); + return false; + } + catch (Exception ex) + { + m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " + ex.Message); + return false; + } + } + + PrimMesher.SculptMesh.SculptType sculptType; + switch ((OpenMetaverse.SculptType)primShape.SculptType) + { + case OpenMetaverse.SculptType.Cylinder: + sculptType = PrimMesher.SculptMesh.SculptType.cylinder; + break; + case OpenMetaverse.SculptType.Plane: + sculptType = PrimMesher.SculptMesh.SculptType.plane; + break; + case OpenMetaverse.SculptType.Torus: + sculptType = PrimMesher.SculptMesh.SculptType.torus; + break; + case OpenMetaverse.SculptType.Sphere: + sculptType = PrimMesher.SculptMesh.SculptType.sphere; + break; + default: + sculptType = PrimMesher.SculptMesh.SculptType.plane; + break; + } + + bool mirror = ((primShape.SculptType & 128) != 0); + bool invert = ((primShape.SculptType & 64) != 0); + + sculptMesh = new PrimMesher.SculptMesh((Bitmap)idata, sculptType, (int)lod, false, mirror, invert); + + idata.Dispose(); + + sculptMesh.DumpRaw(baseDir, primName, "primMesh"); + + sculptMesh.Scale(size.X, size.Y, size.Z); + + coords = sculptMesh.coords; + faces = sculptMesh.faces; + + return true; + } + + /// + /// Generate the co-ords and faces necessary to construct a mesh from the shape data the accompanies a prim. + /// + /// + /// + /// + /// Coords are added to this list by the method. + /// Faces are added to this list by the method. + /// true if coords and faces were successfully generated, false if not + private bool GenerateCoordsAndFacesFromPrimShapeData( + string primName, PrimitiveBaseShape primShape, Vector3 size, out List coords, out List faces) + { + PrimMesh primMesh; + coords = new List(); + faces = new List(); + + float pathShearX = primShape.PathShearX < 128 ? (float)primShape.PathShearX * 0.01f : (float)(primShape.PathShearX - 256) * 0.01f; + float pathShearY = primShape.PathShearY < 128 ? (float)primShape.PathShearY * 0.01f : (float)(primShape.PathShearY - 256) * 0.01f; + float pathBegin = (float)primShape.PathBegin * 2.0e-5f; + float pathEnd = 1.0f - (float)primShape.PathEnd * 2.0e-5f; + float pathScaleX = (float)(primShape.PathScaleX - 100) * 0.01f; + float pathScaleY = (float)(primShape.PathScaleY - 100) * 0.01f; + + float profileBegin = (float)primShape.ProfileBegin * 2.0e-5f; + float profileEnd = 1.0f - (float)primShape.ProfileEnd * 2.0e-5f; + float profileHollow = (float)primShape.ProfileHollow * 2.0e-5f; + if (profileHollow > 0.95f) + profileHollow = 0.95f; + + int sides = 4; + if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle) + sides = 3; + else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle) + sides = 24; + else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle) + { // half circle, prim is a sphere + sides = 24; + + profileBegin = 0.5f * profileBegin + 0.5f; + profileEnd = 0.5f * profileEnd + 0.5f; + } + + int hollowSides = sides; + if (primShape.HollowShape == HollowShape.Circle) + hollowSides = 24; + else if (primShape.HollowShape == HollowShape.Square) + hollowSides = 4; + else if (primShape.HollowShape == HollowShape.Triangle) + hollowSides = 3; + + primMesh = new PrimMesh(sides, profileBegin, profileEnd, profileHollow, hollowSides); + + if (primMesh.errorMessage != null) + if (primMesh.errorMessage.Length > 0) + m_log.Error("[ERROR] " + primMesh.errorMessage); + + primMesh.topShearX = pathShearX; + primMesh.topShearY = pathShearY; + primMesh.pathCutBegin = pathBegin; + primMesh.pathCutEnd = pathEnd; + + if (primShape.PathCurve == (byte)Extrusion.Straight || primShape.PathCurve == (byte) Extrusion.Flexible) + { + primMesh.twistBegin = primShape.PathTwistBegin * 18 / 10; + primMesh.twistEnd = primShape.PathTwist * 18 / 10; + primMesh.taperX = pathScaleX; + primMesh.taperY = pathScaleY; + + if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f) + { + ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh); + if (profileBegin < 0.0f) profileBegin = 0.0f; + if (profileEnd > 1.0f) profileEnd = 1.0f; + } +#if SPAM + m_log.Debug("****** PrimMesh Parameters (Linear) ******\n" + primMesh.ParamsToDisplayString()); +#endif + try + { + primMesh.ExtrudeLinear(); + } + catch (Exception ex) + { + ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh); + return false; + } + } + else + { + primMesh.holeSizeX = (200 - primShape.PathScaleX) * 0.01f; + primMesh.holeSizeY = (200 - primShape.PathScaleY) * 0.01f; + primMesh.radius = 0.01f * primShape.PathRadiusOffset; + primMesh.revolutions = 1.0f + 0.015f * primShape.PathRevolutions; + primMesh.skew = 0.01f * primShape.PathSkew; + primMesh.twistBegin = primShape.PathTwistBegin * 36 / 10; + primMesh.twistEnd = primShape.PathTwist * 36 / 10; + primMesh.taperX = primShape.PathTaperX * 0.01f; + primMesh.taperY = primShape.PathTaperY * 0.01f; + + if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f) + { + ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh); + if (profileBegin < 0.0f) profileBegin = 0.0f; + if (profileEnd > 1.0f) profileEnd = 1.0f; + } +#if SPAM + m_log.Debug("****** PrimMesh Parameters (Circular) ******\n" + primMesh.ParamsToDisplayString()); +#endif + try + { + primMesh.ExtrudeCircular(); + } + catch (Exception ex) + { + ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh); + return false; + } + } + + primMesh.DumpRaw(baseDir, primName, "primMesh"); + + primMesh.Scale(size.X, size.Y, size.Z); + + coords = primMesh.coords; + faces = primMesh.faces; + + return true; + } + public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) { return CreateMesh(primName, primShape, size, lod, false); diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index 6b74e74ba3..4f461ad47d 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -1220,18 +1220,23 @@ namespace OpenSim.Region.Physics.OdePlugin { m_requestedUpdateFrequency = ms; m_eventsubscription = ms; - _parent_scene.addCollisionEventReporting(this); + _parent_scene.AddCollisionEventReporting(this); } + public override void UnSubscribeEvents() { - _parent_scene.remCollisionEventReporting(this); + _parent_scene.RemoveCollisionEventReporting(this); m_requestedUpdateFrequency = 0; m_eventsubscription = 0; } + public void AddCollisionEvent(uint CollidedWith, ContactPoint contact) { if (m_eventsubscription > 0) { +// m_log.DebugFormat( +// "[PHYSICS]: Adding collision event for {0}, collidedWith {1}, contact {2}", "", CollidedWith, contact); + CollisionEventsThisFrame.addCollider(CollidedWith, contact); } } @@ -1248,6 +1253,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_eventsubscription = 0; } } + public override bool SubscribedEvents() { if (m_eventsubscription > 0) diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index b3045bd8cb..924d7c2d77 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -61,6 +61,22 @@ namespace OpenSim.Region.Physics.OdePlugin { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private bool m_isphysical; + + /// + /// Is this prim subject to physics? Even if not, it's still solid for collision purposes. + /// + public override bool IsPhysical + { + get { return m_isphysical; } + set + { + m_isphysical = value; + if (!m_isphysical) // Zero the remembered last velocity + m_lastVelocity = Vector3.Zero; + } + } + private Vector3 _position; private Vector3 _velocity; private Vector3 _torque; @@ -138,12 +154,15 @@ namespace OpenSim.Region.Physics.OdePlugin private List m_forcelist = new List(); private List m_angularforcelist = new List(); - private IMesh _mesh; private PrimitiveBaseShape _pbs; private OdeScene _parent_scene; + + /// + /// The physics space which contains prim geometries + /// public IntPtr m_targetSpace = IntPtr.Zero; + public IntPtr prim_geom; - public IntPtr prev_geom; public IntPtr _triMeshData; private IntPtr _linkJointGroup = IntPtr.Zero; @@ -153,7 +172,6 @@ namespace OpenSim.Region.Physics.OdePlugin private List childrenPrim = new List(); private bool iscolliding; - private bool m_isphysical; private bool m_isSelected; internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively @@ -188,7 +206,7 @@ namespace OpenSim.Region.Physics.OdePlugin internal int m_material = (int)Material.Wood; public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size, - Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode) + Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode) { Name = primName; m_vehicle = new ODEDynamics(); @@ -208,9 +226,7 @@ namespace OpenSim.Region.Physics.OdePlugin // m_tensor = parent_scene.bodyMotorJointMaxforceTensor; body_autodisable_frames = parent_scene.bodyFramesAutoDisable; - prim_geom = IntPtr.Zero; - prev_geom = IntPtr.Zero; if (!pos.IsFinite()) { @@ -233,20 +249,21 @@ namespace OpenSim.Region.Physics.OdePlugin _orientation = rotation; m_taintrot = _orientation; - _mesh = mesh; _pbs = pbs; _parent_scene = parent_scene; m_targetSpace = (IntPtr)0; if (pos.Z < 0) - m_isphysical = false; + { + IsPhysical = false; + } else { - m_isphysical = pisPhysical; + IsPhysical = pisPhysical; // If we're physical, we need to be in the master space for now. // linksets *should* be in a space together.. but are not currently - if (m_isphysical) + if (IsPhysical) m_targetSpace = _parent_scene.space; } @@ -289,7 +306,7 @@ namespace OpenSim.Region.Physics.OdePlugin // through it while it's selected m_collisionscore = 0; - if ((m_isphysical && !_zeroFlag) || !value) + if ((IsPhysical && !_zeroFlag) || !value) { m_taintselected = value; _parent_scene.AddPhysicsActorTaint(this); @@ -305,15 +322,21 @@ namespace OpenSim.Region.Physics.OdePlugin } } + /// + /// Set a new geometry for this prim. + /// + /// public void SetGeom(IntPtr geom) { - prev_geom = prim_geom; prim_geom = geom; //Console.WriteLine("SetGeom to " + prim_geom + " for " + Name); if (prim_geom != IntPtr.Zero) { d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + + _parent_scene.geom_name_map[prim_geom] = Name; + _parent_scene.actor_name_map[prim_geom] = this; } if (childPrim) @@ -332,7 +355,7 @@ namespace OpenSim.Region.Physics.OdePlugin { if (!childPrim) { - if (m_isphysical && Body != IntPtr.Zero) + if (IsPhysical && Body != IntPtr.Zero) { d.BodyEnable(Body); if (m_vehicle.Type != Vehicle.TYPE_NONE) @@ -347,12 +370,15 @@ namespace OpenSim.Region.Physics.OdePlugin { m_disabled = true; - if (m_isphysical && Body != IntPtr.Zero) + if (IsPhysical && Body != IntPtr.Zero) { d.BodyDisable(Body); } } + /// + /// Make a prim subject to physics. + /// public void enableBody() { // Don't enable this body if we're a child prim @@ -728,6 +754,9 @@ namespace OpenSim.Region.Physics.OdePlugin } } + /// + /// Stop a prim from being subject to physics. + /// public void disableBody() { //this kills the body so things like 'mesh' can re-create it. @@ -778,6 +807,7 @@ namespace OpenSim.Region.Physics.OdePlugin Body = IntPtr.Zero; } } + m_disabled = true; m_collisionscore = 0; } @@ -886,7 +916,7 @@ Console.WriteLine("ZProcessTaints for " + Name); } } - if (m_taintPhysics != m_isphysical && !(m_taintparent != _parent)) + if (m_taintPhysics != IsPhysical && !(m_taintparent != _parent)) changePhysicsStatus(timestep); if (!_size.ApproxEquals(m_taintsize, 0f)) @@ -968,7 +998,7 @@ Console.WriteLine("ZProcessTaints for " + Name); OdePrim obj = (OdePrim)m_taintparent; //obj.disableBody(); //Console.WriteLine("changelink calls ParentPrim"); - obj.ParentPrim(this); + obj.AddChildPrim(this); /* if (obj.Body != (IntPtr)0 && Body != (IntPtr)0 && obj.Body != Body) @@ -1005,14 +1035,16 @@ Console.WriteLine("ZProcessTaints for " + Name); } _parent = m_taintparent; - m_taintPhysics = m_isphysical; + m_taintPhysics = IsPhysical; } - // I'm the parent - // prim is the child - public void ParentPrim(OdePrim prim) + /// + /// Add a child prim to this parent prim. + /// + /// Child prim + public void AddChildPrim(OdePrim prim) { -//Console.WriteLine("ParentPrim " + Name); +//Console.WriteLine("AddChildPrim " + Name); if (this.m_localID != prim.m_localID) { if (Body == IntPtr.Zero) @@ -1035,7 +1067,6 @@ Console.WriteLine("ZProcessTaints for " + Name); d.MassSetZero(out m2); d.MassSetBoxTotal(out m2, prim.CalculateMass(), prm._size.X, prm._size.Y, prm._size.Z); - d.Quaternion quat = new d.Quaternion(); quat.W = prm._orientation.W; quat.X = prm._orientation.X; @@ -1105,6 +1136,7 @@ Console.WriteLine("ZProcessTaints for " + Name); prm.Body = Body; _parent_scene.addActivePrim(prm); } + m_collisionCategories |= CollisionCategories.Body; m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); @@ -1113,7 +1145,6 @@ Console.WriteLine("ZProcessTaints for " + Name); //Console.WriteLine(" Post GeomSetCategoryBits 2"); d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); - d.Quaternion quat2 = new d.Quaternion(); quat2.W = _orientation.W; quat2.X = _orientation.X; @@ -1135,7 +1166,6 @@ Console.WriteLine("ZProcessTaints for " + Name); d.BodySetAutoDisableFlag(Body, true); d.BodySetAutoDisableSteps(Body, body_autodisable_frames); - m_interpenetrationcount = 0; m_collisionscore = 0; m_disabled = false; @@ -1146,7 +1176,9 @@ Console.WriteLine("ZProcessTaints for " + Name); createAMotor(m_angularlock); } d.BodySetPosition(Body, Position.X, Position.Y, Position.Z); - if (m_vehicle.Type != Vehicle.TYPE_NONE) m_vehicle.Enable(Body, _parent_scene); + if (m_vehicle.Type != Vehicle.TYPE_NONE) + m_vehicle.Enable(Body, _parent_scene); + _parent_scene.addActivePrim(this); } } @@ -1156,7 +1188,7 @@ Console.WriteLine("ZProcessTaints for " + Name); private void ChildSetGeom(OdePrim odePrim) { - //if (m_isphysical && Body != IntPtr.Zero) + //if (IsPhysical && Body != IntPtr.Zero) lock (childrenPrim) { foreach (OdePrim prm in childrenPrim) @@ -1172,7 +1204,6 @@ Console.WriteLine("ZProcessTaints for " + Name); } disableBody(); - if (Body != IntPtr.Zero) { _parent_scene.remActivePrim(this); @@ -1183,10 +1214,9 @@ Console.WriteLine("ZProcessTaints for " + Name); foreach (OdePrim prm in childrenPrim) { //Console.WriteLine("ChildSetGeom calls ParentPrim"); - ParentPrim(prm); + AddChildPrim(prm); } } - } private void ChildDelink(OdePrim odePrim) @@ -1223,7 +1253,7 @@ Console.WriteLine("ZProcessTaints for " + Name); foreach (OdePrim prm in childrenPrim) { //Console.WriteLine("ChildDelink calls ParentPrim"); - ParentPrim(prm); + AddChildPrim(prm); } } } @@ -1257,7 +1287,7 @@ Console.WriteLine("ZProcessTaints for " + Name); // first 50 again. then the last 50 are disabled. then the first 50, which were just woken // up, start simulating again, which in turn wakes up the last 50. - if (m_isphysical) + if (IsPhysical) { disableBodySoft(); } @@ -1268,7 +1298,7 @@ Console.WriteLine("ZProcessTaints for " + Name); d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); } - if (m_isphysical) + if (IsPhysical) { disableBodySoft(); } @@ -1277,7 +1307,7 @@ Console.WriteLine("ZProcessTaints for " + Name); { m_collisionCategories = CollisionCategories.Geom; - if (m_isphysical) + if (IsPhysical) m_collisionCategories |= CollisionCategories.Body; m_collisionFlags = m_default_collisionFlags; @@ -1292,7 +1322,8 @@ Console.WriteLine("ZProcessTaints for " + Name); d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); } - if (m_isphysical) + + if (IsPhysical) { if (Body != IntPtr.Zero) { @@ -1311,7 +1342,7 @@ Console.WriteLine("ZProcessTaints for " + Name); { m_taintposition = _position; m_taintrot = _orientation; - m_taintPhysics = m_isphysical; + m_taintPhysics = IsPhysical; m_taintselected = m_isSelected; m_taintsize = _size; m_taintshape = false; @@ -1320,14 +1351,19 @@ Console.WriteLine("ZProcessTaints for " + Name); m_taintVelocity = Vector3.Zero; } - public void CreateGeom(IntPtr m_targetSpace, IMesh _mesh) + /// + /// Create a geometry for the given mesh in the given target space. + /// + /// + /// If null, then a mesh is used that is based on the profile shape data. + public void CreateGeom(IntPtr m_targetSpace, IMesh mesh) { #if SPAM Console.WriteLine("CreateGeom:"); #endif - if (_mesh != null) + if (mesh != null) { - setMesh(_parent_scene, _mesh); + setMesh(_parent_scene, mesh); } else { @@ -1400,6 +1436,39 @@ Console.WriteLine("CreateGeom:"); } } + /// + /// Remove the existing geom from this prim. + /// + /// + /// If null, then a mesh is used that is based on the profile shape data. + /// true if the geom was successfully removed, false if it was already gone or the remove failed. + public bool RemoveGeom() + { + if (prim_geom != IntPtr.Zero) + { + try + { + _parent_scene.geom_name_map.Remove(prim_geom); + _parent_scene.actor_name_map.Remove(prim_geom); + d.GeomDestroy(prim_geom); + prim_geom = IntPtr.Zero; + } + catch (System.AccessViolationException) + { + prim_geom = IntPtr.Zero; + m_log.ErrorFormat("[PHYSICS]: PrimGeom dead for {0}", Name); + + return false; + } + + return true; + } + else + { + return false; + } + } + public void changeadd(float timestep) { int[] iprimspaceArrItem = _parent_scene.calculateSpaceArrayItemFromPos(_position); @@ -1410,15 +1479,14 @@ Console.WriteLine("CreateGeom:"); m_targetSpace = targetspace; - if (_mesh == null) + IMesh mesh = null; + + if (_parent_scene.needsMeshing(_pbs)) { - if (_parent_scene.needsMeshing(_pbs)) - { - // Don't need to re-enable body.. it's done in SetMesh - _mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical); - // createmesh returns null when it's a shape that isn't a cube. - // m_log.Debug(m_localID); - } + // Don't need to re-enable body.. it's done in SetMesh + mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical); + // createmesh returns null when it's a shape that isn't a cube. + // m_log.Debug(m_localID); } lock (_parent_scene.OdeLock) @@ -1426,7 +1494,7 @@ Console.WriteLine("CreateGeom:"); #if SPAM Console.WriteLine("changeadd 1"); #endif - CreateGeom(m_targetSpace, _mesh); + CreateGeom(m_targetSpace, mesh); if (prim_geom != IntPtr.Zero) { @@ -1439,15 +1507,12 @@ Console.WriteLine("changeadd 1"); d.GeomSetQuaternion(prim_geom, ref myrot); } - if (m_isphysical && Body == IntPtr.Zero) + if (IsPhysical && Body == IntPtr.Zero) { enableBody(); } } - _parent_scene.geom_name_map[prim_geom] = this.Name; - _parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this; - changeSelectedStatus(timestep); m_taintadd = false; @@ -1455,9 +1520,8 @@ Console.WriteLine("changeadd 1"); public void changemove(float timestep) { - if (m_isphysical) + if (IsPhysical) { - if (!m_disabled && !m_taintremove && !childPrim) { if (Body == IntPtr.Zero) @@ -1789,7 +1853,7 @@ Console.WriteLine(" JointCreateFixed"); { // KF: If this is a root prim do BodySet d.BodySetQuaternion(Body, ref myrot); - if (m_isphysical) + if (IsPhysical) { if (!m_angularlock.ApproxEquals(Vector3.One, 0f)) createAMotor(m_angularlock); @@ -1826,7 +1890,7 @@ Console.WriteLine(" JointCreateFixed"); public void changePhysicsStatus(float timestep) { - if (m_isphysical == true) + if (IsPhysical) { if (Body == IntPtr.Zero) { @@ -1846,25 +1910,12 @@ Console.WriteLine(" JointCreateFixed"); { if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim) { - + RemoveGeom(); - if (prim_geom != IntPtr.Zero) - { - try - { - d.GeomDestroy(prim_geom); - prim_geom = IntPtr.Zero; - _mesh = null; - } - catch (System.AccessViolationException) - { - prim_geom = IntPtr.Zero; - m_log.ErrorFormat("[PHYSICS]: PrimGeom dead for {0}", Name); - } - } //Console.WriteLine("changePhysicsStatus for " + Name); changeadd(2f); } + if (childPrim) { if (_parent != null) @@ -1883,7 +1934,7 @@ Console.WriteLine(" JointCreateFixed"); changeSelectedStatus(timestep); resetCollisionAccounting(); - m_taintPhysics = m_isphysical; + m_taintPhysics = IsPhysical; } public void changesize(float timestamp) @@ -1892,18 +1943,10 @@ Console.WriteLine(" JointCreateFixed"); m_log.DebugFormat("[ODE PRIM]: Called changesize"); #endif - string oldname = _parent_scene.geom_name_map[prim_geom]; - if (_size.X <= 0) _size.X = 0.01f; if (_size.Y <= 0) _size.Y = 0.01f; if (_size.Z <= 0) _size.Z = 0.01f; - // Cleanup of old prim geometry - if (_mesh != null) - { - // TODO: Cleanup meshing here - } - //kill body to rebuild if (IsPhysical && Body != IntPtr.Zero) { @@ -1927,10 +1970,12 @@ Console.WriteLine(" JointCreateFixed"); d.SpaceRemove(m_targetSpace, prim_geom); } - d.GeomDestroy(prim_geom); - prim_geom = IntPtr.Zero; + RemoveGeom(); + // we don't need to do space calculation because the client sends a position update also. + IMesh mesh = null; + // Construction of new prim if (_parent_scene.needsMeshing(_pbs)) { @@ -1940,27 +1985,11 @@ Console.WriteLine(" JointCreateFixed"); meshlod = _parent_scene.MeshSculptphysicalLOD; // Don't need to re-enable body.. it's done in SetMesh - IMesh mesh = null; - if (_parent_scene.needsMeshing(_pbs)) - mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); - -#if SPAM -Console.WriteLine("changesize 1"); -#endif - CreateGeom(m_targetSpace, mesh); - } - else - { - _mesh = null; - -#if SPAM -Console.WriteLine("changesize 2"); -#endif - - CreateGeom(m_targetSpace, _mesh); + mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, meshlod, IsPhysical); } + CreateGeom(m_targetSpace, mesh); d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); d.Quaternion myrot = new d.Quaternion(); myrot.X = _orientation.X; @@ -1978,8 +2007,6 @@ Console.WriteLine("changesize 2"); d.BodyEnable(Body); } - _parent_scene.geom_name_map[prim_geom] = oldname; - changeSelectedStatus(timestamp); if (childPrim) { @@ -2013,8 +2040,6 @@ Console.WriteLine("changesize 2"); public void changeshape(float timestamp) { - string oldname = _parent_scene.geom_name_map[prim_geom]; - // Cleanup of old prim geometry and Bodies if (IsPhysical && Body != IntPtr.Zero) { @@ -2031,23 +2056,17 @@ Console.WriteLine("changesize 2"); disableBody(); } } - try - { - d.GeomDestroy(prim_geom); - } - catch (System.AccessViolationException) - { - prim_geom = IntPtr.Zero; - m_log.ErrorFormat("[PHYSICS]: PrimGeom dead for {0}", Name); - } - prim_geom = IntPtr.Zero; + RemoveGeom(); + // we don't need to do space calculation because the client sends a position update also. if (_size.X <= 0) _size.X = 0.01f; if (_size.Y <= 0) _size.Y = 0.01f; if (_size.Z <= 0) _size.Z = 0.01f; // Construction of new prim + IMesh mesh = null; + if (_parent_scene.needsMeshing(_pbs)) { // Don't need to re-enable body.. it's done in CreateMesh @@ -2057,22 +2076,10 @@ Console.WriteLine("changesize 2"); meshlod = _parent_scene.MeshSculptphysicalLOD; // createmesh returns null when it doesn't mesh. - IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); -#if SPAM -Console.WriteLine("changeshape needed meshing"); -#endif - CreateGeom(m_targetSpace, mesh); - } - else - { - _mesh = null; - -#if SPAM -Console.WriteLine("changeshape not need meshing"); -#endif - CreateGeom(m_targetSpace, null); + mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, meshlod, IsPhysical); } + CreateGeom(m_targetSpace, mesh); d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); d.Quaternion myrot = new d.Quaternion(); //myrot.W = _orientation.w; @@ -2093,7 +2100,6 @@ Console.WriteLine("changeshape not need meshing"); d.BodyEnable(Body); } } - _parent_scene.geom_name_map[prim_geom] = oldname; changeSelectedStatus(timestamp); if (childPrim) @@ -2216,16 +2222,6 @@ Console.WriteLine("changeshape not need meshing"); m_taintVelocity = Vector3.Zero; } - public override bool IsPhysical - { - get { return m_isphysical; } - set { - m_isphysical = value; - if (!m_isphysical) // Zero the remembered last velocity - m_lastVelocity = Vector3.Zero; - } - } - public void setPrimForRemoval() { m_taintremove = true; @@ -2404,7 +2400,7 @@ Console.WriteLine("changeshape not need meshing"); { get { - if (!m_isphysical || Body == IntPtr.Zero) + if (!IsPhysical || Body == IntPtr.Zero) return Vector3.Zero; return _torque; @@ -2986,12 +2982,12 @@ Console.WriteLine("changeshape not need meshing"); public override void SubscribeEvents(int ms) { m_eventsubscription = ms; - _parent_scene.addCollisionEventReporting(this); + _parent_scene.AddCollisionEventReporting(this); } public override void UnSubscribeEvents() { - _parent_scene.remCollisionEventReporting(this); + _parent_scene.RemoveCollisionEventReporting(this); m_eventsubscription = 0; } @@ -2999,6 +2995,7 @@ Console.WriteLine("changeshape not need meshing"); { if (CollisionEventsThisFrame == null) CollisionEventsThisFrame = new CollisionEventUpdate(); + CollisionEventsThisFrame.addCollider(CollidedWith, contact); } diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index a3074691fc..6e603e8f4f 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -100,7 +100,7 @@ namespace OpenSim.Region.Physics.OdePlugin Rubber = 6 } - public sealed class OdeScene : PhysicsScene + public class OdeScene : PhysicsScene { private readonly ILog m_log; // private Dictionary m_storedCollisions = new Dictionary(); @@ -198,7 +198,12 @@ namespace OpenSim.Region.Physics.OdePlugin private readonly List _taintedPrimL = new List(); private readonly HashSet _taintedActors = new HashSet(); private readonly List _perloopContact = new List(); + + /// + /// A list of actors that should receive collision events. + /// private readonly List _collisionEventPrim = new List(); + private readonly HashSet _badCharacter = new HashSet(); public Dictionary geom_name_map = new Dictionary(); public Dictionary actor_name_map = new Dictionary(); @@ -299,7 +304,6 @@ namespace OpenSim.Region.Physics.OdePlugin // Create the world and the first space world = d.WorldCreate(); space = d.HashSpaceCreate(IntPtr.Zero); - contactgroup = d.JointGroupCreate(0); //contactgroup @@ -952,7 +956,6 @@ namespace OpenSim.Region.Physics.OdePlugin character.SetPidStatus(true); } } - if (p1.PhysicsActorType == (int) ActorTypes.Agent) { @@ -1053,9 +1056,7 @@ namespace OpenSim.Region.Physics.OdePlugin { joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]); m_global_contactcount++; - } - } else { @@ -1078,7 +1079,6 @@ namespace OpenSim.Region.Physics.OdePlugin { joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]); m_global_contactcount++; - } } } @@ -1290,6 +1290,7 @@ namespace OpenSim.Region.Physics.OdePlugin //returncollisions = true; break; + case ActorTypes.Prim: if (p1 is OdePrim) { @@ -1317,6 +1318,7 @@ namespace OpenSim.Region.Physics.OdePlugin cc2.AddCollisionEvent(obj2LocalID, contact); break; + case ActorTypes.Prim: if (p2 is OdePrim) @@ -1421,18 +1423,18 @@ namespace OpenSim.Region.Physics.OdePlugin public int TriCallback(IntPtr trimesh, IntPtr refObject, int triangleIndex) { - String name1 = null; - String name2 = null; - - if (!geom_name_map.TryGetValue(trimesh, out name1)) - { - name1 = "null"; - } - - if (!geom_name_map.TryGetValue(refObject, out name2)) - { - name2 = "null"; - } +// String name1 = null; +// String name2 = null; +// +// if (!geom_name_map.TryGetValue(trimesh, out name1)) +// { +// name1 = "null"; +// } +// +// if (!geom_name_map.TryGetValue(refObject, out name2)) +// { +// name2 = "null"; +// } // m_log.InfoFormat("TriCallback: A collision was detected between {1} and {2}. Index was {3}", 0, name1, name2, triangleIndex); @@ -1604,7 +1606,11 @@ namespace OpenSim.Region.Physics.OdePlugin } // End recovered. Kitto Flora - public void addCollisionEventReporting(PhysicsActor obj) + /// + /// Add actor to the list that should receive collision events in the simulate loop. + /// + /// + public void AddCollisionEventReporting(PhysicsActor obj) { lock (_collisionEventPrim) { @@ -1613,7 +1619,11 @@ namespace OpenSim.Region.Physics.OdePlugin } } - public void remCollisionEventReporting(PhysicsActor obj) + /// + /// Remove actor from the list that should receive collision events in the simulate loop. + /// + /// + public void RemoveCollisionEventReporting(PhysicsActor obj) { lock (_collisionEventPrim) { @@ -1677,7 +1687,7 @@ namespace OpenSim.Region.Physics.OdePlugin } private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation, - IMesh mesh, PrimitiveBaseShape pbs, bool isphysical, uint localID) + PrimitiveBaseShape pbs, bool isphysical, uint localID) { Vector3 pos = position; Vector3 siz = size; @@ -1686,7 +1696,7 @@ namespace OpenSim.Region.Physics.OdePlugin OdePrim newPrim; lock (OdeLock) { - newPrim = new OdePrim(name, this, pos, siz, rot, mesh, pbs, isphysical, ode); + newPrim = new OdePrim(name, this, pos, siz, rot, pbs, isphysical, ode); lock (_prims) _prims.Add(newPrim); @@ -1714,28 +1724,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_log.DebugFormat("[PHYSICS]: Adding physics actor to {0}", primName); #endif - PhysicsActor result; - IMesh mesh = null; - - // Don't create the mesh here - wait until the mesh data is loaded from the asset store. -// if (needsMeshing(pbs)) -// { -// try -// { -// mesh = mesher.CreateMesh(primName, pbs, size, 32f, isPhysical); -// } -// catch(Exception e) -// { -// m_log.ErrorFormat("[PHYSICS]: Exception while meshing prim {0}.", primName); -// m_log.Debug(e.ToString()); -// mesh = null; -// return null; -// } -// } - - result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical, localid); - - return result; + return AddPrim(primName, position, size, rotation, pbs, isPhysical, localid); } public override float TimeDilation @@ -2105,6 +2094,8 @@ namespace OpenSim.Region.Physics.OdePlugin public override void RemovePrim(PhysicsActor prim) { + // As with all ODE physics operations, we don't remove the prim immediately but signal that it should be + // removed in the next physics simulate pass. if (prim is OdePrim) { lock (OdeLock) @@ -2121,6 +2112,9 @@ namespace OpenSim.Region.Physics.OdePlugin /// /// This is called from within simulate but outside the locked portion /// We need to do our own locking here + /// (Note: As of 20110801 this no longer appears to be true - this is being called within lock (odeLock) in + /// Simulate() -- justincc). + /// /// Essentially, we need to remove the prim from our space segment, whatever segment it's in. /// /// If there are no more prim in the segment, we need to empty (spacedestroy)the segment and reclaim memory @@ -2132,7 +2126,7 @@ namespace OpenSim.Region.Physics.OdePlugin //Console.WriteLine("RemovePrimThreadLocked " + prim.m_primName); lock (prim) { - remCollisionEventReporting(prim); + RemoveCollisionEventReporting(prim); lock (ode) { if (prim.prim_geom != IntPtr.Zero) @@ -2177,24 +2171,12 @@ namespace OpenSim.Region.Physics.OdePlugin //} //} //m_log.Warn(prim.prim_geom); - try - { - if (prim.prim_geom != IntPtr.Zero) - { - d.GeomDestroy(prim.prim_geom); - prim.prim_geom = IntPtr.Zero; - } - else - { - m_log.Warn("[PHYSICS]: Unable to remove prim from physics scene"); - } - } - catch (AccessViolationException) - { - m_log.Info("[PHYSICS]: Couldn't remove prim from physics scene, it was already be removed."); - } + + if (!prim.RemoveGeom()) + m_log.Warn("[PHYSICS]: Unable to remove prim from physics scene"); + lock (_prims) - _prims.Remove(prim); + _prims.Remove(prim); //If there are no more geometries in the sub-space, we don't need it in the main space anymore //if (d.SpaceGetNumGeoms(prim.m_targetSpace) == 0) @@ -2687,320 +2669,148 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); //if (!ode.lockquery()) //{ // ode.dlock(world); - try - { - // Insert, remove Characters - bool processedtaints = false; - lock (_taintedActors) - { - if (_taintedActors.Count > 0) - { - foreach (OdeCharacter character in _taintedActors) - { - character.ProcessTaints(timeStep); + try + { + // Insert, remove Characters + bool processedtaints = false; - processedtaints = true; - //character.m_collisionscore = 0; - } - - if (processedtaints) - _taintedActors.Clear(); - } - } - - // Modify other objects in the scene. - processedtaints = false; - - lock (_taintedPrimLock) - { - foreach (OdePrim prim in _taintedPrimL) - { - if (prim.m_taintremove) - { - //Console.WriteLine("Simulate calls RemovePrimThreadLocked"); - RemovePrimThreadLocked(prim); - } - else - { - //Console.WriteLine("Simulate calls ProcessTaints"); - prim.ProcessTaints(timeStep); - } - processedtaints = true; - prim.m_collisionscore = 0; - - // This loop can block up the Heartbeat for a very long time on large regions. - // We need to let the Watchdog know that the Heartbeat is not dead - // NOTE: This is currently commented out, but if things like OAR loading are - // timing the heartbeat out we will need to uncomment it - //Watchdog.UpdateThread(); - } - - if (SupportsNINJAJoints) - { - // Create pending joints, if possible - - // joints can only be processed after ALL bodies are processed (and exist in ODE), since creating - // a joint requires specifying the body id of both involved bodies - if (pendingJoints.Count > 0) - { - List successfullyProcessedPendingJoints = new List(); - //DoJointErrorMessage(joints_connecting_actor, "taint: " + pendingJoints.Count + " pending joints"); - foreach (PhysicsJoint joint in pendingJoints) - { - //DoJointErrorMessage(joint, "taint: time to create joint with parms: " + joint.RawParams); - string[] jointParams = joint.RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries); - List jointBodies = new List(); - bool allJointBodiesAreReady = true; - foreach (string jointParam in jointParams) - { - if (jointParam == "NULL") - { - //DoJointErrorMessage(joint, "attaching NULL joint to world"); - jointBodies.Add(IntPtr.Zero); - } - else - { - //DoJointErrorMessage(joint, "looking for prim name: " + jointParam); - bool foundPrim = false; - lock (_prims) - { - foreach (OdePrim prim in _prims) // FIXME: inefficient - { - if (prim.SOPName == jointParam) - { - //DoJointErrorMessage(joint, "found for prim name: " + jointParam); - if (prim.IsPhysical && prim.Body != IntPtr.Zero) - { - jointBodies.Add(prim.Body); - foundPrim = true; - break; - } - else - { - DoJointErrorMessage(joint, "prim name " + jointParam + - " exists but is not (yet) physical; deferring joint creation. " + - "IsPhysical property is " + prim.IsPhysical + - " and body is " + prim.Body); - foundPrim = false; - break; - } - } - } - } - if (foundPrim) - { - // all is fine - } - else - { - allJointBodiesAreReady = false; - break; - } - } - } - if (allJointBodiesAreReady) - { - //DoJointErrorMessage(joint, "allJointBodiesAreReady for " + joint.ObjectNameInScene + " with parms " + joint.RawParams); - if (jointBodies[0] == jointBodies[1]) - { - DoJointErrorMessage(joint, "ERROR: joint cannot be created; the joint bodies are the same, body1==body2. Raw body is " + jointBodies[0] + ". raw parms: " + joint.RawParams); - } - else - { - switch (joint.Type) - { - case PhysicsJointType.Ball: - { - IntPtr odeJoint; - //DoJointErrorMessage(joint, "ODE creating ball joint "); - odeJoint = d.JointCreateBall(world, IntPtr.Zero); - //DoJointErrorMessage(joint, "ODE attaching ball joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]); - d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]); - //DoJointErrorMessage(joint, "ODE setting ball anchor: " + odeJoint + " to vec:" + joint.Position); - d.JointSetBallAnchor(odeJoint, - joint.Position.X, - joint.Position.Y, - joint.Position.Z); - //DoJointErrorMessage(joint, "ODE joint setting OK"); - //DoJointErrorMessage(joint, "The ball joint's bodies are here: b0: "); - //DoJointErrorMessage(joint, "" + (jointBodies[0] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[0]) : "fixed environment")); - //DoJointErrorMessage(joint, "The ball joint's bodies are here: b1: "); - //DoJointErrorMessage(joint, "" + (jointBodies[1] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[1]) : "fixed environment")); - - if (joint is OdePhysicsJoint) - { - ((OdePhysicsJoint)joint).jointID = odeJoint; - } - else - { - DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!"); - } - } - break; - case PhysicsJointType.Hinge: - { - IntPtr odeJoint; - //DoJointErrorMessage(joint, "ODE creating hinge joint "); - odeJoint = d.JointCreateHinge(world, IntPtr.Zero); - //DoJointErrorMessage(joint, "ODE attaching hinge joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]); - d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]); - //DoJointErrorMessage(joint, "ODE setting hinge anchor: " + odeJoint + " to vec:" + joint.Position); - d.JointSetHingeAnchor(odeJoint, - joint.Position.X, - joint.Position.Y, - joint.Position.Z); - // We use the orientation of the x-axis of the joint's coordinate frame - // as the axis for the hinge. - - // Therefore, we must get the joint's coordinate frame based on the - // joint.Rotation field, which originates from the orientation of the - // joint's proxy object in the scene. - - // The joint's coordinate frame is defined as the transformation matrix - // that converts a vector from joint-local coordinates into world coordinates. - // World coordinates are defined as the XYZ coordinate system of the sim, - // as shown in the top status-bar of the viewer. - - // Once we have the joint's coordinate frame, we extract its X axis (AtAxis) - // and use that as the hinge axis. - - //joint.Rotation.Normalize(); - Matrix4 proxyFrame = Matrix4.CreateFromQuaternion(joint.Rotation); - - // Now extract the X axis of the joint's coordinate frame. - - // Do not try to use proxyFrame.AtAxis or you will become mired in the - // tar pit of transposed, inverted, and generally messed-up orientations. - // (In other words, Matrix4.AtAxis() is borked.) - // Vector3 jointAxis = proxyFrame.AtAxis; <--- this path leadeth to madness - - // Instead, compute the X axis of the coordinate frame by transforming - // the (1,0,0) vector. At least that works. - - //m_log.Debug("PHY: making axis: complete matrix is " + proxyFrame); - Vector3 jointAxis = Vector3.Transform(Vector3.UnitX, proxyFrame); - //m_log.Debug("PHY: making axis: hinge joint axis is " + jointAxis); - //DoJointErrorMessage(joint, "ODE setting hinge axis: " + odeJoint + " to vec:" + jointAxis); - d.JointSetHingeAxis(odeJoint, - jointAxis.X, - jointAxis.Y, - jointAxis.Z); - //d.JointSetHingeParam(odeJoint, (int)dParam.CFM, 0.1f); - if (joint is OdePhysicsJoint) - { - ((OdePhysicsJoint)joint).jointID = odeJoint; - } - else - { - DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!"); - } - } - break; - } - successfullyProcessedPendingJoints.Add(joint); - } - } - else - { - DoJointErrorMessage(joint, "joint could not yet be created; still pending"); - } - } - foreach (PhysicsJoint successfullyProcessedJoint in successfullyProcessedPendingJoints) - { - //DoJointErrorMessage(successfullyProcessedJoint, "finalizing succesfully procsssed joint " + successfullyProcessedJoint.ObjectNameInScene + " parms " + successfullyProcessedJoint.RawParams); - //DoJointErrorMessage(successfullyProcessedJoint, "removing from pending"); - InternalRemovePendingJoint(successfullyProcessedJoint); - //DoJointErrorMessage(successfullyProcessedJoint, "adding to active"); - InternalAddActiveJoint(successfullyProcessedJoint); - //DoJointErrorMessage(successfullyProcessedJoint, "done"); - } - } - } - - if (processedtaints) -//Console.WriteLine("Simulate calls Clear of _taintedPrim list"); - _taintedPrimH.Clear(); - _taintedPrimL.Clear(); - } - - // Move characters - lock (_characters) - { - List defects = new List(); - foreach (OdeCharacter actor in _characters) - { - if (actor != null) - actor.Move(timeStep, defects); - } - if (0 != defects.Count) - { - foreach (OdeCharacter defect in defects) - { - RemoveCharacter(defect); - } - } - } - - // Move other active objects - lock (_activeprims) - { - foreach (OdePrim prim in _activeprims) - { - prim.m_collisionscore = 0; - prim.Move(timeStep); - } - } - - //if ((framecount % m_randomizeWater) == 0) - // randomizeWater(waterlevel); - - //int RayCastTimeMS = m_rayCastManager.ProcessQueuedRequests(); - m_rayCastManager.ProcessQueuedRequests(); - - collision_optimized(timeStep); - - lock (_collisionEventPrim) - { - foreach (PhysicsActor obj in _collisionEventPrim) - { - if (obj == null) - continue; - - switch ((ActorTypes)obj.PhysicsActorType) - { - case ActorTypes.Agent: - OdeCharacter cobj = (OdeCharacter)obj; - cobj.AddCollisionFrameTime(100); - cobj.SendCollisions(); - break; - case ActorTypes.Prim: - OdePrim pobj = (OdePrim)obj; - pobj.SendCollisions(); - break; - } - } - } - - //if (m_global_contactcount > 5) - //{ - // m_log.DebugFormat("[PHYSICS]: Contacts:{0}", m_global_contactcount); - //} - - m_global_contactcount = 0; - - d.WorldQuickStep(world, ODE_STEPSIZE); - d.JointGroupEmpty(contactgroup); - //ode.dunlock(world); - } - catch (Exception e) + lock (_taintedActors) + { + if (_taintedActors.Count > 0) { - m_log.ErrorFormat("[PHYSICS]: {0}, {1}, {2}", e.Message, e.TargetSite, e); - ode.dunlock(world); + foreach (OdeCharacter character in _taintedActors) + { + character.ProcessTaints(timeStep); + + processedtaints = true; + //character.m_collisionscore = 0; + } + + if (processedtaints) + _taintedActors.Clear(); + } + } + + // Modify other objects in the scene. + processedtaints = false; + + lock (_taintedPrimLock) + { + foreach (OdePrim prim in _taintedPrimL) + { + if (prim.m_taintremove) + { +// Console.WriteLine("Simulate calls RemovePrimThreadLocked for {0}", prim.Name); + RemovePrimThreadLocked(prim); + } + else + { +// Console.WriteLine("Simulate calls ProcessTaints for {0}", prim.Name); + prim.ProcessTaints(timeStep); + } + + processedtaints = true; + prim.m_collisionscore = 0; + + // This loop can block up the Heartbeat for a very long time on large regions. + // We need to let the Watchdog know that the Heartbeat is not dead + // NOTE: This is currently commented out, but if things like OAR loading are + // timing the heartbeat out we will need to uncomment it + //Watchdog.UpdateThread(); } - step_time -= ODE_STEPSIZE; - i++; + if (SupportsNINJAJoints) + SimulatePendingNINJAJoints(); + + if (processedtaints) + { +//Console.WriteLine("Simulate calls Clear of _taintedPrim list"); + _taintedPrimH.Clear(); + _taintedPrimL.Clear(); + } + } + + // Move characters + lock (_characters) + { + List defects = new List(); + foreach (OdeCharacter actor in _characters) + { + if (actor != null) + actor.Move(timeStep, defects); + } + if (0 != defects.Count) + { + foreach (OdeCharacter defect in defects) + { + RemoveCharacter(defect); + } + } + } + + // Move other active objects + lock (_activeprims) + { + foreach (OdePrim prim in _activeprims) + { + prim.m_collisionscore = 0; + prim.Move(timeStep); + } + } + + //if ((framecount % m_randomizeWater) == 0) + // randomizeWater(waterlevel); + + //int RayCastTimeMS = m_rayCastManager.ProcessQueuedRequests(); + m_rayCastManager.ProcessQueuedRequests(); + + collision_optimized(timeStep); + + lock (_collisionEventPrim) + { + foreach (PhysicsActor obj in _collisionEventPrim) + { + if (obj == null) + continue; + +// m_log.DebugFormat("[PHYSICS]: Assessing {0} for collision events", obj.SOPName); + + switch ((ActorTypes)obj.PhysicsActorType) + { + case ActorTypes.Agent: + OdeCharacter cobj = (OdeCharacter)obj; + cobj.AddCollisionFrameTime(100); + cobj.SendCollisions(); + break; + + case ActorTypes.Prim: + OdePrim pobj = (OdePrim)obj; + pobj.SendCollisions(); + break; + } + } + } + + //if (m_global_contactcount > 5) + //{ + // m_log.DebugFormat("[PHYSICS]: Contacts:{0}", m_global_contactcount); + //} + + m_global_contactcount = 0; + + d.WorldQuickStep(world, ODE_STEPSIZE); + d.JointGroupEmpty(contactgroup); + //ode.dunlock(world); + } + catch (Exception e) + { + m_log.ErrorFormat("[PHYSICS]: {0}, {1}, {2}", e.Message, e.TargetSite, e); + ode.dunlock(world); + } + + step_time -= ODE_STEPSIZE; + i++; //} //else //{ @@ -3017,6 +2827,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); { if (actor.bad) m_log.WarnFormat("[PHYSICS]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid); + actor.UpdatePositionAndVelocity(); } } @@ -3030,6 +2841,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); { RemoveCharacter(chr); } + _badCharacter.Clear(); } } @@ -3045,30 +2857,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); actor.UpdatePositionAndVelocity(); if (SupportsNINJAJoints) - { - // If an actor moved, move its joint proxy objects as well. - // There seems to be an event PhysicsActor.OnPositionUpdate that could be used - // for this purpose but it is never called! So we just do the joint - // movement code here. - - if (actor.SOPName != null && - joints_connecting_actor.ContainsKey(actor.SOPName) && - joints_connecting_actor[actor.SOPName] != null && - joints_connecting_actor[actor.SOPName].Count > 0) - { - foreach (PhysicsJoint affectedJoint in joints_connecting_actor[actor.SOPName]) - { - if (affectedJoint.IsInPhysicsEngine) - { - DoJointMoved(affectedJoint); - } - else - { - DoJointErrorMessage(affectedJoint, "a body connected to a joint was moved, but the joint doesn't exist yet! this will lead to joint error. joint was: " + affectedJoint.ObjectNameInScene + " parms:" + affectedJoint.RawParams); - } - } - } - } + SimulateActorPendingJoints(actor); } } } @@ -3079,7 +2868,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); // Finished with all sim stepping. If requested, dump world state to file for debugging. // TODO: This call to the export function is already inside lock (OdeLock) - but is an extra lock needed? // TODO: This overwrites all dump files in-place. Should this be a growing logfile, or separate snapshots? - if (physics_logging && (physics_logging_interval>0) && (framecount % physics_logging_interval == 0)) + if (physics_logging && (physics_logging_interval > 0) && (framecount % physics_logging_interval == 0)) { string fname = "state-" + world.ToString() + ".DIF"; // give each physics world a separate filename string prefix = "world" + world.ToString(); // prefix for variable names in exported .DIF file @@ -3091,8 +2880,10 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); fwriter.WriteLine(header); fwriter.Close(); } + d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix); } + latertickcount = Util.EnvironmentTickCount() - tickCountFrameRun; // OpenSimulator above does 10 fps. 10 fps = means that the main thread loop and physics @@ -3101,7 +2892,9 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); // If Physics stalls, it takes longer which makes the tick count ms larger. if (latertickcount < 100) + { m_timeDilation = 1.0f; + } else { m_timeDilation = 100f / latertickcount; @@ -3114,6 +2907,229 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); return fps; } + /// + /// Simulate pending NINJA joints. + /// + /// + /// Called by the main Simulate() loop if NINJA joints are active. Should not be called from anywhere else. + /// + protected void SimulatePendingNINJAJoints() + { + // Create pending joints, if possible + + // joints can only be processed after ALL bodies are processed (and exist in ODE), since creating + // a joint requires specifying the body id of both involved bodies + if (pendingJoints.Count > 0) + { + List successfullyProcessedPendingJoints = new List(); + //DoJointErrorMessage(joints_connecting_actor, "taint: " + pendingJoints.Count + " pending joints"); + foreach (PhysicsJoint joint in pendingJoints) + { + //DoJointErrorMessage(joint, "taint: time to create joint with parms: " + joint.RawParams); + string[] jointParams = joint.RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries); + List jointBodies = new List(); + bool allJointBodiesAreReady = true; + foreach (string jointParam in jointParams) + { + if (jointParam == "NULL") + { + //DoJointErrorMessage(joint, "attaching NULL joint to world"); + jointBodies.Add(IntPtr.Zero); + } + else + { + //DoJointErrorMessage(joint, "looking for prim name: " + jointParam); + bool foundPrim = false; + lock (_prims) + { + foreach (OdePrim prim in _prims) // FIXME: inefficient + { + if (prim.SOPName == jointParam) + { + //DoJointErrorMessage(joint, "found for prim name: " + jointParam); + if (prim.IsPhysical && prim.Body != IntPtr.Zero) + { + jointBodies.Add(prim.Body); + foundPrim = true; + break; + } + else + { + DoJointErrorMessage(joint, "prim name " + jointParam + + " exists but is not (yet) physical; deferring joint creation. " + + "IsPhysical property is " + prim.IsPhysical + + " and body is " + prim.Body); + foundPrim = false; + break; + } + } + } + } + if (foundPrim) + { + // all is fine + } + else + { + allJointBodiesAreReady = false; + break; + } + } + } + + if (allJointBodiesAreReady) + { + //DoJointErrorMessage(joint, "allJointBodiesAreReady for " + joint.ObjectNameInScene + " with parms " + joint.RawParams); + if (jointBodies[0] == jointBodies[1]) + { + DoJointErrorMessage(joint, "ERROR: joint cannot be created; the joint bodies are the same, body1==body2. Raw body is " + jointBodies[0] + ". raw parms: " + joint.RawParams); + } + else + { + switch (joint.Type) + { + case PhysicsJointType.Ball: + { + IntPtr odeJoint; + //DoJointErrorMessage(joint, "ODE creating ball joint "); + odeJoint = d.JointCreateBall(world, IntPtr.Zero); + //DoJointErrorMessage(joint, "ODE attaching ball joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]); + d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]); + //DoJointErrorMessage(joint, "ODE setting ball anchor: " + odeJoint + " to vec:" + joint.Position); + d.JointSetBallAnchor(odeJoint, + joint.Position.X, + joint.Position.Y, + joint.Position.Z); + //DoJointErrorMessage(joint, "ODE joint setting OK"); + //DoJointErrorMessage(joint, "The ball joint's bodies are here: b0: "); + //DoJointErrorMessage(joint, "" + (jointBodies[0] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[0]) : "fixed environment")); + //DoJointErrorMessage(joint, "The ball joint's bodies are here: b1: "); + //DoJointErrorMessage(joint, "" + (jointBodies[1] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[1]) : "fixed environment")); + + if (joint is OdePhysicsJoint) + { + ((OdePhysicsJoint)joint).jointID = odeJoint; + } + else + { + DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!"); + } + } + break; + case PhysicsJointType.Hinge: + { + IntPtr odeJoint; + //DoJointErrorMessage(joint, "ODE creating hinge joint "); + odeJoint = d.JointCreateHinge(world, IntPtr.Zero); + //DoJointErrorMessage(joint, "ODE attaching hinge joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]); + d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]); + //DoJointErrorMessage(joint, "ODE setting hinge anchor: " + odeJoint + " to vec:" + joint.Position); + d.JointSetHingeAnchor(odeJoint, + joint.Position.X, + joint.Position.Y, + joint.Position.Z); + // We use the orientation of the x-axis of the joint's coordinate frame + // as the axis for the hinge. + + // Therefore, we must get the joint's coordinate frame based on the + // joint.Rotation field, which originates from the orientation of the + // joint's proxy object in the scene. + + // The joint's coordinate frame is defined as the transformation matrix + // that converts a vector from joint-local coordinates into world coordinates. + // World coordinates are defined as the XYZ coordinate system of the sim, + // as shown in the top status-bar of the viewer. + + // Once we have the joint's coordinate frame, we extract its X axis (AtAxis) + // and use that as the hinge axis. + + //joint.Rotation.Normalize(); + Matrix4 proxyFrame = Matrix4.CreateFromQuaternion(joint.Rotation); + + // Now extract the X axis of the joint's coordinate frame. + + // Do not try to use proxyFrame.AtAxis or you will become mired in the + // tar pit of transposed, inverted, and generally messed-up orientations. + // (In other words, Matrix4.AtAxis() is borked.) + // Vector3 jointAxis = proxyFrame.AtAxis; <--- this path leadeth to madness + + // Instead, compute the X axis of the coordinate frame by transforming + // the (1,0,0) vector. At least that works. + + //m_log.Debug("PHY: making axis: complete matrix is " + proxyFrame); + Vector3 jointAxis = Vector3.Transform(Vector3.UnitX, proxyFrame); + //m_log.Debug("PHY: making axis: hinge joint axis is " + jointAxis); + //DoJointErrorMessage(joint, "ODE setting hinge axis: " + odeJoint + " to vec:" + jointAxis); + d.JointSetHingeAxis(odeJoint, + jointAxis.X, + jointAxis.Y, + jointAxis.Z); + //d.JointSetHingeParam(odeJoint, (int)dParam.CFM, 0.1f); + if (joint is OdePhysicsJoint) + { + ((OdePhysicsJoint)joint).jointID = odeJoint; + } + else + { + DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!"); + } + } + break; + } + successfullyProcessedPendingJoints.Add(joint); + } + } + else + { + DoJointErrorMessage(joint, "joint could not yet be created; still pending"); + } + } + + foreach (PhysicsJoint successfullyProcessedJoint in successfullyProcessedPendingJoints) + { + //DoJointErrorMessage(successfullyProcessedJoint, "finalizing succesfully procsssed joint " + successfullyProcessedJoint.ObjectNameInScene + " parms " + successfullyProcessedJoint.RawParams); + //DoJointErrorMessage(successfullyProcessedJoint, "removing from pending"); + InternalRemovePendingJoint(successfullyProcessedJoint); + //DoJointErrorMessage(successfullyProcessedJoint, "adding to active"); + InternalAddActiveJoint(successfullyProcessedJoint); + //DoJointErrorMessage(successfullyProcessedJoint, "done"); + } + } + } + + /// + /// Simulate the joint proxies of a NINJA actor. + /// + /// + /// Called as part of the Simulate() loop if NINJA physics is active. Must only be called from there. + /// + /// + protected void SimulateActorPendingJoints(OdePrim actor) + { + // If an actor moved, move its joint proxy objects as well. + // There seems to be an event PhysicsActor.OnPositionUpdate that could be used + // for this purpose but it is never called! So we just do the joint + // movement code here. + + if (actor.SOPName != null && + joints_connecting_actor.ContainsKey(actor.SOPName) && + joints_connecting_actor[actor.SOPName] != null && + joints_connecting_actor[actor.SOPName].Count > 0) + { + foreach (PhysicsJoint affectedJoint in joints_connecting_actor[actor.SOPName]) + { + if (affectedJoint.IsInPhysicsEngine) + { + DoJointMoved(affectedJoint); + } + else + { + DoJointErrorMessage(affectedJoint, "a body connected to a joint was moved, but the joint doesn't exist yet! this will lead to joint error. joint was: " + affectedJoint.ObjectNameInScene + " parms:" + affectedJoint.RawParams); + } + } + } + } + public override void GetResults() { } @@ -3459,24 +3475,21 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); float hfmin = 2000; float hfmax = -2000; - for (int x = 0; x < heightmapWidthSamples; x++) + for (int x = 0; x < heightmapWidthSamples; x++) + { + for (int y = 0; y < heightmapHeightSamples; y++) { - for (int y = 0; y < heightmapHeightSamples; y++) - { - int xx = Util.Clip(x - 1, 0, regionsize - 1); - int yy = Util.Clip(y - 1, 0, regionsize - 1); - - - float val= heightMap[yy * (int)Constants.RegionSize + xx]; - _heightmap[x * ((int)Constants.RegionSize + 2) + y] = val; - - hfmin = (val < hfmin) ? val : hfmin; - hfmax = (val > hfmax) ? val : hfmax; - } + int xx = Util.Clip(x - 1, 0, regionsize - 1); + int yy = Util.Clip(y - 1, 0, regionsize - 1); + + + float val= heightMap[yy * (int)Constants.RegionSize + xx]; + _heightmap[x * ((int)Constants.RegionSize + 2) + y] = val; + + hfmin = (val < hfmin) ? val : hfmin; + hfmax = (val > hfmax) ? val : hfmax; } - - - + } lock (OdeLock) { @@ -3531,7 +3544,6 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); } RegionTerrain.Add(pOffset, GroundGeom, GroundGeom); TerrainHeightFieldHeights.Add(GroundGeom,_heightmap); - } } @@ -3694,6 +3706,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); //d.CloseODE(); } } + public override Dictionary GetTopColliders() { Dictionary returncolliders = new Dictionary(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index b7102290d6..8093502ccc 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2110,7 +2110,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (module != null) { Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z); - module.Autopilot(new UUID(npc.m_string), World, pos); + module.MoveToTarget(new UUID(npc.m_string), World, pos); } } diff --git a/OpenSim/Server/Handlers/Authorization/AuthorizationServerPostHandler.cs b/OpenSim/Server/Handlers/Authorization/AuthorizationServerPostHandler.cs index f987de4ef1..d656238cf0 100644 --- a/OpenSim/Server/Handlers/Authorization/AuthorizationServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Authorization/AuthorizationServerPostHandler.cs @@ -61,7 +61,7 @@ namespace OpenSim.Server.Handlers.Authorization AuthorizationRequest Authorization = (AuthorizationRequest) xs.Deserialize(request); string message = String.Empty; - bool authorized = m_AuthorizationService.IsAuthorizedForRegion(Authorization.ID, Authorization.RegionID,out message); + bool authorized = m_AuthorizationService.IsAuthorizedForRegion(Authorization.ID, Authorization.FirstName, Authorization.SurName, Authorization.RegionID, out message); AuthorizationResponse result = new AuthorizationResponse(authorized, Authorization.ID + " has been authorized"); diff --git a/OpenSim/Services/AuthorizationService/AuthorizationService.cs b/OpenSim/Services/AuthorizationService/AuthorizationService.cs index d658368320..03da6e144f 100644 --- a/OpenSim/Services/AuthorizationService/AuthorizationService.cs +++ b/OpenSim/Services/AuthorizationService/AuthorizationService.cs @@ -48,10 +48,11 @@ namespace OpenSim.Services.AuthorizationService m_log.Info("[AUTHORIZATION CONNECTOR]: Local Authorization service enabled"); } - public bool IsAuthorizedForRegion(string userID, string regionID, out string message) + public bool IsAuthorizedForRegion( + string userID, string firstName, string lastName, string regionID, out string message) { message = "Authorized"; return true; } } -} +} \ No newline at end of file diff --git a/OpenSim/Services/AvatarService/AvatarService.cs b/OpenSim/Services/AvatarService/AvatarService.cs index 53ca7c868b..c59a9e0263 100644 --- a/OpenSim/Services/AvatarService/AvatarService.cs +++ b/OpenSim/Services/AvatarService/AvatarService.cs @@ -54,7 +54,7 @@ namespace OpenSim.Services.AvatarService public AvatarAppearance GetAppearance(UUID principalID) { AvatarData avatar = GetAvatar(principalID); - return avatar.ToAvatarAppearance(principalID); + return avatar.ToAvatarAppearance(); } public bool SetAppearance(UUID principalID, AvatarAppearance appearance) @@ -109,7 +109,33 @@ namespace OpenSim.Services.AvatarService foreach (KeyValuePair kvp in avatar.Data) { av.Data["Name"] = kvp.Key; - av.Data["Value"] = kvp.Value; + + // justincc 20110730. Yes, this is a hack to get around the fact that a bug in OpenSim is causing + // various simulators on osgrid to inject bad values. Since these simulators might be around for a + // long time, we are going to manually police the value. + // + // It should be possible to remove this in half a year if we don't want to police values server side. + if (kvp.Key == "AvatarHeight") + { + float height; + if (!float.TryParse(kvp.Value, out height) || height < 0 || height > 10) + { + string rawHeight = kvp.Value.Replace(",", "."); + + if (!float.TryParse(rawHeight, out height) || height < 0 || height > 10) + height = 1.771488f; + + m_log.DebugFormat( + "[AVATAR SERVICE]: Rectifying height of avatar {0} from {1} to {2}", + principalID, kvp.Value, height); + } + + av.Data["Value"] = height.ToString(); + } + else + { + av.Data["Value"] = kvp.Value; + } if (!m_Database.Store(av)) { diff --git a/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs b/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs index 1a93ae71c6..8fdb4d0b66 100644 --- a/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs +++ b/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs @@ -89,7 +89,7 @@ namespace OpenSim.Services.Connectors public AvatarAppearance GetAppearance(UUID userID) { AvatarData avatar = GetAvatar(userID); - return avatar.ToAvatarAppearance(userID); + return avatar.ToAvatarAppearance(); } public bool SetAppearance(UUID userID, AvatarAppearance appearance) diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs index 810399c3ee..360f0dd29f 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs @@ -213,7 +213,7 @@ namespace OpenSim.Services.Connectors.SimianGrid wearables[11] = new AvatarWearable(map["UnderpantsItem"].AsUUID(), map["UnderpantsAsset"].AsUUID()); wearables[12] = new AvatarWearable(map["SkirtItem"].AsUUID(), map["SkirtAsset"].AsUUID()); - AvatarAppearance appearance = new AvatarAppearance(userID); + AvatarAppearance appearance = new AvatarAppearance(); appearance.Wearables = wearables; appearance.AvatarHeight = (float)map["Height"].AsReal(); @@ -257,7 +257,7 @@ namespace OpenSim.Services.Connectors.SimianGrid if (avatar.AvatarType == 1) // LLAvatar { - AvatarAppearance appearance = avatar.ToAvatarAppearance(userID); + AvatarAppearance appearance = avatar.ToAvatarAppearance(); OSDMap map = new OSDMap(); diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index 985d77b02d..f663dd6f55 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs @@ -320,18 +320,25 @@ namespace OpenSim.Services.GridService return null; } - public GridRegion GetRegionByName(UUID scopeID, string regionName) + public GridRegion GetRegionByName(UUID scopeID, string name) { - List rdatas = m_Database.Get(regionName + "%", scopeID); + List rdatas = m_Database.Get(name, scopeID); if ((rdatas != null) && (rdatas.Count > 0)) return RegionData2RegionInfo(rdatas[0]); // get the first + if (m_AllowHypergridMapSearch) + { + GridRegion r = GetHypergridRegionByName(scopeID, name); + if (r != null) + return r; + } + return null; } public List GetRegionsByName(UUID scopeID, string name, int maxNumber) { - m_log.DebugFormat("[GRID SERVICE]: GetRegionsByName {0}", name); +// m_log.DebugFormat("[GRID SERVICE]: GetRegionsByName {0}", name); List rdatas = m_Database.Get(name + "%", scopeID); @@ -340,7 +347,7 @@ namespace OpenSim.Services.GridService if (rdatas != null) { - m_log.DebugFormat("[GRID SERVICE]: Found {0} regions", rdatas.Count); +// m_log.DebugFormat("[GRID SERVICE]: Found {0} regions", rdatas.Count); foreach (RegionData rdata in rdatas) { if (count++ < maxNumber) @@ -348,9 +355,9 @@ namespace OpenSim.Services.GridService } } - if (m_AllowHypergridMapSearch && (rdatas == null || (rdatas != null && rdatas.Count == 0)) && name.Contains(".")) + if (m_AllowHypergridMapSearch && (rdatas == null || (rdatas != null && rdatas.Count == 0))) { - GridRegion r = m_HypergridLinker.LinkRegion(scopeID, name); + GridRegion r = GetHypergridRegionByName(scopeID, name); if (r != null) rinfos.Add(r); } @@ -358,6 +365,20 @@ namespace OpenSim.Services.GridService return rinfos; } + /// + /// Get a hypergrid region. + /// + /// + /// + /// null if no hypergrid region could be found. + protected GridRegion GetHypergridRegionByName(UUID scopeID, string name) + { + if (name.Contains(".")) + return m_HypergridLinker.LinkRegion(scopeID, name); + else + return null; + } + public List GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax) { int xminSnap = (int)(xmin / Constants.RegionSize) * (int)Constants.RegionSize; diff --git a/OpenSim/Services/Interfaces/IAuthorizationService.cs b/OpenSim/Services/Interfaces/IAuthorizationService.cs index c5d577ad9a..e5c68f62fa 100644 --- a/OpenSim/Services/Interfaces/IAuthorizationService.cs +++ b/OpenSim/Services/Interfaces/IAuthorizationService.cs @@ -34,14 +34,21 @@ namespace OpenSim.Services.Interfaces public interface IAuthorizationService { - ////////////////////////////////////////////////////// - // Authorized - // - // This method returns a simple true false indicating - // whether or not a user has access to the region - // - bool IsAuthorizedForRegion(string userID, string regionID, out string message); - + /// + /// Check whether the user should be given access to the region. + /// + /// + /// We also supply user first name and last name for situations where the user does not have an account + /// on the region (e.g. they're a visitor via Hypergrid). + /// + /// + /// /param> + /// + /// + /// + /// + bool IsAuthorizedForRegion( + string userID, string firstName, string lastName, string regionID, out string message); } public class AuthorizationRequest @@ -63,7 +70,8 @@ namespace OpenSim.Services.Interfaces m_regionID = RegionID; } - public AuthorizationRequest(string ID,string FirstName, string SurName, string Email, string RegionName, string RegionID) + public AuthorizationRequest( + string ID, string FirstName, string SurName, string Email, string RegionName, string RegionID) { m_userID = ID; m_firstname = FirstName; @@ -108,9 +116,6 @@ namespace OpenSim.Services.Interfaces get { return m_regionID; } set { m_regionID = value; } } - - - } public class AuthorizationResponse @@ -126,7 +131,6 @@ namespace OpenSim.Services.Interfaces { m_isAuthorized = isAuthorized; m_message = message; - } public bool IsAuthorized @@ -141,4 +145,4 @@ namespace OpenSim.Services.Interfaces set { m_message = value; } } } -} +} \ No newline at end of file diff --git a/OpenSim/Services/Interfaces/IAvatarService.cs b/OpenSim/Services/Interfaces/IAvatarService.cs index d7af562b62..0d5ab7db2e 100644 --- a/OpenSim/Services/Interfaces/IAvatarService.cs +++ b/OpenSim/Services/Interfaces/IAvatarService.cs @@ -180,9 +180,9 @@ namespace OpenSim.Services.Interfaces } } - public AvatarAppearance ToAvatarAppearance(UUID owner) + public AvatarAppearance ToAvatarAppearance() { - AvatarAppearance appearance = new AvatarAppearance(owner); + AvatarAppearance appearance = new AvatarAppearance(); if (Data.Count == 0) return appearance; diff --git a/OpenSim/Services/Interfaces/IGridService.cs b/OpenSim/Services/Interfaces/IGridService.cs index a34f0bebf6..41dd20cd66 100644 --- a/OpenSim/Services/Interfaces/IGridService.cs +++ b/OpenSim/Services/Interfaces/IGridService.cs @@ -71,6 +71,12 @@ namespace OpenSim.Services.Interfaces /// GridRegion GetRegionByPosition(UUID scopeID, int x, int y); + /// + /// Get information about a region which exactly matches the name given. + /// + /// + /// + /// Returns the region information if the name matched. Null otherwise. GridRegion GetRegionByName(UUID scopeID, string regionName); /// diff --git a/OpenSim/Services/InventoryService/LibraryService.cs b/OpenSim/Services/InventoryService/LibraryService.cs index 383f311fdf..f90895b203 100644 --- a/OpenSim/Services/InventoryService/LibraryService.cs +++ b/OpenSim/Services/InventoryService/LibraryService.cs @@ -193,10 +193,11 @@ namespace OpenSim.Services.InventoryService item.Description = config.GetString("description", item.Name); item.InvType = config.GetInt("inventoryType", 0); item.AssetType = config.GetInt("assetType", item.InvType); - item.CurrentPermissions = (uint)config.GetLong("currentPermissions", 0x7FFFFFFF); - item.NextPermissions = (uint)config.GetLong("nextPermissions", 0x7FFFFFFF); - item.EveryOnePermissions = (uint)config.GetLong("everyonePermissions", 0x7FFFFFFF); - item.BasePermissions = (uint)config.GetLong("basePermissions", 0x7FFFFFFF); + item.CurrentPermissions = (uint)config.GetLong("currentPermissions", (uint)PermissionMask.All); + item.NextPermissions = (uint)config.GetLong("nextPermissions", (uint)PermissionMask.All); + item.EveryOnePermissions + = (uint)config.GetLong("everyonePermissions", (uint)PermissionMask.All - (uint)PermissionMask.Modify); + item.BasePermissions = (uint)config.GetLong("basePermissions", (uint)PermissionMask.All); item.Flags = (uint)config.GetInt("flags", 0); if (libraryFolders.ContainsKey(item.Folder)) diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index 2b15896d69..00405a118a 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -785,7 +785,7 @@ namespace OpenSim.Services.LLLoginService if (avatar != null) aCircuit.Appearance = new AvatarAppearance(avatar); else - aCircuit.Appearance = new AvatarAppearance(account.PrincipalID); + aCircuit.Appearance = new AvatarAppearance(); //aCircuit.BaseFolder = irrelevant aCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); diff --git a/OpenSim/Tests/Common/Helpers/AssetHelpers.cs b/OpenSim/Tests/Common/Helpers/AssetHelpers.cs index 9b68331038..99eb12410b 100644 --- a/OpenSim/Tests/Common/Helpers/AssetHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/AssetHelpers.cs @@ -42,7 +42,7 @@ namespace OpenSim.Tests.Common /// public static AssetBase CreateAsset() { - return CreateAsset(UUID.Random(), AssetType.Notecard, "hello", UUID.Random()); + return CreateAsset(UUID.Random()); } /// @@ -50,9 +50,9 @@ namespace OpenSim.Tests.Common /// /// /param> /// - public static AssetBase CreateAsset(UUID creatorId) + public static AssetBase CreateAsset(UUID id) { - return CreateAsset(UUID.Random(), AssetType.Notecard, "hello", creatorId); + return CreateAsset(id, AssetType.Notecard, "hello", UUID.Random()); } /// diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index bf91ab5817..88043f3739 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -234,7 +234,7 @@ namespace OpenSim.Tests.Common.Mock public event ScriptReset OnScriptReset; public event GetScriptRunning OnGetScriptRunning; public event SetScriptRunning OnSetScriptRunning; - public event UpdateVector OnAutoPilotGo; + public event Action OnAutoPilotGo; public event TerrainUnacked OnUnackedTerrain; @@ -1214,7 +1214,7 @@ namespace OpenSim.Tests.Common.Mock { } - public void SendTextBoxRequest(string message, int chatChannel, string objectname, string ownerFirstName, string ownerLastName, UUID objectId) + public void SendTextBoxRequest(string message, int chatChannel, string objectname, UUID ownerID, string ownerFirstName, string ownerLastName, UUID objectId) { } diff --git a/bin/OpenSim.Region.OptionalModules.Tests.dll.config b/bin/OpenSim.Region.OptionalModules.Tests.dll.config new file mode 100644 index 0000000000..a3f681d89e --- /dev/null +++ b/bin/OpenSim.Region.OptionalModules.Tests.dll.config @@ -0,0 +1,33 @@ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 2fe4db7d26..bcfaf76704 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -39,6 +39,9 @@ ;# {save_crashes} {} {Save crashes to disk?} {true false} false ;; Set this to true if you want to log crashes to disk ;; this can be useful when submitting bug reports. + ;; However, this will only log crashes within OpenSimulator that cause the entire program to exit + ;; It will not log crashes caused by virtual machine failures, which includes mono and ODE failures. + ;; You will need to capture these native stack traces by recording the session log itself. ; save_crashes = false ;# {crash_dir} {save_crashes:true} {Directory to save crashes to?} {} crashes @@ -80,9 +83,11 @@ ;; This can be overriden in the region config file. ; ClampPrimSize = false - ;# {AllowScriptCrossing} {} {Allow scripts to cross into this region} {true false} false - ;; Allow scripts to keep running when they cross region boundaries, rather than being restarted. Script code is recompiled on the destination region and the state reloaded. - ; AllowScriptCrossing = false + ;# {AllowScriptCrossing} {} {Allow scripts to cross into this region} {true false} true + ;; Allow scripts to keep running when they cross region boundaries, rather than being restarted. State is reloaded on the destination region. + ;; This only applies when crossing to a region running in a different simulator. + ;; For crossings where the regions are on the same simulator the script is always kept running. + ; AllowScriptCrossing = true ;# {TrustBinaries} {AllowScriptCrossing:true} {Accept compiled binary script code? (DANGEROUS!)} {true false} false ;; Allow compiled script binary code to cross region boundaries. @@ -711,6 +716,11 @@ ; Enabled = true; +[NPC] + ;# {Enabled} {} {Enable Non Player Character (NPC) facilities} {true false} false + ; Enabled = false + + [PrimLimitsModule] ;# {EnforcePrimLimits} {} {Enforce parcel prim limits} {true false} false ;; Enable parcel prim limits. Off by default to emulate pre-existing behavior. diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index d487ce6312..28775417c6 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -5,6 +5,9 @@ [Startup] ; Set this to true if you want to log crashes to disk ; this can be useful when submitting bug reports. + ; However, this will only log crashes within OpenSimulator that cause the entire program to exit + ; It will not log crashes caused by virtual machine failures, which includes mono and ODE failures. + ; You will need to capture these native stack traces by recording the session log itself. save_crashes = false ; Directory to save crashes to if above is enabled @@ -77,8 +80,10 @@ ; This can be overriden in the region config file. ClampPrimSize = false - ; Allow scripts to keep running when they cross region boundaries, rather than being restarted. Script code is recompiled on the destination region and the state reloaded. - AllowScriptCrossing = false + ; Allow scripts to keep running when they cross region boundaries, rather than being restarted. State is reloaded on the destination region. + ; This only applies when crossing to a region running in a different simulator. + ; For crossings where the regions are on the same simulator the script is always kept running. + AllowScriptCrossing = true ; Allow compiled script binary code to cross region boundaries. ; If you set this to "true", any region that can teleport to you can @@ -170,8 +175,8 @@ ; If set to false, then, in theory, the server never carries out permission checks (allowing anybody to copy ; any item, etc. This may not yet be implemented uniformally. ; If set to true, then all permissions checks are carried out - ; Default is false - serverside_object_permissions = false + ; Default is true + serverside_object_permissions = true allow_grid_gods = false @@ -1403,6 +1408,10 @@ ; Enable media on a prim facilities Enabled = true; +[NPC] + ;; Enable Non Player Character (NPC) facilities + Enabled = false + ;; ;; If you are using a simian grid frontend you can enable ;; this module to upload tile images for the mapping fn diff --git a/bin/inventory/AnimationsLibrary/AnimationsLibraryItems.xml b/bin/inventory/AnimationsLibrary/AnimationsLibraryItems.xml index 2a6ceb4529..9cfadf0361 100644 --- a/bin/inventory/AnimationsLibrary/AnimationsLibraryItems.xml +++ b/bin/inventory/AnimationsLibrary/AnimationsLibraryItems.xml @@ -108,8 +108,6 @@
- - diff --git a/bin/inventory/BodyPartsLibrary/BodyPartsLibraryItems.xml b/bin/inventory/BodyPartsLibrary/BodyPartsLibraryItems.xml index aa8d9d964b..d9adf1c53c 100644 --- a/bin/inventory/BodyPartsLibrary/BodyPartsLibraryItems.xml +++ b/bin/inventory/BodyPartsLibrary/BodyPartsLibraryItems.xml @@ -9,10 +9,6 @@ - - - - --> + diff --git a/bin/inventory/ClothingLibrary/ClothingLibraryItems.xml b/bin/inventory/ClothingLibrary/ClothingLibraryItems.xml index 9e297f063e..a12bb8af21 100644 --- a/bin/inventory/ClothingLibrary/ClothingLibraryItems.xml +++ b/bin/inventory/ClothingLibrary/ClothingLibraryItems.xml @@ -9,10 +9,6 @@ - - - - --> + diff --git a/bin/inventory/GesturesLibrary/GesturesLibraryItems.xml b/bin/inventory/GesturesLibrary/GesturesLibraryItems.xml index 1312129ca6..ca3ce2d18c 100644 --- a/bin/inventory/GesturesLibrary/GesturesLibraryItems.xml +++ b/bin/inventory/GesturesLibrary/GesturesLibraryItems.xml @@ -7,11 +7,8 @@ - - - - +
@@ -20,11 +17,8 @@ - - - -
+
@@ -33,11 +27,8 @@ - - - -
+
@@ -46,11 +37,8 @@ - - - -
+
@@ -59,11 +47,8 @@ - - - -
+
@@ -72,11 +57,8 @@ - - - -
+
@@ -85,11 +67,8 @@ - - - -
+
@@ -98,11 +77,8 @@ - - - -
+
@@ -111,11 +87,8 @@ - - - -
+
@@ -124,11 +97,8 @@ - - - -
+
@@ -137,11 +107,8 @@ - - - -
+
@@ -150,11 +117,8 @@ - - - -
+
@@ -163,11 +127,8 @@ - - - -
+
@@ -176,11 +137,8 @@ - - - -
+
@@ -189,11 +147,8 @@ - - - -
+
@@ -202,9 +157,6 @@ - - - -
+ diff --git a/bin/inventory/LandmarksLibrary/LandmarksLibraryItems.xml b/bin/inventory/LandmarksLibrary/LandmarksLibraryItems.xml index 4047a5838e..44194cd52f 100644 --- a/bin/inventory/LandmarksLibrary/LandmarksLibraryItems.xml +++ b/bin/inventory/LandmarksLibrary/LandmarksLibraryItems.xml @@ -9,10 +9,6 @@ - - - - --> diff --git a/bin/inventory/NotecardsLibrary/NotecardsLibraryItems.xml b/bin/inventory/NotecardsLibrary/NotecardsLibraryItems.xml index 713c365755..e232bcc350 100644 --- a/bin/inventory/NotecardsLibrary/NotecardsLibraryItems.xml +++ b/bin/inventory/NotecardsLibrary/NotecardsLibraryItems.xml @@ -9,10 +9,6 @@ - - - - --> @@ -24,11 +20,8 @@ - - - - +
@@ -37,9 +30,6 @@ - - - -
+ diff --git a/bin/inventory/ObjectsLibrary/ObjectsLibraryItems.xml b/bin/inventory/ObjectsLibrary/ObjectsLibraryItems.xml index 4047a5838e..44194cd52f 100644 --- a/bin/inventory/ObjectsLibrary/ObjectsLibraryItems.xml +++ b/bin/inventory/ObjectsLibrary/ObjectsLibraryItems.xml @@ -9,10 +9,6 @@ - - - - --> diff --git a/bin/inventory/OpenSimLibrary/OpenSimLibrary.xml b/bin/inventory/OpenSimLibrary/OpenSimLibrary.xml index 7eb8de3c1a..bef59d8add 100644 --- a/bin/inventory/OpenSimLibrary/OpenSimLibrary.xml +++ b/bin/inventory/OpenSimLibrary/OpenSimLibrary.xml @@ -10,10 +10,6 @@ - - - - --> diff --git a/bin/inventory/PhotosLibrary/PhotosLibraryItems.xml b/bin/inventory/PhotosLibrary/PhotosLibraryItems.xml index 4047a5838e..44194cd52f 100644 --- a/bin/inventory/PhotosLibrary/PhotosLibraryItems.xml +++ b/bin/inventory/PhotosLibrary/PhotosLibraryItems.xml @@ -9,10 +9,6 @@ - - - - --> diff --git a/bin/inventory/ScriptsLibrary/ScriptsLibraryItems.xml b/bin/inventory/ScriptsLibrary/ScriptsLibraryItems.xml index 9641f7db6b..df9d867b5d 100644 --- a/bin/inventory/ScriptsLibrary/ScriptsLibraryItems.xml +++ b/bin/inventory/ScriptsLibrary/ScriptsLibraryItems.xml @@ -25,11 +25,8 @@ - - - - +
@@ -38,11 +35,8 @@ - - - -
+
@@ -51,11 +45,8 @@ - - - -
+
@@ -64,11 +55,8 @@ - - - -
+
@@ -77,11 +65,8 @@ - - - -
+
@@ -90,11 +75,8 @@ - - - -
+
@@ -103,11 +85,8 @@ - - - -
+
@@ -116,11 +95,8 @@ - - - -
+
@@ -129,11 +105,8 @@ - - - -
+
@@ -142,11 +115,8 @@ - - - -
+
@@ -155,11 +125,8 @@ - - - -
+
@@ -169,11 +136,8 @@ - - - -
+ @@ -187,6 +151,7 @@ +
@@ -195,11 +160,8 @@ - - - -
+
@@ -208,11 +170,8 @@ - - - -
+
@@ -221,11 +180,8 @@ - - - -
+
@@ -234,11 +190,8 @@ - - - -
+
@@ -248,11 +201,8 @@ - - - -
+
@@ -261,11 +211,8 @@ - - - -
+
@@ -274,11 +221,8 @@ - - - -
+ @@ -288,213 +232,166 @@
- + - - - -
+
- + - - - -
+
- + - - - -
+
- + - - - -
+
- + - - - -
+
- + - - - -
+
- + - - - -
+
- + - - - -
+
- + - - - -
+
- + - - - -
+
- + - - - -
+
- + - - - -
+
- + - - - -
+
- + - - - -
+
- + - - - -
+
- + - - - -
+ +
@@ -503,11 +400,8 @@ - - - -
+
@@ -516,11 +410,8 @@ - - - -
+
@@ -529,9 +420,5 @@ - - - -
diff --git a/bin/inventory/SoundsLibrary/SoundsLibraryItems.xml b/bin/inventory/SoundsLibrary/SoundsLibraryItems.xml index 4047a5838e..44194cd52f 100644 --- a/bin/inventory/SoundsLibrary/SoundsLibraryItems.xml +++ b/bin/inventory/SoundsLibrary/SoundsLibraryItems.xml @@ -9,10 +9,6 @@ - - - - --> diff --git a/bin/inventory/TexturesLibrary/TexturesLibraryItems.xml b/bin/inventory/TexturesLibrary/TexturesLibraryItems.xml index adba99aae5..a018a0de78 100644 --- a/bin/inventory/TexturesLibrary/TexturesLibraryItems.xml +++ b/bin/inventory/TexturesLibrary/TexturesLibraryItems.xml @@ -9,10 +9,6 @@ - - - - --> @@ -24,11 +20,8 @@ - - - - +
@@ -37,11 +30,8 @@ - - - -
+
@@ -50,11 +40,8 @@ - - - -
+
@@ -63,11 +50,8 @@ - - - -
+
@@ -76,11 +60,8 @@ - - - -
+
@@ -89,11 +70,8 @@ - - - -
+
@@ -102,11 +80,8 @@ - - - -
+
@@ -115,11 +90,8 @@ - - - -
+
@@ -128,11 +100,8 @@ - - - -
+
@@ -141,11 +110,8 @@ - - - -
+
@@ -154,11 +120,8 @@ - - - -
+
@@ -167,11 +130,8 @@ - - - -
+
@@ -180,11 +140,8 @@ - - - -
+
@@ -193,11 +150,8 @@ - - - -
+
@@ -206,11 +160,8 @@ - - - -
+
@@ -219,11 +170,8 @@ - - - -
+
@@ -232,11 +180,8 @@ - - - -
+
@@ -245,11 +190,8 @@ - - - -
+
@@ -258,11 +200,8 @@ - - - -
+
@@ -271,11 +210,8 @@ - - - -
+
@@ -284,11 +220,8 @@ - - - -
+
@@ -297,11 +230,8 @@ - - - -
+
@@ -310,11 +240,8 @@ - - - -
+
@@ -323,11 +250,8 @@ - - - -
+
@@ -336,11 +260,8 @@ - - - -
+
@@ -349,11 +270,8 @@ - - - -
+
@@ -362,11 +280,8 @@ - - - -
+
@@ -375,11 +290,8 @@ - - - -
+
@@ -388,11 +300,8 @@ - - - -
+
@@ -401,11 +310,8 @@ - - - -
+
@@ -414,11 +320,8 @@ - - - -
+
@@ -427,11 +330,8 @@ - - - -
+
@@ -440,11 +340,8 @@ - - - -
+
@@ -453,11 +350,8 @@ - - - -
+
@@ -466,11 +360,8 @@ - - - -
+
@@ -479,11 +370,8 @@ - - - -
+
@@ -492,11 +380,8 @@ - - - -
+
@@ -505,11 +390,8 @@ - - - -
+
@@ -518,11 +400,8 @@ - - - -
+
@@ -531,11 +410,8 @@ - - - -
+
@@ -544,11 +420,8 @@ - - - -
+
@@ -557,11 +430,8 @@ - - - -
+
@@ -570,11 +440,8 @@ - - - -
+
@@ -583,11 +450,8 @@ - - - -
+
@@ -596,11 +460,8 @@ - - - -
+
@@ -609,11 +470,8 @@ - - - -
+
@@ -622,11 +480,8 @@ - - - -
+
@@ -635,10 +490,6 @@ - - - -
@@ -649,11 +500,8 @@ - - - -
+
@@ -662,11 +510,8 @@ - - - -
+
@@ -675,11 +520,8 @@ - - - -
+
@@ -688,10 +530,6 @@ - - - -
@@ -702,10 +540,6 @@ - - - -
@@ -716,10 +550,6 @@ - - - -
@@ -730,9 +560,5 @@ - - - -