diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 1d5b4268c2..24f986a756 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -1651,7 +1651,9 @@ namespace OpenSim.Framework.Servers.HttpServer public void httpServerException(object source, Exception exception) { - m_log.Error(String.Format("[BASE HTTP SERVER]: {0} had an exception: {1} ", source.ToString(), exception.Message), exception); + if (source.ToString() == "HttpServer.HttpListener" && exception.ToString().StartsWith("Mono.Security.Protocol.Tls.TlsException")) + return; + m_log.ErrorFormat("[BASE HTTP SERVER]: {0} had an exception {1}", source.ToString(), exception.ToString()); /* if (HTTPDRunning)// && NotSocketErrors > 5) { diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index bcb45cf34c..79e35f4762 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -155,6 +155,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Flag to signal when clients should send pings protected bool m_sendPing; + private ExpiringCache> m_pendingCache = new ExpiringCache>(); + private int m_defaultRTO = 0; private int m_maxRTO = 0; private int m_ackTimeout = 0; @@ -765,21 +767,46 @@ namespace OpenSim.Region.ClientStack.LindenUDP #region Packet to Client Mapping - // UseCircuitCode handling - if (packet.Type == PacketType.UseCircuitCode) + // If there is already a client for this endpoint, don't process UseCircuitCode + IClientAPI client = null; + if (!m_scene.TryGetClient(address, out client)) { - object[] array = new object[] { buffer, packet }; + // UseCircuitCode handling + if (packet.Type == PacketType.UseCircuitCode) + { + // And if there is a UseCircuitCode pending, also drop it + lock (m_pendingCache) + { + if (m_pendingCache.Contains(address)) + return; - Util.FireAndForget(HandleUseCircuitCode, array); + m_pendingCache.AddOrUpdate(address, new Queue(), 60); + } - return; + object[] array = new object[] { buffer, packet }; + + Util.FireAndForget(HandleUseCircuitCode, array); + + return; + } + } + + // If this is a pending connection, enqueue, don't process yet + lock (m_pendingCache) + { + Queue queue; + if (m_pendingCache.TryGetValue(address, out queue)) + { + //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type); + queue.Enqueue(buffer); + return; + } } // Determine which agent this packet came from - IClientAPI client; - if (!m_scene.TryGetClient(address, out client) || !(client is LLClientView)) + if (client == null || !(client is LLClientView)) { -// m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); + //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); return; } @@ -1014,6 +1041,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP // We only want to send initial data to new clients, not ones which are being converted from child to root. if (client != null) client.SceneAgent.SendInitialDataToMe(); + + // Now we know we can handle more data + Thread.Sleep(200); + + // Obtain the queue and remove it from the cache + Queue queue = null; + + lock (m_pendingCache) + { + if (!m_pendingCache.TryGetValue(remoteEndPoint, out queue)) + { + m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present"); + return; + } + m_pendingCache.Remove(remoteEndPoint); + } + + m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count); + + // Reinject queued packets + while(queue.Count > 0) + { + UDPPacketBuffer buf = queue.Dequeue(); + PacketReceived(buf); + } + queue = null; } else { @@ -1021,6 +1074,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_log.WarnFormat( "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, remoteEndPoint); + lock (m_pendingCache) + m_pendingCache.Remove(remoteEndPoint); } // m_log.DebugFormat( diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index 7f2f1478cc..f4a89bd4f2 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -215,7 +215,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); return urlcode; } - string url = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString() + "/"; + string url = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString(); UrlData urlData = new UrlData(); urlData.hostID = host.UUID; @@ -228,11 +228,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp m_UrlMap[url] = urlData; - string uri = "/lslhttps/" + urlcode.ToString() + "/"; + string uri = "/lslhttps/" + urlcode.ToString(); - m_HttpsServer.AddPollServiceHTTPHandler( - uri, - new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode,25000)); + PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode, 25000); + args.Type = PollServiceEventArgs.EventType.LslHttp; + m_HttpsServer.AddPollServiceHTTPHandler(uri, args); m_log.DebugFormat( "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}", diff --git a/OpenSim/Region/Framework/Scenes/SOPVehicle.cs b/OpenSim/Region/Framework/Scenes/SOPVehicle.cs index 41e894419e..9cb901a3c2 100644 --- a/OpenSim/Region/Framework/Scenes/SOPVehicle.cs +++ b/OpenSim/Region/Framework/Scenes/SOPVehicle.cs @@ -36,7 +36,6 @@ using System.Xml; using OpenSim.Framework.Serialization; using OpenSim.Framework.Serialization.External; using OpenSim.Region.Framework.Scenes.Serialization; -using OpenSim.Region.Framework.Scenes.Serialization; namespace OpenSim.Region.Framework.Scenes { @@ -215,7 +214,7 @@ namespace OpenSim.Region.Framework.Scenes switch (pParam) { case Vehicle.REFERENCE_FRAME: - vd.m_referenceFrame = Quaternion.Inverse(pValue); + vd.m_referenceFrame = pValue; break; } }//end ProcessRotationVehicleParam diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 19f319cab5..f437bc832f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -879,6 +879,8 @@ namespace OpenSim.Region.Framework.Scenes StatsReporter = new SimStatsReporter(this); StatsReporter.OnSendStatsResult += SendSimStatsPackets; StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats; + + MainConsole.Instance.Commands.AddCommand("scene", false, "gc collect", "gc collect", "gc collect", "Cause the garbage collector to make a single pass", HandleGcCollect); } public Scene(RegionInfo regInfo) : base(regInfo) @@ -5773,5 +5775,10 @@ Environment.Exit(1); m_SpawnPoint = 1; return m_SpawnPoint - 1; } + + private void HandleGcCollect(string module, string[] args) + { + GC.Collect(); + } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 33a2cc5050..f1f94a78bf 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2061,8 +2061,6 @@ namespace OpenSim.Region.Framework.Scenes HasGroupChangedDueToDelink = false; m_scene.EventManager.TriggerOnSceneObjectPreSave(backup_group, this); - datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID); - backup_group.ForEachPart(delegate(SceneObjectPart part) { if (part.KeyframeMotion != null) @@ -2070,6 +2068,12 @@ namespace OpenSim.Region.Framework.Scenes part.KeyframeMotion = KeyframeMotion.FromData(backup_group, part.KeyframeMotion.Serialize()); part.KeyframeMotion.UpdateSceneObject(this); } + }); + + datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID); + + backup_group.ForEachPart(delegate(SceneObjectPart part) + { part.Inventory.ProcessInventoryBackup(datastore); }); diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs index 865180f534..b506b1c370 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs @@ -95,7 +95,7 @@ namespace OpenSim.Region.Physics.OdePlugin private bool m_iscollidingObj = false; private bool m_alwaysRun = false; private int m_requestedUpdateFrequency = 0; - public uint m_localID = 0; + private uint m_localID = 0; public bool m_returnCollisions = false; // taints and their non-tainted counterparts public bool m_isPhysical = false; // the current physical status @@ -214,6 +214,7 @@ namespace OpenSim.Region.Physics.OdePlugin public override uint LocalID { + get { return m_localID; } set { m_localID = value; } } diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs index e900c02a6c..a7dda7acd2 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs @@ -425,7 +425,8 @@ namespace OpenSim.Region.Physics.OdePlugin switch (pParam) { case Vehicle.REFERENCE_FRAME: - m_referenceFrame = Quaternion.Inverse(pValue); + // m_referenceFrame = Quaternion.Inverse(pValue); + m_referenceFrame = pValue; break; case Vehicle.ROLL_FRAME: m_RollreferenceFrame = pValue; diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs index ff17a6e46b..6d322e27be 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs @@ -101,7 +101,6 @@ namespace OpenSim.Region.Physics.OdePlugin private float m_invTimeStep = 50.0f; private float m_timeStep = .02f; - private Vector3 m_PIDTarget; private float m_PIDTau; private bool m_usePID; @@ -119,7 +118,7 @@ namespace OpenSim.Region.Physics.OdePlugin private float m_buoyancy; //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle. private int body_autodisable_frames = 5; - private int bodydisablecontrol = 0; + public int bodydisablecontrol = 0; // Default we're a Geometry @@ -134,7 +133,7 @@ namespace OpenSim.Region.Physics.OdePlugin // private bool m_collidesLand = true; private bool m_collidesWater; - public bool m_returnCollisions; +// public bool m_returnCollisions; private bool m_NoColide; // for now only for internal use for bad meshs @@ -144,7 +143,7 @@ namespace OpenSim.Region.Physics.OdePlugin public bool m_disabled; - public uint m_localID; + private uint m_localID; private IMesh m_mesh; private object m_meshlock = new object(); @@ -164,10 +163,10 @@ namespace OpenSim.Region.Physics.OdePlugin private List childrenPrim = new List(); - private bool m_throttleUpdates; - private int throttleCounter; +// private bool m_throttleUpdates; +// private int throttleCounter; public float m_collisionscore; - int m_colliderfilter = 0; + private int m_colliderfilter = 0; public IntPtr collide_geom; // for objects: geom if single prim space it linkset @@ -235,7 +234,6 @@ namespace OpenSim.Region.Physics.OdePlugin } } - public override bool Phantom // this is not reliable for internal use { get { return m_fakeisphantom; } @@ -292,15 +290,19 @@ namespace OpenSim.Region.Physics.OdePlugin } public override uint LocalID + { + get { return m_localID; } + set { m_localID = value; } + } + + public OdePrim Parent { get { - return m_localID; - } - set - { - //m_log.Info("[PHYSICS]: Setting TrackerID: " + value); - m_localID = value; + if (childPrim) + return (OdePrim)_parent; + else + return this; } } @@ -363,12 +365,14 @@ namespace OpenSim.Region.Physics.OdePlugin set { return; } } - public override bool ThrottleUpdates + + public override bool ThrottleUpdates {get;set;} +/* { get { return m_throttleUpdates; } set { m_throttleUpdates = value; } } - +*/ public override bool Stopped { get { return _zeroFlag; } @@ -943,15 +947,15 @@ namespace OpenSim.Region.Physics.OdePlugin CollisionEventsThisFrame = null; } m_eventsubscription = 0; - // for now still done on odescene -// _parent_scene.RemoveCollisionEventReporting(this); + _parent_scene.RemoveCollisionEventReporting(this); } public void AddCollisionEvent(uint CollidedWith, ContactPoint contact) { if (CollisionEventsThisFrame == null) CollisionEventsThisFrame = new CollisionEventUpdate(); - CollisionEventsThisFrame.AddCollider(CollidedWith, contact); +// if(CollisionEventsThisFrame.Count < 32) + CollisionEventsThisFrame.AddCollider(CollidedWith, contact); } public void SendCollisions() @@ -1746,8 +1750,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (childrenPrim.Count == 0) { collide_geom = prim_geom; - m_targetSpace = _parent_scene.ActiveSpace; - d.SpaceAdd(m_targetSpace, prim_geom); + m_targetSpace = _parent_scene.ActiveSpace; } else { @@ -1755,7 +1758,6 @@ namespace OpenSim.Region.Physics.OdePlugin d.HashSpaceSetLevels(m_targetSpace, -2, 8); d.SpaceSetSublevel(m_targetSpace, 3); d.SpaceSetCleanup(m_targetSpace, false); - d.SpaceAdd(m_targetSpace, prim_geom); d.GeomSetCategoryBits(m_targetSpace, (uint)(CollisionCategories.Space | CollisionCategories.Geom | @@ -1766,12 +1768,21 @@ namespace OpenSim.Region.Physics.OdePlugin collide_geom = m_targetSpace; } + d.SpaceAdd(m_targetSpace, prim_geom); + if (m_delaySelect) { m_isSelected = true; m_delaySelect = false; } + m_collisionscore = 0; + + UpdateCollisionCatFlags(); + ApplyCollisionCatFlags(); + + _parent_scene.addActivePrim(this); + lock (childrenPrim) { foreach (OdePrim prm in childrenPrim) @@ -1809,10 +1820,6 @@ namespace OpenSim.Region.Physics.OdePlugin createAMotor(m_angularlock); } - m_collisionscore = 0; - - UpdateCollisionCatFlags(); - ApplyCollisionCatFlags(); if (m_isSelected || m_disabled) { @@ -1822,9 +1829,7 @@ namespace OpenSim.Region.Physics.OdePlugin { d.BodySetAngularVel(Body, m_rotationalVelocity.X, m_rotationalVelocity.Y, m_rotationalVelocity.Z); d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z); - } - - _parent_scene.addActivePrim(this); + } _parent_scene.addActiveGroups(this); } @@ -3441,92 +3446,14 @@ namespace OpenSim.Region.Physics.OdePlugin if (++bodydisablecontrol < 20) return; - bodydisablecontrol = 0; + d.BodyEnable(Body); } + bodydisablecontrol = 0; + d.Vector3 lpos = d.GeomGetPosition(prim_geom); // root position that is seem by rest of simulator -/* moved down to UpdateMove... where it belongs again - - // check outside region - - if (lpos.Z < -100 || lpos.Z > 100000f) - { - m_outbounds = true; - - lpos.Z = Util.Clip(lpos.Z, -100f, 100000f); - _acceleration.X = 0; - _acceleration.Y = 0; - _acceleration.Z = 0; - - _velocity.X = 0; - _velocity.Y = 0; - _velocity.Z = 0; - m_rotationalVelocity.X = 0; - m_rotationalVelocity.Y = 0; - m_rotationalVelocity.Z = 0; - - d.BodySetLinearVel(Body, 0, 0, 0); // stop it - d.BodySetAngularVel(Body, 0, 0, 0); // stop it - d.BodySetPosition(Body, lpos.X, lpos.Y, lpos.Z); // put it somewhere - m_lastposition = _position; - m_lastorientation = _orientation; - - base.RequestPhysicsterseUpdate(); - - throttleCounter = 0; - _zeroFlag = true; - - disableBodySoft(); // disable it and colisions - base.RaiseOutOfBounds(_position); - return; - } - - if (lpos.X < 0f) - { - _position.X = Util.Clip(lpos.X, -2f, -0.1f); - m_outbounds = true; - } - else if (lpos.X > _parent_scene.WorldExtents.X) - { - _position.X = Util.Clip(lpos.X, _parent_scene.WorldExtents.X + 0.1f, _parent_scene.WorldExtents.X + 2f); - m_outbounds = true; - } - if (lpos.Y < 0f) - { - _position.Y = Util.Clip(lpos.Y, -2f, -0.1f); - m_outbounds = true; - } - else if (lpos.Y > _parent_scene.WorldExtents.Y) - { - _position.Y = Util.Clip(lpos.Y, _parent_scene.WorldExtents.Y + 0.1f, _parent_scene.WorldExtents.Y + 2f); - m_outbounds = true; - } - - if (m_outbounds) - { - m_lastposition = _position; - m_lastorientation = _orientation; - - d.Vector3 dtmp = d.BodyGetAngularVel(Body); - m_rotationalVelocity.X = dtmp.X; - m_rotationalVelocity.Y = dtmp.Y; - m_rotationalVelocity.Z = dtmp.Z; - - dtmp = d.BodyGetLinearVel(Body); - _velocity.X = dtmp.X; - _velocity.Y = dtmp.Y; - _velocity.Z = dtmp.Z; - - d.BodySetLinearVel(Body, 0, 0, 0); // stop it - d.BodySetAngularVel(Body, 0, 0, 0); - d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); - disableBodySoft(); // stop collisions - base.RequestPhysicsterseUpdate(); - return; - } -*/ if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) { // 'VEHICLES' are dealt with in ODEDynamics.cs @@ -3721,7 +3648,7 @@ namespace OpenSim.Region.Physics.OdePlugin base.RequestPhysicsterseUpdate(); - throttleCounter = 0; +// throttleCounter = 0; _zeroFlag = true; disableBodySoft(); // disable it and colisions @@ -3769,6 +3696,8 @@ namespace OpenSim.Region.Physics.OdePlugin d.BodySetAngularVel(Body, 0, 0, 0); d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); disableBodySoft(); // stop collisions + UnSubscribeEvents(); + base.RequestPhysicsterseUpdate(); return; } @@ -3940,8 +3869,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_vehicle = null; RemoveGeom(); m_targetSpace = IntPtr.Zero; - if (m_eventsubscription > 0) - UnSubscribeEvents(); + UnSubscribeEvents(); return true; case changes.Link: diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs index 5122ebfa11..3d108f8cde 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs @@ -509,14 +509,14 @@ namespace OpenSim.Region.Physics.OdePlugin if ((thisFlags & CurrentRayFilter) == 0) return; - ID = ((OdePrim)p2).m_localID; + ID = ((OdePrim)p2).LocalID; } else if (p2 is OdeCharacter) { if ((CurrentRayFilter & RayFilterFlags.agent) == 0) return; else - ID = ((OdeCharacter)p2).m_localID; + ID = ((OdeCharacter)p2).LocalID; } else //?? return; diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs index 23411868c7..ee48db54c5 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs @@ -61,6 +61,8 @@ namespace OdeAPI public static int NTotalBodies = 0; public static int NTotalGeoms = 0; + public const uint CONTACTS_UNIMPORTANT = 0x80000000; + #region Flags and Enumerations [Flags] diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index 7848b35edf..292825738e 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs @@ -713,8 +713,18 @@ namespace OpenSim.Region.Physics.OdePlugin if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) return; - - count = d.CollidePtr(g1, g2, (contactsPerCollision & 0xffff), ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); + if(d.GeomGetCategoryBits(g1) == (uint)CollisionCategories.VolumeDtc || + d.GeomGetCategoryBits(g1) == (uint)CollisionCategories.VolumeDtc) + { + int cflags; + unchecked + { + cflags = (int)(1 | d.CONTACTS_UNIMPORTANT); + } + count = d.CollidePtr(g1, g2, cflags, ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); + } + else + count = d.CollidePtr(g1, g2, (contactsPerCollision & 0xffff), ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); } catch (SEHException) { @@ -1161,6 +1171,8 @@ namespace OpenSim.Region.Physics.OdePlugin OdePrim cp1; OdeCharacter cc2; OdePrim cp2; + OdePrim cp1Parent; + OdePrim cp2Parent; uint obj2LocalID = 0; bool p1events = p1.SubscribedEvents(); @@ -1197,18 +1209,19 @@ namespace OpenSim.Region.Physics.OdePlugin { case ActorTypes.Agent: cc2 = (OdeCharacter)p2; - obj2LocalID = cc2.m_localID; + obj2LocalID = cc2.LocalID; if (p2events) - cc2.AddCollisionEvent(cc1.m_localID, contact); + cc2.AddCollisionEvent(cc1.LocalID, contact); break; case ActorTypes.Prim: if (p2 is OdePrim) { cp2 = (OdePrim)p2; - obj2LocalID = cp2.m_localID; if (p2events) - cp2.AddCollisionEvent(cc1.m_localID, contact); + cp2.AddCollisionEvent(cc1.LocalID, contact); + cp2 = cp2.Parent; + obj2LocalID = cp2.LocalID; } break; @@ -1230,17 +1243,16 @@ namespace OpenSim.Region.Physics.OdePlugin if (p1 is OdePrim) { cp1 = (OdePrim)p1; - - // obj1LocalID = cp2.m_localID; + cp1Parent = cp1.Parent; switch ((ActorTypes)p2.PhysicsActorType) { case ActorTypes.Agent: if (p2 is OdeCharacter) { cc2 = (OdeCharacter)p2; - obj2LocalID = cc2.m_localID; + obj2LocalID = cc2.LocalID; if (p2events) - cc2.AddCollisionEvent(cp1.m_localID, contact); + cc2.AddCollisionEvent(cp1Parent.LocalID, contact); } break; case ActorTypes.Prim: @@ -1248,9 +1260,10 @@ namespace OpenSim.Region.Physics.OdePlugin if (p2 is OdePrim) { cp2 = (OdePrim)p2; - obj2LocalID = cp2.m_localID; if (p2events) - cp2.AddCollisionEvent(cp1.m_localID, contact); + cp2.AddCollisionEvent(cp1Parent.LocalID, contact); + cp2 = cp2.Parent; + obj2LocalID = cp2.LocalID; } break; @@ -1276,7 +1289,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (p2 is OdeCharacter) { cc2 = (OdeCharacter)p2; - obj2LocalID = cc2.m_localID; + obj2LocalID = cc2.LocalID; if (p2events) cc2.AddCollisionEvent(0, contact); } @@ -1285,7 +1298,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (p2 is OdePrim) { cp2 = (OdePrim)p2; - obj2LocalID = cp2.m_localID; + obj2LocalID = cp2.LocalID; if (p2events) cp2.AddCollisionEvent(0, contact); } @@ -1340,8 +1353,11 @@ namespace OpenSim.Region.Physics.OdePlugin { foreach (OdePrim prm in _activegroups) { - if (d.BodyIsEnabled(prm.Body) && !prm.m_outbounds) - d.SpaceCollide2(StaticSpace, prm.collide_geom, IntPtr.Zero, nearCallback); + if (!prm.m_outbounds) + { + if (d.BodyIsEnabled(prm.Body)) + d.SpaceCollide2(StaticSpace, prm.collide_geom, IntPtr.Zero, nearCallback); + } } } catch (AccessViolationException) @@ -1594,7 +1610,7 @@ namespace OpenSim.Region.Physics.OdePlugin //Console.WriteLine("RemovePrimThreadLocked " + prim.m_primName); lock (prim) { - RemoveCollisionEventReporting(prim); +// RemoveCollisionEventReporting(prim); lock (_prims) _prims.Remove(prim); } @@ -2002,6 +2018,7 @@ namespace OpenSim.Region.Physics.OdePlugin case ActorTypes.Prim: OdePrim pobj = (OdePrim)obj; if (pobj.Body == IntPtr.Zero || (d.BodyIsEnabled(pobj.Body) && !pobj.m_outbounds)) + if (!pobj.m_outbounds) { pobj.AddCollisionFrameTime((int)(odetimestepMS)); pobj.SendCollisions(); @@ -2718,7 +2735,6 @@ namespace OpenSim.Region.Physics.OdePlugin WaterMapHandler.Free(); } - if (ContactgeomsArray != IntPtr.Zero) Marshal.FreeHGlobal(ContactgeomsArray); if (GlobalContactsArray != IntPtr.Zero) @@ -2741,7 +2757,7 @@ namespace OpenSim.Region.Physics.OdePlugin { if (prm.CollisionScore > 0) { - returncolliders.Add(prm.m_localID, prm.CollisionScore); + returncolliders.Add(prm.LocalID, prm.CollisionScore); cnt++; prm.CollisionScore = 0f; if (cnt > 25) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index a43a8bb229..6ec3081e05 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2449,9 +2449,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } public LSL_Rotation llGetLocalRot() + { + return GetPartLocalRot(m_host); + } + + private LSL_Rotation GetPartLocalRot(SceneObjectPart part) { m_host.AddScriptLPS(1); - Quaternion rot = m_host.RotationOffset; + Quaternion rot = part.RotationOffset; return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W); } @@ -3708,7 +3713,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected void TargetOmega(SceneObjectPart part, LSL_Vector axis, double spinrate, double gain) { - spinrate *= gain; part.UpdateAngularVelocity(new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate))); } @@ -7761,7 +7765,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset. int idx = 0; - SceneObjectPart sitpart = World.GetSceneObjectPart(av.ParentID); // betting this will be used bool positionChanged = false; Vector3 finalPos = Vector3.Zero; @@ -7776,78 +7779,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api switch (code) { - // a avatar is a child case (int)ScriptBaseClass.PRIM_POSITION: case (int)ScriptBaseClass.PRIM_POS_LOCAL: { if (remain < 1) return; + LSL_Vector v; v = rules.GetVector3Item(idx++); - if (sitpart == null) + SceneObjectPart part = World.GetSceneObjectPart(av.ParentID); + if (part == null) break; - Vector3 pos = new Vector3((float)v.x, (float)v.y, (float)v.z); // requested absolute position - - if (sitpart != sitpart.ParentGroup.RootPart) + LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION; + LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR; + if (part.LinkNum > 1) { - pos -= sitpart.OffsetPosition; // remove sit part offset - Quaternion rot = sitpart.RotationOffset; - pos *= Quaternion.Conjugate(rot); // removed sit part rotation + localRot = GetPartLocalRot(part); + localPos = GetPartLocalPos(part); } - Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f * 2.0f); - pos += sitOffset; - finalPos = pos; - positionChanged = true; + v -= localPos; + v /= localRot; + + LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f); + + v = v + 2 * sitOffset; + + av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z); + av.SendAvatarDataToAllAgents(); + } break; + case (int)ScriptBaseClass.PRIM_ROT_LOCAL: case (int)ScriptBaseClass.PRIM_ROTATION: { if (remain < 1) return; - if (sitpart == null) + LSL_Rotation r; + r = rules.GetQuaternionItem(idx++); + + SceneObjectPart part = World.GetSceneObjectPart(av.ParentID); + if (part == null) break; - LSL_Rotation r = rules.GetQuaternionItem(idx++); - Quaternion rot = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s); // requested world rotation + LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION; + LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR; -// need to replicate SL bug - SceneObjectGroup sitgrp = sitpart.ParentGroup; - if (sitgrp != null && sitgrp.RootPart != sitpart) - { - rot = sitgrp.RootPart.RotationOffset * rot; - } + if (part.LinkNum > 1) + localRot = GetPartLocalRot(part); - Quaternion srot = sitpart.RotationOffset; - rot = Quaternion.Conjugate(srot) * rot; // removed sit part offset rotation - av.Rotation = rot; -// av.SendAvatarDataToAllAgents(); - av.SendTerseUpdateToAllClients(); - } - break; - - case (int)ScriptBaseClass.PRIM_ROT_LOCAL: - { - if (remain < 1) - return; - - if (sitpart == null) - break; - - LSL_Rotation r = rules.GetQuaternionItem(idx++); - Quaternion rot = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s); // requested offset rotation - if (sitpart != sitpart.ParentGroup.RootPart) - { - Quaternion srot = sitpart.RotationOffset; - rot = Quaternion.Conjugate(srot) * rot; // remove sit part offset rotation - } - av.Rotation = rot; -// av.SendAvatarDataToAllAgents(); - av.SendTerseUpdateToAllClients(); + r = r * llGetRootRotation() / localRot; + av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s); + av.SendAvatarDataToAllAgents(); } break; diff --git a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs index 2882906792..45ebf3abef 100644 --- a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs +++ b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs @@ -55,7 +55,10 @@ namespace OpenSim.Services.Connectors // Keeps track of concurrent requests for the same asset, so that it's only loaded once. // Maps: Asset ID -> Handlers which will be called when the asset has been loaded - private Dictionary m_AssetHandlers = new Dictionary(); +// private Dictionary m_AssetHandlers = new Dictionary(); + + private Dictionary> m_AssetHandlers = new Dictionary>(); + private Dictionary m_UriMap = new Dictionary(); public AssetServicesConnector() @@ -269,16 +272,21 @@ namespace OpenSim.Services.Connectors { AssetRetrievedEx handlerEx = new AssetRetrievedEx(delegate(AssetBase _asset) { handler(id, sender, _asset); }); - AssetRetrievedEx handlers; +// AssetRetrievedEx handlers; + List handlers; if (m_AssetHandlers.TryGetValue(id, out handlers)) { // Someone else is already loading this asset. It will notify our handler when done. - handlers += handlerEx; +// handlers += handlerEx; + handlers.Add(handlerEx); return true; } // Load the asset ourselves - handlers += handlerEx; +// handlers += handlerEx; + handlers = new List(); + handlers.Add(handlerEx); + m_AssetHandlers.Add(id, handlers); } @@ -290,14 +298,26 @@ namespace OpenSim.Services.Connectors { if (m_Cache != null) m_Cache.Cache(a); - +/* AssetRetrievedEx handlers; lock (m_AssetHandlers) { handlers = m_AssetHandlers[id]; m_AssetHandlers.Remove(id); } + handlers.Invoke(a); +*/ + List handlers; + lock (m_AssetHandlers) + { + handlers = m_AssetHandlers[id]; + m_AssetHandlers.Remove(id); + } + foreach (AssetRetrievedEx h in handlers) + h.Invoke(a); + if (handlers != null) + handlers.Clear(); }); success = true; @@ -306,10 +326,14 @@ namespace OpenSim.Services.Connectors { if (!success) { + List handlers; lock (m_AssetHandlers) { + handlers = m_AssetHandlers[id]; m_AssetHandlers.Remove(id); } + if (handlers != null) + handlers.Clear(); } } }