From c7e4b14a26c2c3a265b268a9e6c43e6c93db205e Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 30 Sep 2016 19:35:44 -0700 Subject: [PATCH 01/13] BulletSim: fix problem with avatar velocity going to zero when flying across region boundries. Move code for Velocity, ForceVelocity and SetMomentum to BSPhysObject and have both BSPrim and BSCharacter share the code. --- .../PhysicsModules/BulletS/BSCharacter.cs | 19 ++----- .../PhysicsModules/BulletS/BSPhysObject.cs | 45 +++++++++++++++- .../Region/PhysicsModules/BulletS/BSPrim.cs | 53 ++++--------------- 3 files changed, 58 insertions(+), 59 deletions(-) diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs b/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs index 5ad2136c1a..213f2eba45 100644 --- a/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs @@ -52,7 +52,6 @@ public sealed class BSCharacter : BSPhysObject private bool _setAlwaysRun; private bool _throttleUpdates; private bool _floatOnWater; - private OMV.Vector3 _rotationalVelocity; private bool _kinematic; private float _buoyancy; @@ -291,7 +290,7 @@ public sealed class BSCharacter : BSPhysObject { RawVelocity = OMV.Vector3.Zero; _acceleration = OMV.Vector3.Zero; - _rotationalVelocity = OMV.Vector3.Zero; + RawRotationalVelocity = OMV.Vector3.Zero; // Zero some other properties directly into the physics engine PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.ZeroMotion", delegate() @@ -303,7 +302,7 @@ public sealed class BSCharacter : BSPhysObject public override void ZeroAngularMotion(bool inTaintTime) { - _rotationalVelocity = OMV.Vector3.Zero; + RawRotationalVelocity = OMV.Vector3.Zero; PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.ZeroMotion", delegate() { @@ -618,14 +617,6 @@ public sealed class BSCharacter : BSPhysObject }); } } - public override OMV.Vector3 RotationalVelocity { - get { return _rotationalVelocity; } - set { _rotationalVelocity = value; } - } - public override OMV.Vector3 ForceRotationalVelocity { - get { return _rotationalVelocity; } - set { _rotationalVelocity = value; } - } public override bool Kinematic { get { return _kinematic; } set { _kinematic = value; } @@ -716,8 +707,6 @@ public sealed class BSCharacter : BSPhysObject public override void AddAngularForce(bool inTaintTime, OMV.Vector3 force) { } - public override void SetMomentum(OMV.Vector3 momentum) { - } // The avatar's physical shape (whether capsule or cube) is unit sized. BulletSim sets // the scale of that unit shape to create the avatars full size. @@ -841,7 +830,7 @@ public sealed class BSCharacter : BSPhysObject RawVelocity = entprop.Velocity; _acceleration = entprop.Acceleration; - _rotationalVelocity = entprop.RotationalVelocity; + RawRotationalVelocity = entprop.RotationalVelocity; // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. if (PositionSanityCheck(true)) @@ -861,7 +850,7 @@ public sealed class BSCharacter : BSPhysObject // PhysScene.PostUpdate(this); DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", - LocalID, RawPosition, RawOrientation, RawVelocity, _acceleration, _rotationalVelocity); + LocalID, RawPosition, RawOrientation, RawVelocity, _acceleration, RawRotationalVelocity); } } } diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs b/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs index bb21f0cf78..7c6f213bd7 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs @@ -239,6 +239,8 @@ public abstract class BSPhysObject : PhysicsActor public virtual OMV.Vector3 RawVelocity { get; set; } public abstract OMV.Vector3 ForceVelocity { get; set; } + public OMV.Vector3 RawRotationalVelocity { get; set; } + // RawForce is a constant force applied to object (see Force { set; } ) public OMV.Vector3 RawForce { get; set; } public OMV.Vector3 RawTorque { get; set; } @@ -250,7 +252,48 @@ public abstract class BSPhysObject : PhysicsActor public abstract void AddAngularForce(bool inTaintTime, OMV.Vector3 force); public abstract void AddForce(bool inTaintTime, OMV.Vector3 force); - public abstract OMV.Vector3 ForceRotationalVelocity { get; set; } + // PhysicsActor.SetMomentum + // All the physics engined use this as a way of forcing the velocity to something. + public override void SetMomentum(OMV.Vector3 momentum) + { + // This doesn't just set Velocity=momentum because velocity is ramped up to (see MoveActor) + RawVelocity = momentum; + PhysScene.TaintedObject(LocalID, TypeName + ".SetMomentum", delegate() + { + // DetailLog("{0},BSPrim.SetMomentum,taint,vel={1}", LocalID, RawVelocity); + ForceVelocity = RawVelocity; + }); + } + + public override OMV.Vector3 RotationalVelocity { + get { + return RawRotationalVelocity; + } + set { + RawRotationalVelocity = value; + Util.ClampV(RawRotationalVelocity, BSParam.MaxAngularVelocity); + // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); + PhysScene.TaintedObject(LocalID, TypeName + ".setRotationalVelocity", delegate() + { + ForceRotationalVelocity = RawRotationalVelocity; + }); + } + } + public OMV.Vector3 ForceRotationalVelocity { + get { + return RawRotationalVelocity; + } + set { + RawRotationalVelocity = Util.ClampV(value, BSParam.MaxAngularVelocity); + if (PhysBody.HasPhysicalBody) + { + DetailLog("{0},{1}.ForceRotationalVel,taint,rotvel={2}", LocalID, TypeName, RawRotationalVelocity); + PhysScene.PE.SetAngularVelocity(PhysBody, RawRotationalVelocity); + // PhysicsScene.PE.SetInterpolationAngularVelocity(PhysBody, _rotationalVelocity); + ActivateIfPhysical(false); + } + } + } public abstract float ForceBuoyancy { get; set; } diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs b/OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs index fd9b8344f4..78a617d731 100644 --- a/OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs @@ -59,7 +59,6 @@ public class BSPrim : BSPhysObject private bool _setAlwaysRun; private bool _throttleUpdates; private bool _floatOnWater; - private OMV.Vector3 _rotationalVelocity; private bool _kinematic; private float _buoyancy; @@ -90,7 +89,7 @@ public class BSPrim : BSPhysObject RawOrientation = rotation; _buoyancy = 0f; RawVelocity = OMV.Vector3.Zero; - _rotationalVelocity = OMV.Vector3.Zero; + RawRotationalVelocity = OMV.Vector3.Zero; BaseShape = pbs; _isPhysical = pisPhysical; _isVolumeDetect = false; @@ -256,7 +255,7 @@ public class BSPrim : BSPhysObject { RawVelocity = OMV.Vector3.Zero; _acceleration = OMV.Vector3.Zero; - _rotationalVelocity = OMV.Vector3.Zero; + RawRotationalVelocity = OMV.Vector3.Zero; // Zero some other properties in the physics engine PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ZeroMotion", delegate() @@ -267,15 +266,15 @@ public class BSPrim : BSPhysObject } public override void ZeroAngularMotion(bool inTaintTime) { - _rotationalVelocity = OMV.Vector3.Zero; + RawRotationalVelocity = OMV.Vector3.Zero; // Zero some other properties in the physics engine PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ZeroMotion", delegate() { // DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity); if (PhysBody.HasPhysicalBody) { - PhysScene.PE.SetInterpolationAngularVelocity(PhysBody, _rotationalVelocity); - PhysScene.PE.SetAngularVelocity(PhysBody, _rotationalVelocity); + PhysScene.PE.SetInterpolationAngularVelocity(PhysBody, RawRotationalVelocity); + PhysScene.PE.SetAngularVelocity(PhysBody, RawRotationalVelocity); } }); } @@ -426,9 +425,9 @@ public class BSPrim : BSPhysObject RawVelocity = Util.ClampV(RawVelocity, BSParam.MaxLinearVelocity); ret = true; } - if (_rotationalVelocity.LengthSquared() > BSParam.MaxAngularVelocitySquared) + if (RawRotationalVelocity.LengthSquared() > BSParam.MaxAngularVelocitySquared) { - _rotationalVelocity = Util.ClampV(_rotationalVelocity, BSParam.MaxAngularVelocity); + RawRotationalVelocity = Util.ClampV(RawRotationalVelocity, BSParam.MaxAngularVelocity); ret = true; } @@ -1008,7 +1007,7 @@ public class BSPrim : BSPhysObject // For good measure, make sure the transform is set through to the motion state ForcePosition = RawPosition; ForceVelocity = RawVelocity; - ForceRotationalVelocity = _rotationalVelocity; + ForceRotationalVelocity = RawRotationalVelocity; // A dynamic object has mass UpdatePhysicalMassProperties(RawMass, false); @@ -1128,35 +1127,6 @@ public class BSPrim : BSPhysObject }); } } - public override OMV.Vector3 RotationalVelocity { - get { - return _rotationalVelocity; - } - set { - _rotationalVelocity = value; - Util.ClampV(_rotationalVelocity, BSParam.MaxAngularVelocity); - // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); - PhysScene.TaintedObject(LocalID, "BSPrim.setRotationalVelocity", delegate() - { - ForceRotationalVelocity = _rotationalVelocity; - }); - } - } - public override OMV.Vector3 ForceRotationalVelocity { - get { - return _rotationalVelocity; - } - set { - _rotationalVelocity = Util.ClampV(value, BSParam.MaxAngularVelocity); - if (PhysBody.HasPhysicalBody) - { - DetailLog("{0},BSPrim.ForceRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); - PhysScene.PE.SetAngularVelocity(PhysBody, _rotationalVelocity); - // PhysicsScene.PE.SetInterpolationAngularVelocity(PhysBody, _rotationalVelocity); - ActivateIfPhysical(false); - } - } - } public override bool Kinematic { get { return _kinematic; } set { _kinematic = value; @@ -1358,9 +1328,6 @@ public class BSPrim : BSPhysObject }); } - public override void SetMomentum(OMV.Vector3 momentum) { - // DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum); - } #region Mass Calculation private float CalculateMass() @@ -1930,7 +1897,7 @@ public class BSPrim : BSPhysObject if (entprop.Velocity == OMV.Vector3.Zero || !entprop.Velocity.ApproxEquals(RawVelocity, BSParam.UpdateVelocityChangeThreshold)) RawVelocity = entprop.Velocity; _acceleration = entprop.Acceleration; - _rotationalVelocity = entprop.RotationalVelocity; + RawRotationalVelocity = entprop.RotationalVelocity; // DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG @@ -1939,7 +1906,7 @@ public class BSPrim : BSPhysObject { entprop.Position = RawPosition; entprop.Velocity = RawVelocity; - entprop.RotationalVelocity = _rotationalVelocity; + entprop.RotationalVelocity = RawRotationalVelocity; entprop.Acceleration = _acceleration; } From 878fac3fe3626a6bff003a8a6d7efce9e0d83e8a Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 1 Oct 2016 20:26:37 +0100 Subject: [PATCH 02/13] fix comment telling the correct default physics engine --- bin/OpenSimDefaults.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 47257b23ca..77ba3c81fe 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -293,7 +293,7 @@ ;; OpenDynamicsEngine was the previous default physics engine in OpenSimulator 0.7.6.1 and before. ;; It continues to provide a workable physics implementation. It does not currently support varregions. ;; basicphysics effectively does not model physics at all, making all objects phantom. - ;; Default is OpenDynamicsEngine + ;; Default is BulletSim physics = BulletSim ;physics = modified_BulletX ;physics = OpenDynamicsEngine From cd9d176c3cd710b29b43dd4420c7616ff0f01f43 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 2 Oct 2016 11:12:03 +0100 Subject: [PATCH 03/13] change avatar and attachments priority (downgraded) in priritizer option SimpleAngularDistance --- .../Region/Framework/Scenes/Prioritizer.cs | 65 +++++++++---------- 1 file changed, 30 insertions(+), 35 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs index 5669c43b70..ed80b3abe0 100644 --- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs +++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs @@ -274,50 +274,45 @@ namespace OpenSim.Region.Framework.Scenes private uint GetPriorityByAngularDistance(IClientAPI client, ISceneEntity entity) { - uint pqueue = 2; // keep compiler happy - ScenePresence presence = m_scene.GetScenePresence(client.AgentId); if (presence == null) return PriorityQueue.NumberOfQueues - 1; - // All avatars other than our own go into pqueue 1 - if (entity is ScenePresence) - return 1; - - if (entity is SceneObjectPart) - { - // Attachments are high priority, - if (((SceneObjectPart)entity).ParentGroup.IsAttachment) - return 2; - - pqueue = ComputeAngleDistancePriority(presence, entity); - - // Non physical prims are lower priority than physical prims - PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor; - if (physActor == null || !physActor.IsPhysical) - pqueue++; - } - + uint pqueue = ComputeAngleDistancePriority(presence, entity); return pqueue; } private uint ComputeAngleDistancePriority(ScenePresence presence, ISceneEntity entity) { - double distance; - - Vector3 presencePos = presence.AbsolutePosition; - - SceneObjectGroup group = (entity as SceneObjectPart).ParentGroup; - float bradius = group.GetBoundsRadius(); - Vector3 grppos = group.AbsolutePosition + group.getBoundsCenter(); - distance = Vector3.Distance(presencePos, grppos); - distance -= bradius; - distance *= group.getAreaFactor(); - // And convert the distance to a priority queue, this computation gives queues // at 10, 20, 40, 80, 160, 320, 640, and 1280m - uint pqueue = PriorityQueue.NumberOfImmediateQueues + 1; // reserve attachments queue - uint queues = PriorityQueue.NumberOfQueues - PriorityQueue.NumberOfImmediateQueues; + uint minpqueue = PriorityQueue.NumberOfImmediateQueues; + uint maxqueue = PriorityQueue.NumberOfQueues - PriorityQueue.NumberOfImmediateQueues -1; + uint pqueue = minpqueue; + float distance; + + Vector3 presencePos = presence.AbsolutePosition; + if(entity is ScenePresence) + { + ScenePresence sp = entity as ScenePresence; + distance = Vector3.Distance(presencePos, sp.AbsolutePosition); + distance *= 0.5f; + } + else + { + SceneObjectGroup group = (entity as SceneObjectPart).ParentGroup; + float bradius = group.GetBoundsRadius(); + Vector3 grppos = group.AbsolutePosition + group.getBoundsCenter(); + distance = Vector3.Distance(presencePos, grppos); + distance -= bradius; + distance *= group.getAreaFactor(); + if(group.IsAttachment) + distance *= 0.5f; + else if(group.GetSittingAvatarsCount() > 0) + distance *= 0.5f; + else if(group.UsesPhysics) + distance *= 0.6f; + } if (distance > 10f) { @@ -328,8 +323,8 @@ namespace OpenSim.Region.Framework.Scenes // 2st constant makes it be log2(distance/10) pqueue += (uint)tmp; - if (pqueue > queues - 1) - pqueue = queues - 1; + if (pqueue > maxqueue) + pqueue = maxqueue; } return pqueue; From f3e7603c37a5448f5a4ac59a2621b24724707288 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 2 Oct 2016 11:54:07 +0100 Subject: [PATCH 04/13] minor cleanup --- OpenSim/Region/Framework/Scenes/Prioritizer.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs index ed80b3abe0..97009a04ac 100644 --- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs +++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs @@ -286,9 +286,10 @@ namespace OpenSim.Region.Framework.Scenes { // And convert the distance to a priority queue, this computation gives queues // at 10, 20, 40, 80, 160, 320, 640, and 1280m - uint minpqueue = PriorityQueue.NumberOfImmediateQueues; +// uint minpqueue = PriorityQueue.NumberOfImmediateQueues; uint maxqueue = PriorityQueue.NumberOfQueues - PriorityQueue.NumberOfImmediateQueues -1; - uint pqueue = minpqueue; +// uint pqueue = minpqueue; + uint pqueue = PriorityQueue.NumberOfImmediateQueues; float distance; Vector3 presencePos = presence.AbsolutePosition; @@ -308,10 +309,10 @@ namespace OpenSim.Region.Framework.Scenes distance *= group.getAreaFactor(); if(group.IsAttachment) distance *= 0.5f; - else if(group.GetSittingAvatarsCount() > 0) - distance *= 0.5f; else if(group.UsesPhysics) distance *= 0.6f; + else if(group.GetSittingAvatarsCount() > 0) + distance *= 0.5f; } if (distance > 10f) From e13fecfd3d465cd51f4d0802b3f2a4d9b2c989b7 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 3 Oct 2016 20:47:30 -0700 Subject: [PATCH 05/13] BulletSim: zero velocity target when setting velocity through the SetMomentum method. --- OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs | 12 +++++++++++- .../Region/PhysicsModules/BulletS/BSPhysObject.cs | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs b/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs index 213f2eba45..757f06ccd3 100644 --- a/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs @@ -350,7 +350,6 @@ public sealed class BSCharacter : BSPhysObject } } - // Check that the current position is sane and, if not, modify the position to make it so. // Check for being below terrain or on water. // Returns 'true' of the position was made sane by some action. @@ -502,6 +501,17 @@ public sealed class BSCharacter : BSPhysObject } } + // SetMomentum just sets the velocity without a target. We need to stop the movement actor if a character. + public override void SetMomentum(OMV.Vector3 momentum) + { + if (m_moveActor != null) + { + m_moveActor.SetVelocityAndTarget(OMV.Vector3.Zero, OMV.Vector3.Zero, false /* inTaintTime */); + } + base.SetMomentum(momentum); + } + + public override OMV.Vector3 Torque { get { return RawTorque; } set { RawTorque = value; diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs b/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs index 7c6f213bd7..3682455154 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs @@ -625,7 +625,7 @@ public abstract class BSPhysObject : PhysicsActor { CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); DetailLog("{0},{1}.SubscribeEvents,setting collision. ms={2}, collisionFlags={3:x}", - LocalID, TypeName, ms, CurrentCollisionFlags); + LocalID, TypeName, SubscribedEventsMs, CurrentCollisionFlags); } }); } From 8a3958ad048535ad4f8a752cbd71d9114e53a42b Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 5 Oct 2016 13:17:23 +0100 Subject: [PATCH 06/13] dont let ignored AgentUpdates change their throttles. Apply respective movement to physics on the handling thread, not heartbeat, avoiding missing transitions that should get into physics. Make some usefull sp state flags visible everywhere --- OpenSim/Framework/ISceneAgent.cs | 3 + .../ClientStack/Linden/UDP/LLClientView.cs | 87 +++++++++---------- .../Region/Framework/Scenes/ScenePresence.cs | 49 +++++++---- 3 files changed, 79 insertions(+), 60 deletions(-) diff --git a/OpenSim/Framework/ISceneAgent.cs b/OpenSim/Framework/ISceneAgent.cs index 1848b1757e..c8424e3691 100644 --- a/OpenSim/Framework/ISceneAgent.cs +++ b/OpenSim/Framework/ISceneAgent.cs @@ -55,6 +55,9 @@ namespace OpenSim.Framework /// bool IsChildAgent { get; } + bool IsInTransit { get; } + bool isNPC { get;} + bool Invulnerable { get; set; } /// /// Avatar appearance data. diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 8194260ebf..2650be4c88 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -909,7 +909,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look) { m_thisAgentUpdateArgs.CameraAtAxis.X = float.MinValue; - m_thisAgentUpdateArgs.ControlFlags = uint.MaxValue; +// m_thisAgentUpdateArgs.ControlFlags = uint.MaxValue; + m_thisAgentUpdateArgs.ControlFlags = 0; AgentMovementCompletePacket mov = (AgentMovementCompletePacket)PacketPool.Instance.GetPacket(PacketType.AgentMovementComplete); mov.SimData.ChannelVersion = m_channelVersion; @@ -6196,27 +6197,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// private bool CheckAgentMovementUpdateSignificance(AgentUpdatePacket.AgentDataBlock x) { - float qdelta1 = Math.Abs(Quaternion.Dot(x.BodyRotation, m_thisAgentUpdateArgs.BodyRotation)); - //qdelta2 = Math.Abs(Quaternion.Dot(x.HeadRotation, m_thisAgentUpdateArgs.HeadRotation)); - - bool movementSignificant = + if( (x.ControlFlags != m_thisAgentUpdateArgs.ControlFlags) // significant if control flags changed - || (x.ControlFlags != (byte)AgentManager.ControlFlags.NONE) // significant if user supplying any movement update commands + || ((x.ControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0 && + (x.ControlFlags & 0x3f8dfff) != 0) // we need to rotate the av on fly || (x.Flags != m_thisAgentUpdateArgs.Flags) // significant if Flags changed || (x.State != m_thisAgentUpdateArgs.State) // significant if Stats changed - || (qdelta1 < QDELTABody) // significant if body rotation above(below cos) threshold - // Ignoring head rotation altogether, because it's not being used for anything interesting up the stack - // || (qdelta2 < QDELTAHead) // significant if head rotation above(below cos) threshold || (Math.Abs(x.Far - m_thisAgentUpdateArgs.Far) >= 32) // significant if far distance changed - ; - //if (movementSignificant) - //{ - //m_log.DebugFormat("[LLCLIENTVIEW]: Bod {0} {1}", - // qdelta1, qdelta2); - //m_log.DebugFormat("[LLCLIENTVIEW]: St {0} {1} {2} {3}", - // x.ControlFlags, x.Flags, x.Far, x.State); - //} - return movementSignificant; + ) + return true; + + float qdelta1 = Math.Abs(Quaternion.Dot(x.BodyRotation, m_thisAgentUpdateArgs.BodyRotation)); + //qdelta2 = Math.Abs(Quaternion.Dot(x.HeadRotation, m_thisAgentUpdateArgs.HeadRotation)); + + if( + qdelta1 < QDELTABody // significant if body rotation above(below cos) threshold + // Ignoring head rotation altogether, because it's not being used for anything interesting up the stack + // || qdelta2 < QDELTAHead // significant if head rotation above(below cos) threshold + ) + return true; + + return false; } /// @@ -6227,33 +6228,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// private bool CheckAgentCameraUpdateSignificance(AgentUpdatePacket.AgentDataBlock x) { - float vdelta1 = Vector3.Distance(x.CameraAtAxis, m_thisAgentUpdateArgs.CameraAtAxis); - float vdelta2 = Vector3.Distance(x.CameraCenter, m_thisAgentUpdateArgs.CameraCenter); - float vdelta3 = Vector3.Distance(x.CameraLeftAxis, m_thisAgentUpdateArgs.CameraLeftAxis); - float vdelta4 = Vector3.Distance(x.CameraUpAxis, m_thisAgentUpdateArgs.CameraUpAxis); + float vdelta = Vector3.Distance(x.CameraAtAxis, m_thisAgentUpdateArgs.CameraAtAxis); + if((vdelta > VDELTA)) + return true; - bool cameraSignificant = - (vdelta1 > VDELTA) || - (vdelta2 > VDELTA) || - (vdelta3 > VDELTA) || - (vdelta4 > VDELTA) - ; + vdelta = Vector3.Distance(x.CameraCenter, m_thisAgentUpdateArgs.CameraCenter); + if((vdelta > VDELTA)) + return true; - //if (cameraSignificant) - //{ - //m_log.DebugFormat("[LLCLIENTVIEW]: Cam1 {0} {1}", - // x.CameraAtAxis, x.CameraCenter); - //m_log.DebugFormat("[LLCLIENTVIEW]: Cam2 {0} {1}", - // x.CameraLeftAxis, x.CameraUpAxis); - //} + vdelta = Vector3.Distance(x.CameraLeftAxis, m_thisAgentUpdateArgs.CameraLeftAxis); + if((vdelta > VDELTA)) + return true; - return cameraSignificant; + vdelta = Vector3.Distance(x.CameraUpAxis, m_thisAgentUpdateArgs.CameraUpAxis); + if((vdelta > VDELTA)) + return true; + + return false; } private bool HandleAgentUpdate(IClientAPI sender, Packet packet) { - // We got here, which means that something in agent update was significant - AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet; AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData; @@ -6264,10 +6259,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP } TotalAgentUpdates++; + // dont let ignored updates pollute this throttles + if(SceneAgent == null || SceneAgent.IsChildAgent || SceneAgent.IsInTransit) + { + // throttle reset is done at MoveAgentIntoRegion() + // called by scenepresence on completemovement + PacketPool.Instance.ReturnPacket(packet); + return true; + } bool movement = CheckAgentMovementUpdateSignificance(x); bool camera = CheckAgentCameraUpdateSignificance(x); - + // Was there a significant movement/state change? if (movement) { @@ -6276,7 +6279,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_thisAgentUpdateArgs.Far = x.Far; m_thisAgentUpdateArgs.Flags = x.Flags; m_thisAgentUpdateArgs.HeadRotation = x.HeadRotation; -// m_thisAgentUpdateArgs.SessionID = x.SessionID; m_thisAgentUpdateArgs.State = x.State; UpdateAgent handlerAgentUpdate = OnAgentUpdate; @@ -6287,9 +6289,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (handlerAgentUpdate != null) OnAgentUpdate(this, m_thisAgentUpdateArgs); - - handlerAgentUpdate = null; - handlerPreAgentUpdate = null; + } // Was there a significant camera(s) change? @@ -6305,7 +6305,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (handlerAgentCameraUpdate != null) handlerAgentCameraUpdate(this, m_thisAgentUpdateArgs); - handlerAgentCameraUpdate = null; } PacketPool.Instance.ReturnPacket(packet); diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index bb6e89b3ba..6f4d6c3f97 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -281,7 +281,9 @@ namespace OpenSim.Region.Framework.Scenes private bool m_followCamAuto = false; - private Vector3? m_forceToApply; +// private object m_forceToApplyLock = new object(); +// private bool m_forceToApplyValid; +// private Vector3 m_forceToApply; private int m_userFlags; public int UserFlags { @@ -582,11 +584,11 @@ namespace OpenSim.Region.Framework.Scenes { get { - return m_drawDistance; + return m_drawDistance; } set { - m_drawDistance = Util.Clamp(value, 32f, m_scene.MaxDrawDistance); + m_drawDistance = Util.Clamp(value, 32f, m_scene.MaxDrawDistance); } } @@ -594,7 +596,7 @@ namespace OpenSim.Region.Framework.Scenes { get { - return Util.Clamp(m_drawDistance, 32f, m_scene.MaxRegionViewDistance); + return Util.Clamp(m_drawDistance, 32f, m_scene.MaxRegionViewDistance); } } @@ -2120,6 +2122,7 @@ namespace OpenSim.Region.Framework.Scenes if (haveAnims) SendAnimPackToAgent(this, animIDs, animseqs, animsobjs); + // we should be able to receive updates, etc // so release them m_inTransit = false; @@ -2238,6 +2241,9 @@ namespace OpenSim.Region.Framework.Scenes } finally { + haveGroupInformation = false; + gotCrossUpdate = false; + crossingFlags = 0; m_inTransit = false; } // if hide force a check @@ -2247,9 +2253,6 @@ namespace OpenSim.Region.Framework.Scenes // m_currentParcelHide = newhide; // } - haveGroupInformation = false; - gotCrossUpdate = false; - crossingFlags = 0; m_scene.EventManager.OnRegionHeartbeatEnd += RegionHeartbeatEnd; @@ -3006,7 +3009,8 @@ namespace OpenSim.Region.Framework.Scenes MovingToTarget = false; // MoveToPositionTarget = Vector3.Zero; - m_forceToApply = null; // cancel possible last action +// lock(m_forceToApplyLock) +// m_forceToApplyValid = false; // cancel possible last action // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag. @@ -3638,8 +3642,14 @@ namespace OpenSim.Region.Framework.Scenes } // m_log.DebugFormat("[SCENE PRESENCE]: Setting force to apply to {0} for {1}", direc, Name); - - m_forceToApply = direc; +/* + lock(m_forceToApplyLock) + { + m_forceToApply = direc; + m_forceToApplyValid = true; + } +*/ + Velocity = direc; Animator.UpdateMovementAnimations(); } @@ -4734,17 +4744,21 @@ namespace OpenSim.Region.Framework.Scenes /// public void UpdateMovement() { +/* if (IsInTransit) return; - if (m_forceToApply.HasValue) + + lock(m_forceToApplyLock) { - Vector3 force = m_forceToApply.Value; + if (m_forceToApplyValid) + { + Velocity = m_forceToApply; - Velocity = force; - - m_forceToApply = null; - TriggerScenePresenceUpdated(); + m_forceToApplyValid = false; + TriggerScenePresenceUpdated(); + } } +*/ } /// @@ -4767,6 +4781,9 @@ namespace OpenSim.Region.Framework.Scenes // Appearance.SetHeight(); Appearance.SetSize(new Vector3(0.45f,0.6f,1.9f)); +// lock(m_forceToApplyLock) +// m_forceToApplyValid = false; + PhysicsScene scene = m_scene.PhysicsScene; Vector3 pVec = AbsolutePosition; From 76a2d90dada467a16c462bbdc49fdc175be66e29 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 5 Oct 2016 13:38:12 +0100 Subject: [PATCH 07/13] remove attachment to event OnPreAgentUpdate that is doing nothing --- .../Region/CoreModules/World/Land/LandManagementModule.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 68c9c971a5..11a6d9f745 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -212,7 +212,6 @@ namespace OpenSim.Region.CoreModules.World.Land client.OnParcelReclaim += ClientOnParcelReclaim; client.OnParcelInfoRequest += ClientOnParcelInfoRequest; client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup; - client.OnPreAgentUpdate += ClientOnPreAgentUpdate; client.OnParcelEjectUser += ClientOnParcelEjectUser; client.OnParcelFreezeUser += ClientOnParcelFreezeUser; client.OnSetStartLocationRequest += ClientOnSetHome; @@ -223,10 +222,6 @@ namespace OpenSim.Region.CoreModules.World.Land avatar.currentParcelUUID = UUID.Zero; } - void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) - { - } - public void Close() { } From 7494d7726afd9f8b9762d78aead918ba7a90efa3 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 11 Oct 2016 01:14:53 +0100 Subject: [PATCH 08/13] change math on GetParcelMaxPrimCount and GetSimulatorMaxPrimCount to reduce round errors, limit both to region max prims. consider ObjectBonus on last one also. Change a variable name in PrimLimitsModule to make it more clear --- .../CoreModules/World/Land/LandObject.cs | 25 +++++++++++++------ .../PrimLimitsModule/PrimLimitsModule.cs | 4 +-- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 69a34550a9..4cbc8b81af 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -341,10 +341,16 @@ namespace OpenSim.Region.CoreModules.World.Land else { // Normal Calculations - int parcelMax = (int)( (long)LandData.Area - * (long)m_scene.RegionInfo.ObjectCapacity - * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus - / (long)(m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY) ); + int parcelMax = (int)( + (double)LandData.Area + * (double)m_scene.RegionInfo.ObjectCapacity + * (double)m_scene.RegionInfo.RegionSettings.ObjectBonus + / (double)(m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY) + + 0.5 ); + + if(parcelMax > m_scene.RegionInfo.ObjectCapacity) + parcelMax = m_scene.RegionInfo.ObjectCapacity; + //m_log.DebugFormat("Area: {0}, Capacity {1}, Bonus {2}, Parcel {3}", LandData.Area, m_scene.RegionInfo.ObjectCapacity, m_scene.RegionInfo.RegionSettings.ObjectBonus, parcelMax); return parcelMax; } @@ -359,9 +365,14 @@ namespace OpenSim.Region.CoreModules.World.Land else { //Normal Calculations - int simMax = (int)( (long)LandData.SimwideArea - * (long)m_scene.RegionInfo.ObjectCapacity - / (long)(m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY) ); + int simMax = (int)( (double)LandData.SimwideArea + * (double)m_scene.RegionInfo.ObjectCapacity + * (double)m_scene.RegionInfo.RegionSettings.ObjectBonus + / (long)(m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY) + +0.5 ); + + if(simMax > m_scene.RegionInfo.ObjectCapacity) + simMax = m_scene.RegionInfo.ObjectCapacity; //m_log.DebugFormat("Simwide Area: {0}, Capacity {1}, SimMax {2}, SimWidePrims {3}", // LandData.SimwideArea, m_scene.RegionInfo.ObjectCapacity, simMax, LandData.SimwidePrims); return simMax; diff --git a/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs b/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs index 50a5fae06d..4ffb03bd75 100644 --- a/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs +++ b/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs @@ -186,8 +186,8 @@ namespace OpenSim.Region.OptionalModules { string response = null; - int simulatorCapacity = lo.GetSimulatorMaxPrimCount(); - if ((objectCount + lo.PrimCounts.Total) > simulatorCapacity) + int OwnedParcelsCapacity = lo.GetSimulatorMaxPrimCount(); + if ((objectCount + lo.PrimCounts.Total) > OwnedParcelsCapacity) { response = "Unable to rez object because the parcel is too full"; } From 7cd4fa8cf5f51e576aeb866a83649206e37e8483 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 15 Oct 2016 20:26:23 +0100 Subject: [PATCH 09/13] bug fix: We can't filter out any of the avatar controls relative to movement, even if not flying (a condition i incorrectly added recently) in fact the entire AgentUpdates throotling is questionable, since its viewer Job. But keeping it... --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 2650be4c88..48cb85edf4 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -6173,8 +6173,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Threshold for body rotation to be a significant agent update // use the abs of cos - private const float QDELTABody = 1.0f - 0.0001f; - private const float QDELTAHead = 1.0f - 0.0001f; + private const float QDELTABody = 1.0f - 0.00005f; + private const float QDELTAHead = 1.0f - 0.00005f; // Threshold for camera rotation to be a significant agent update private const float VDELTA = 0.01f; @@ -6199,8 +6199,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if( (x.ControlFlags != m_thisAgentUpdateArgs.ControlFlags) // significant if control flags changed - || ((x.ControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0 && - (x.ControlFlags & 0x3f8dfff) != 0) // we need to rotate the av on fly +// || ((x.ControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0 && +// (x.ControlFlags & 0x3f8dfff) != 0) // we need to rotate the av on fly + || (x.ControlFlags & 0x3f8dfff) != 0 // actually all movement controls need to pass || (x.Flags != m_thisAgentUpdateArgs.Flags) // significant if Flags changed || (x.State != m_thisAgentUpdateArgs.State) // significant if Stats changed || (Math.Abs(x.Far - m_thisAgentUpdateArgs.Far) >= 32) // significant if far distance changed From 954bcbc5efad2a0cf7bf1784d363816a8987fdbb Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 15 Oct 2016 20:44:18 +0100 Subject: [PATCH 10/13] bug fix: let ALL avatar controls have a repeat rate controled by viewer (so as before commit 8a3958ad048535ad4f8a752cbd71d9114e53a42b on this) --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 48cb85edf4..fd3f997525 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -6201,7 +6201,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP (x.ControlFlags != m_thisAgentUpdateArgs.ControlFlags) // significant if control flags changed // || ((x.ControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0 && // (x.ControlFlags & 0x3f8dfff) != 0) // we need to rotate the av on fly - || (x.ControlFlags & 0x3f8dfff) != 0 // actually all movement controls need to pass + || x.ControlFlags != (byte)AgentManager.ControlFlags.NONE// actually all movement controls need to pass || (x.Flags != m_thisAgentUpdateArgs.Flags) // significant if Flags changed || (x.State != m_thisAgentUpdateArgs.State) // significant if Stats changed || (Math.Abs(x.Far - m_thisAgentUpdateArgs.Far) >= 32) // significant if far distance changed From 90be326457160a6f433dea2d544a596f429279e9 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 15 Oct 2016 21:06:17 +0100 Subject: [PATCH 11/13] Xengine option AppDomainLoading default option true is causing problems with several mono versions. Until a fix is found change the default to false, so this is not a major problem for the less technical skilled users. --- bin/OpenSim.ini.example | 6 ++++-- bin/OpenSimDefaults.ini | 11 ++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 3fe3992093..8fc608da53 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -903,8 +903,10 @@ ;; ;; However, setting this to false will also prevent script DLLs from being unloaded from memory if the script is deleted. ;; This may cause an OutOfMemory problem over time when avatars with scripted attachments move in and out of the region. - ;; Some Windows users have also reported script loading problems when AppDomainLoading = false - ; AppDomainLoading = true + ;; at this time some mono versions seem to have problems with the true option + ;; so default is now false until a fix is found, to simply life of less technical skilled users. + ;; this should only be a issue if regions stay alive for a long time with lots of scripts added or edited. + ; AppDomainLoading = false ;; Controls whether scripts are stopped by aborting their threads externally (abort) or by co-operative checks from the compiled script (co-op) ;; co-op will be more stable but this option is currently experimental. diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 77ba3c81fe..e846e73e0e 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -1690,12 +1690,13 @@ ; Stack size per thread created ThreadStackSize = 262144 - ; Set this to true (the default) to load each script into a separate + ; Set this to true to load each script into a separate ; AppDomain. Setting this to false will load all script assemblies into the - ; current AppDomain, which will reduce the per-script overhead at the - ; expense of reduced security and the inability to garbage collect the - ; script assemblies - AppDomainLoading = true + ; current AppDomain, which will reduce the per-script overhead but deleted scripts stay inactive using memory + ; this may only be a problem if regions stay alive for a long time with lots of scripts added or edited. + ; at this time some mono versions seem to have problems with the true option + ; so default is now false until a fix is found + AppDomainLoading = false ; Controls whether previously compiled scripts DLLs are deleted on sim restart. If you set this to false ; then startup will be considerably faster since scripts won't need to be recompiled. However, then it becomes your responsibility to delete the From eaac332d00b193137b8b8e26b5fa323b6b7b2a55 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 16 Oct 2016 17:33:39 +0100 Subject: [PATCH 12/13] fix a coment on OpenSim.ini.example ( mantis 8037) --- bin/OpenSim.ini.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 8fc608da53..4b83751daf 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -894,7 +894,7 @@ ;; The trade-off may be increased memory usage by the script engine. ; ThreadStackSize = 262144 - ;; Set this to true (the default) to load each script into a separate + ;; Set this to true to load each script into a separate ;; AppDomain. ;; ;; Setting this to false will load all script assemblies into the From 586e4cf163cd68b47fce0b25ee34a0155d41bf4c Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 17 Oct 2016 19:16:07 +0100 Subject: [PATCH 13/13] ignore prims with shape type none on max size check for physics --- .../Framework/Scenes/SceneObjectGroup.cs | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 53a9441896..e643db7436 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3869,15 +3869,11 @@ namespace OpenSim.Region.Framework.Scenes for (int i = 0; i < parts.Length; i++) { SceneObjectPart part = parts[i]; - if (part.Scale.X > m_scene.m_maxPhys || - part.Scale.Y > m_scene.m_maxPhys || - part.Scale.Z > m_scene.m_maxPhys ) - { - UsePhysics = false; // Reset physics - break; - } - if (checkShape && part.PhysicsShapeType != (byte)PhysicsShapeType.None) + if(part.PhysicsShapeType == (byte)PhysicsShapeType.None) + continue; // assuming root type was checked elsewhere + + if (checkShape) { if (--maxprims < 0) { @@ -3885,6 +3881,14 @@ namespace OpenSim.Region.Framework.Scenes break; } } + + if (part.Scale.X > m_scene.m_maxPhys || + part.Scale.Y > m_scene.m_maxPhys || + part.Scale.Z > m_scene.m_maxPhys ) + { + UsePhysics = false; // Reset physics + break; + } } }