diff options
Diffstat (limited to 'OpenSim')
9 files changed, 170 insertions, 221 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 74701a5..f41e89e 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | |||
@@ -768,6 +768,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
768 | { | 768 | { |
769 | g.RootPart.AttachPoint = g.RootPart.Shape.State; | 769 | g.RootPart.AttachPoint = g.RootPart.Shape.State; |
770 | g.RootPart.AttachOffset = g.AbsolutePosition; | 770 | g.RootPart.AttachOffset = g.AbsolutePosition; |
771 | g.RootPart.Shape.State = 0; | ||
771 | } | 772 | } |
772 | 773 | ||
773 | objlist.Add(g); | 774 | objlist.Add(g); |
@@ -800,6 +801,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
800 | SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml); | 801 | SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml); |
801 | g.RootPart.AttachPoint = g.RootPart.Shape.State; | 802 | g.RootPart.AttachPoint = g.RootPart.Shape.State; |
802 | g.RootPart.AttachOffset = g.AbsolutePosition; | 803 | g.RootPart.AttachOffset = g.AbsolutePosition; |
804 | g.RootPart.Shape.State = 0; | ||
803 | 805 | ||
804 | objlist.Add(g); | 806 | objlist.Add(g); |
805 | XmlElement el = (XmlElement)n; | 807 | XmlElement el = (XmlElement)n; |
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 0a1b921..f6f6a1a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -1519,8 +1519,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
1519 | if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) | 1519 | if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) |
1520 | { | 1520 | { |
1521 | // VolumeDetect can't be set via UI and will always be off when a change is made there | 1521 | // VolumeDetect can't be set via UI and will always be off when a change is made there |
1522 | if (PhysData.PhysShapeType == PhysShapeType.invalid) | 1522 | // now only change volume dtc if phantom off |
1523 | group.UpdatePrimFlags(localID, UsePhysics, SetTemporary, SetPhantom, false); | 1523 | |
1524 | if (PhysData.PhysShapeType == PhysShapeType.invalid) // check for extraPhysics data | ||
1525 | { | ||
1526 | bool vdtc; | ||
1527 | if (SetPhantom) // if phantom keep volumedtc | ||
1528 | vdtc = group.RootPart.VolumeDetectActive; | ||
1529 | else // else turn it off | ||
1530 | vdtc = false; | ||
1531 | |||
1532 | group.UpdatePrimFlags(localID, UsePhysics, SetTemporary, SetPhantom, vdtc); | ||
1533 | } | ||
1524 | else | 1534 | else |
1525 | { | 1535 | { |
1526 | SceneObjectPart part = GetSceneObjectPart(localID); | 1536 | SceneObjectPart part = GetSceneObjectPart(localID); |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 7bd6c11..cb0a57a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -1941,6 +1941,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
1941 | // "[SCENE]: Storing {0}, {1} in {2}", | 1941 | // "[SCENE]: Storing {0}, {1} in {2}", |
1942 | // Name, UUID, m_scene.RegionInfo.RegionName); | 1942 | // Name, UUID, m_scene.RegionInfo.RegionName); |
1943 | 1943 | ||
1944 | if (RootPart.Shape.PCode == 9 && RootPart.Shape.State != 0) | ||
1945 | { | ||
1946 | RootPart.Shape.State = 0; | ||
1947 | ScheduleGroupForFullUpdate(); | ||
1948 | } | ||
1949 | |||
1944 | SceneObjectGroup backup_group = Copy(false); | 1950 | SceneObjectGroup backup_group = Copy(false); |
1945 | backup_group.RootPart.Velocity = RootPart.Velocity; | 1951 | backup_group.RootPart.Velocity = RootPart.Velocity; |
1946 | backup_group.RootPart.Acceleration = RootPart.Acceleration; | 1952 | backup_group.RootPart.Acceleration = RootPart.Acceleration; |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 511ab19..c73fc98 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -1830,7 +1830,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1830 | 1830 | ||
1831 | public void ApplyPhysics(uint _ObjectFlags, bool _VolumeDetectActive, bool building) | 1831 | public void ApplyPhysics(uint _ObjectFlags, bool _VolumeDetectActive, bool building) |
1832 | { | 1832 | { |
1833 | VolumeDetectActive = _VolumeDetectActive; //?? as is used this is redundante | 1833 | VolumeDetectActive = _VolumeDetectActive; |
1834 | 1834 | ||
1835 | if (!ParentGroup.Scene.CollidablePrims) | 1835 | if (!ParentGroup.Scene.CollidablePrims) |
1836 | return; | 1836 | return; |
@@ -1839,7 +1839,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
1839 | return; | 1839 | return; |
1840 | 1840 | ||
1841 | bool isPhysical = (_ObjectFlags & (uint) PrimFlags.Physics) != 0; | 1841 | bool isPhysical = (_ObjectFlags & (uint) PrimFlags.Physics) != 0; |
1842 | bool isPhantom = (_ObjectFlags & (uint) PrimFlags.Phantom) != 0; | 1842 | bool isPhantom = (_ObjectFlags & (uint)PrimFlags.Phantom) != 0; |
1843 | |||
1844 | if (_VolumeDetectActive) | ||
1845 | isPhantom = true; | ||
1843 | 1846 | ||
1844 | if (IsJoint()) | 1847 | if (IsJoint()) |
1845 | { | 1848 | { |
@@ -2065,6 +2068,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2065 | 2068 | ||
2066 | /// <summary> | 2069 | /// <summary> |
2067 | /// Do a physics propery update for this part. | 2070 | /// Do a physics propery update for this part. |
2071 | /// now also updates phantom and volume detector | ||
2068 | /// </summary> | 2072 | /// </summary> |
2069 | /// <param name="UsePhysics"></param> | 2073 | /// <param name="UsePhysics"></param> |
2070 | /// <param name="isNew"></param> | 2074 | /// <param name="isNew"></param> |
@@ -2096,7 +2100,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2096 | if (ParentGroup.RootPart == this) | 2100 | if (ParentGroup.RootPart == this) |
2097 | AngularVelocity = new Vector3(0, 0, 0); | 2101 | AngularVelocity = new Vector3(0, 0, 0); |
2098 | 2102 | ||
2099 | if (pa.Phantom) | 2103 | if (pa.Phantom && !VolumeDetectActive) |
2100 | { | 2104 | { |
2101 | RemoveFromPhysics(); | 2105 | RemoveFromPhysics(); |
2102 | return; | 2106 | return; |
@@ -2143,6 +2147,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
2143 | if (pa.Phantom != phan) | 2147 | if (pa.Phantom != phan) |
2144 | pa.Phantom = phan; | 2148 | pa.Phantom = phan; |
2145 | 2149 | ||
2150 | // some engines dont' have this check still | ||
2151 | // if (VolumeDetectActive != pa.IsVolumeDtc) | ||
2152 | { | ||
2153 | if (VolumeDetectActive) | ||
2154 | pa.SetVolumeDetect(1); | ||
2155 | else | ||
2156 | pa.SetVolumeDetect(0); | ||
2157 | } | ||
2146 | 2158 | ||
2147 | // If this part is a sculpt then delay the physics update until we've asynchronously loaded the | 2159 | // If this part is a sculpt then delay the physics update until we've asynchronously loaded the |
2148 | // mesh data. | 2160 | // mesh data. |
@@ -4599,6 +4611,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
4599 | if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD)) | 4611 | if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD)) |
4600 | return; | 4612 | return; |
4601 | 4613 | ||
4614 | VolumeDetectActive = SetVD; | ||
4615 | |||
4616 | // volume detector implies phantom | ||
4617 | if (VolumeDetectActive) | ||
4618 | SetPhantom = true; | ||
4619 | |||
4602 | if (UsePhysics) | 4620 | if (UsePhysics) |
4603 | AddFlag(PrimFlags.Physics); | 4621 | AddFlag(PrimFlags.Physics); |
4604 | else | 4622 | else |
@@ -4614,7 +4632,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
4614 | else | 4632 | else |
4615 | RemFlag(PrimFlags.TemporaryOnRez); | 4633 | RemFlag(PrimFlags.TemporaryOnRez); |
4616 | 4634 | ||
4617 | VolumeDetectActive = SetVD; | ||
4618 | 4635 | ||
4619 | if (ParentGroup.Scene == null) | 4636 | if (ParentGroup.Scene == null) |
4620 | return; | 4637 | return; |
@@ -4624,7 +4641,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4624 | if (pa != null && building && pa.Building != building) | 4641 | if (pa != null && building && pa.Building != building) |
4625 | pa.Building = building; | 4642 | pa.Building = building; |
4626 | 4643 | ||
4627 | if ((SetPhantom && !UsePhysics) || ParentGroup.IsAttachment || PhysicsShapeType == (byte)PhysShapeType.none | 4644 | if ((SetPhantom && !UsePhysics && !SetVD) || ParentGroup.IsAttachment || PhysicsShapeType == (byte)PhysShapeType.none |
4628 | || (Shape.PathCurve == (byte)Extrusion.Flexible)) | 4645 | || (Shape.PathCurve == (byte)Extrusion.Flexible)) |
4629 | { | 4646 | { |
4630 | if (pa != null) | 4647 | if (pa != null) |
@@ -4669,12 +4686,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
4669 | else // it already has a physical representation | 4686 | else // it already has a physical representation |
4670 | { | 4687 | { |
4671 | DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. | 4688 | DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. |
4672 | 4689 | /* moved into DoPhysicsPropertyUpdate | |
4673 | if(VolumeDetectActive) | 4690 | if(VolumeDetectActive) |
4674 | pa.SetVolumeDetect(1); | 4691 | pa.SetVolumeDetect(1); |
4675 | else | 4692 | else |
4676 | pa.SetVolumeDetect(0); | 4693 | pa.SetVolumeDetect(0); |
4677 | 4694 | */ | |
4678 | if (pa.Building != building) | 4695 | if (pa.Building != building) |
4679 | pa.Building = building; | 4696 | pa.Building = building; |
4680 | } | 4697 | } |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 292dbdc..ac791ae 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -1076,6 +1076,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1076 | 1076 | ||
1077 | public void TeleportWithMomentum(Vector3 pos) | 1077 | public void TeleportWithMomentum(Vector3 pos) |
1078 | { | 1078 | { |
1079 | TeleportWithMomentum(pos, null); | ||
1080 | } | ||
1081 | |||
1082 | public void TeleportWithMomentum(Vector3 pos, Vector3? v) | ||
1083 | { | ||
1079 | bool isFlying = Flying; | 1084 | bool isFlying = Flying; |
1080 | Vector3 vel = Velocity; | 1085 | Vector3 vel = Velocity; |
1081 | RemoveFromPhysicalScene(); | 1086 | RemoveFromPhysicalScene(); |
@@ -1083,7 +1088,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
1083 | AbsolutePosition = pos; | 1088 | AbsolutePosition = pos; |
1084 | AddToPhysicalScene(isFlying); | 1089 | AddToPhysicalScene(isFlying); |
1085 | if (PhysicsActor != null) | 1090 | if (PhysicsActor != null) |
1086 | PhysicsActor.SetMomentum(vel); | 1091 | { |
1092 | if (v.HasValue) | ||
1093 | PhysicsActor.SetMomentum((Vector3)v); | ||
1094 | else | ||
1095 | PhysicsActor.SetMomentum(vel); | ||
1096 | } | ||
1087 | 1097 | ||
1088 | SendTerseUpdateToAllClients(); | 1098 | SendTerseUpdateToAllClients(); |
1089 | } | 1099 | } |
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 68f21c8..ebf5e84 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | |||
@@ -323,9 +323,15 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
323 | { | 323 | { |
324 | NPCAvatar av; | 324 | NPCAvatar av; |
325 | if (m_avatars.TryGetValue(npcID, out av)) | 325 | if (m_avatars.TryGetValue(npcID, out av)) |
326 | { | ||
327 | if (npcID == callerID) | ||
328 | return true; | ||
326 | return CheckPermissions(av, callerID); | 329 | return CheckPermissions(av, callerID); |
330 | } | ||
327 | else | 331 | else |
332 | { | ||
328 | return false; | 333 | return false; |
334 | } | ||
329 | } | 335 | } |
330 | } | 336 | } |
331 | 337 | ||
@@ -337,7 +343,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
337 | /// <returns>true if they do, false if they don't.</returns> | 343 | /// <returns>true if they do, false if they don't.</returns> |
338 | private bool CheckPermissions(NPCAvatar av, UUID callerID) | 344 | private bool CheckPermissions(NPCAvatar av, UUID callerID) |
339 | { | 345 | { |
340 | return callerID == UUID.Zero || av.OwnerID == UUID.Zero || av.OwnerID == callerID; | 346 | return callerID == UUID.Zero || av.OwnerID == UUID.Zero || av.OwnerID == callerID || av.AgentId == callerID; |
341 | } | 347 | } |
342 | } | 348 | } |
343 | } | 349 | } |
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs index 9c1b87b..ec4be58 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs | |||
@@ -683,7 +683,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
683 | PID_D *= m_mass / _parent_scene.ODE_STEPSIZE; | 683 | PID_D *= m_mass / _parent_scene.ODE_STEPSIZE; |
684 | PID_P /= 50 * 80; | 684 | PID_P /= 50 * 80; |
685 | PID_P *= m_mass / _parent_scene.ODE_STEPSIZE; | 685 | PID_P *= m_mass / _parent_scene.ODE_STEPSIZE; |
686 | 686 | ||
687 | Body = d.BodyCreate(_parent_scene.world); | 687 | Body = d.BodyCreate(_parent_scene.world); |
688 | 688 | ||
689 | d.BodySetAutoDisableFlag(Body, false); | 689 | d.BodySetAutoDisableFlag(Body, false); |
@@ -771,16 +771,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
771 | /// <param name="timeStep"></param> | 771 | /// <param name="timeStep"></param> |
772 | public void Move(float timeStep, List<OdeCharacter> defects) | 772 | public void Move(float timeStep, List<OdeCharacter> defects) |
773 | { | 773 | { |
774 | // no lock; for now it's only called from within Simulate() | ||
775 | |||
776 | // If the PID Controller isn't active then we set our force | ||
777 | // calculating base velocity to the current position | ||
778 | |||
779 | if (Body == IntPtr.Zero) | 774 | if (Body == IntPtr.Zero) |
780 | return; | 775 | return; |
781 | 776 | ||
782 | d.Vector3 dtmp; | 777 | d.Vector3 dtmp = d.BodyGetPosition(Body); |
783 | d.BodyCopyPosition(Body, out dtmp); | ||
784 | Vector3 localpos = new Vector3(dtmp.X, dtmp.Y, dtmp.Z); | 778 | Vector3 localpos = new Vector3(dtmp.X, dtmp.Y, dtmp.Z); |
785 | 779 | ||
786 | // the Amotor still lets avatar rotation to drift during colisions | 780 | // the Amotor still lets avatar rotation to drift during colisions |
@@ -797,22 +791,43 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
797 | { | 791 | { |
798 | _zeroPosition = localpos; | 792 | _zeroPosition = localpos; |
799 | } | 793 | } |
800 | //PidStatus = true; | ||
801 | |||
802 | 794 | ||
803 | if (!localpos.IsFinite()) | 795 | if (!localpos.IsFinite()) |
804 | { | 796 | { |
805 | |||
806 | m_log.Warn("[PHYSICS]: Avatar Position is non-finite!"); | 797 | m_log.Warn("[PHYSICS]: Avatar Position is non-finite!"); |
807 | defects.Add(this); | 798 | defects.Add(this); |
808 | // _parent_scene.RemoveCharacter(this); | 799 | // _parent_scene.RemoveCharacter(this); |
809 | 800 | ||
810 | // destroy avatar capsule and related ODE data | 801 | // destroy avatar capsule and related ODE data |
811 | AvatarGeomAndBodyDestroy(); | 802 | AvatarGeomAndBodyDestroy(); |
812 | |||
813 | return; | 803 | return; |
814 | } | 804 | } |
815 | 805 | ||
806 | // check outbounds forcing to be in world | ||
807 | bool fixbody = false; | ||
808 | if (localpos.X < 0.0f) | ||
809 | { | ||
810 | fixbody = true; | ||
811 | localpos.X = 0.1f; | ||
812 | } | ||
813 | else if (localpos.X > _parent_scene.WorldExtents.X - 0.1f) | ||
814 | { | ||
815 | fixbody = true; | ||
816 | localpos.X = _parent_scene.WorldExtents.X - 0.1f; | ||
817 | } | ||
818 | if (localpos.Y < 0.0f) | ||
819 | { | ||
820 | fixbody = true; | ||
821 | localpos.Y = 0.1f; | ||
822 | } | ||
823 | else if (localpos.Y > _parent_scene.WorldExtents.Y - 0.1) | ||
824 | { | ||
825 | fixbody = true; | ||
826 | localpos.Y = _parent_scene.WorldExtents.Y - 0.1f; | ||
827 | } | ||
828 | if (fixbody) | ||
829 | d.BodySetPosition(Body, localpos.X, localpos.Y, localpos.Z); | ||
830 | |||
816 | Vector3 vec = Vector3.Zero; | 831 | Vector3 vec = Vector3.Zero; |
817 | dtmp = d.BodyGetLinearVel(Body); | 832 | dtmp = d.BodyGetLinearVel(Body); |
818 | Vector3 vel = new Vector3(dtmp.X, dtmp.Y, dtmp.Z); | 833 | Vector3 vel = new Vector3(dtmp.X, dtmp.Y, dtmp.Z); |
@@ -820,16 +835,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
820 | float movementdivisor = 1f; | 835 | float movementdivisor = 1f; |
821 | //Ubit change divisions into multiplications below | 836 | //Ubit change divisions into multiplications below |
822 | if (!m_alwaysRun) | 837 | if (!m_alwaysRun) |
823 | { | ||
824 | movementdivisor = 1 / walkDivisor; | 838 | movementdivisor = 1 / walkDivisor; |
825 | } | ||
826 | else | 839 | else |
827 | { | ||
828 | movementdivisor = 1 / runDivisor; | 840 | movementdivisor = 1 / runDivisor; |
829 | } | ||
830 | 841 | ||
842 | //****************************************** | ||
831 | // colide with land | 843 | // colide with land |
832 | |||
833 | d.AABB aabb; | 844 | d.AABB aabb; |
834 | d.GeomGetAABB(Shell, out aabb); | 845 | d.GeomGetAABB(Shell, out aabb); |
835 | float chrminZ = aabb.MinZ; | 846 | float chrminZ = aabb.MinZ; |
@@ -851,32 +862,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
851 | float depth = terrainheight - chrminZ; | 862 | float depth = terrainheight - chrminZ; |
852 | if (!flying) | 863 | if (!flying) |
853 | { | 864 | { |
854 | vec.Z = -vel.Z * PID_D * 1.5f + depth * PID_P * 50; | 865 | vec.Z = -vel.Z * PID_D * 1.5f + depth * PID_P * 60; |
855 | } | 866 | } |
856 | else | 867 | else |
857 | vec.Z = depth * PID_P * 50; | 868 | vec.Z = depth * PID_P * 60; |
858 | |||
859 | /* | ||
860 | Vector3 vtmp; | ||
861 | vtmp.X = _target_velocity.X * timeStep; | ||
862 | vtmp.Y = _target_velocity.Y * timeStep; | ||
863 | // fake and avoid squares | ||
864 | float k = (Math.Abs(vtmp.X) + Math.Abs(vtmp.Y)); | ||
865 | if (k > 0) | ||
866 | { | ||
867 | posch.X += vtmp.X; | ||
868 | posch.Y += vtmp.Y; | ||
869 | terrainheight -= _parent_scene.GetTerrainHeightAtXY(posch.X, posch.Y); | ||
870 | k = 1 + Math.Abs(terrainheight) / k; | ||
871 | movementdivisor /= k; | ||
872 | |||
873 | if (k < 1) | ||
874 | k = 1; | ||
875 | } | ||
876 | */ | ||
877 | 869 | ||
878 | 870 | if (depth < 0.2f) | |
879 | if (depth < 0.1f) | ||
880 | { | 871 | { |
881 | m_iscolliding = true; | 872 | m_iscolliding = true; |
882 | m_colliderfilter = 2; | 873 | m_colliderfilter = 2; |
@@ -901,6 +892,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
901 | else | 892 | else |
902 | m_iscollidingGround = false; | 893 | m_iscollidingGround = false; |
903 | 894 | ||
895 | //****************************************** | ||
904 | 896 | ||
905 | // if velocity is zero, use position control; otherwise, velocity control | 897 | // if velocity is zero, use position control; otherwise, velocity control |
906 | if (_target_velocity.X == 0.0f && _target_velocity.Y == 0.0f && _target_velocity.Z == 0.0f | 898 | if (_target_velocity.X == 0.0f && _target_velocity.Y == 0.0f && _target_velocity.Z == 0.0f |
@@ -1012,97 +1004,31 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1012 | // _parent_scene.RemoveCharacter(this); | 1004 | // _parent_scene.RemoveCharacter(this); |
1013 | // destroy avatar capsule and related ODE data | 1005 | // destroy avatar capsule and related ODE data |
1014 | AvatarGeomAndBodyDestroy(); | 1006 | AvatarGeomAndBodyDestroy(); |
1007 | return; | ||
1015 | } | 1008 | } |
1009 | |||
1010 | // update our local ideia of position velocity and aceleration | ||
1011 | _position = localpos; | ||
1012 | _acceleration = _velocity; // previus velocity | ||
1013 | _velocity = vel; | ||
1014 | _acceleration = (vel - _acceleration) / timeStep; | ||
1015 | |||
1016 | } | 1016 | } |
1017 | 1017 | ||
1018 | /// <summary> | 1018 | /// <summary> |
1019 | /// Updates the reported position and velocity. This essentially sends the data up to ScenePresence. | 1019 | /// Updates the reported position and velocity. |
1020 | /// Used to copy variables from unmanaged space at heartbeat rate and also trigger scene updates acording | ||
1021 | /// also outbounds checking | ||
1022 | /// copy and outbounds now done in move(..) at ode rate | ||
1023 | /// | ||
1020 | /// </summary> | 1024 | /// </summary> |
1021 | public void UpdatePositionAndVelocity() | 1025 | public void UpdatePositionAndVelocity() |
1022 | { | 1026 | { |
1023 | // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! | 1027 | return; |
1024 | if (Body == IntPtr.Zero) | ||
1025 | return; | ||
1026 | |||
1027 | d.Vector3 vec; | ||
1028 | try | ||
1029 | { | ||
1030 | d.BodyCopyPosition(Body, out vec); | ||
1031 | } | ||
1032 | catch (NullReferenceException) | ||
1033 | { | ||
1034 | bad = true; | ||
1035 | _parent_scene.BadCharacter(this); | ||
1036 | vec = new d.Vector3(_position.X, _position.Y, _position.Z); | ||
1037 | base.RaiseOutOfBounds(_position); // Tells ScenePresence that there's a problem! | ||
1038 | m_log.WarnFormat("[ODEPLUGIN]: Avatar Null reference for Avatar {0}, physical actor {1}", m_name, m_uuid); | ||
1039 | } | ||
1040 | |||
1041 | _position.X = vec.X; | ||
1042 | _position.Y = vec.Y; | ||
1043 | _position.Z = vec.Z; | ||
1044 | 1028 | ||
1045 | bool fixbody = false; | 1029 | // if (Body == IntPtr.Zero) |
1046 | 1030 | // return; | |
1047 | if (_position.X < 0.0f) | ||
1048 | { | ||
1049 | fixbody = true; | ||
1050 | _position.X = 0.1f; | ||
1051 | } | ||
1052 | else if (_position.X > (int)_parent_scene.WorldExtents.X - 0.1f) | ||
1053 | { | ||
1054 | fixbody = true; | ||
1055 | _position.X = (int)_parent_scene.WorldExtents.X - 0.1f; | ||
1056 | } | ||
1057 | 1031 | ||
1058 | if (_position.Y < 0.0f) | ||
1059 | { | ||
1060 | fixbody = true; | ||
1061 | _position.Y = 0.1f; | ||
1062 | } | ||
1063 | else if (_position.Y > (int)_parent_scene.WorldExtents.Y - 0.1) | ||
1064 | { | ||
1065 | fixbody = true; | ||
1066 | _position.Y = (int)_parent_scene.WorldExtents.Y - 0.1f; | ||
1067 | } | ||
1068 | |||
1069 | if (fixbody) | ||
1070 | d.BodySetPosition(Body, _position.X, _position.Y, _position.Z); | ||
1071 | |||
1072 | // Did we move last? = zeroflag | ||
1073 | // This helps keep us from sliding all over | ||
1074 | /* | ||
1075 | if (_zeroFlag) | ||
1076 | { | ||
1077 | _velocity.X = 0.0f; | ||
1078 | _velocity.Y = 0.0f; | ||
1079 | _velocity.Z = 0.0f; | ||
1080 | |||
1081 | // Did we send out the 'stopped' message? | ||
1082 | if (!m_lastUpdateSent) | ||
1083 | { | ||
1084 | m_lastUpdateSent = true; | ||
1085 | base.RequestPhysicsterseUpdate(); | ||
1086 | } | ||
1087 | } | ||
1088 | else | ||
1089 | { | ||
1090 | m_lastUpdateSent = false; | ||
1091 | */ | ||
1092 | try | ||
1093 | { | ||
1094 | vec = d.BodyGetLinearVel(Body); | ||
1095 | } | ||
1096 | catch (NullReferenceException) | ||
1097 | { | ||
1098 | vec.X = _velocity.X; | ||
1099 | vec.Y = _velocity.Y; | ||
1100 | vec.Z = _velocity.Z; | ||
1101 | } | ||
1102 | _velocity.X = (vec.X); | ||
1103 | _velocity.Y = (vec.Y); | ||
1104 | _velocity.Z = (vec.Z); | ||
1105 | // } | ||
1106 | } | 1032 | } |
1107 | 1033 | ||
1108 | /// <summary> | 1034 | /// <summary> |
@@ -1245,7 +1171,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1245 | CAPSULE_LENGTH = caplen; | 1171 | CAPSULE_LENGTH = caplen; |
1246 | 1172 | ||
1247 | AvatarGeomAndBodyCreation(_position.X, _position.Y, | 1173 | AvatarGeomAndBodyCreation(_position.X, _position.Y, |
1248 | _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2)); | 1174 | _position.Z + (CAPSULE_LENGTH - prevCapsule) * 0.5f); |
1249 | 1175 | ||
1250 | Velocity = Vector3.Zero; | 1176 | Velocity = Vector3.Zero; |
1251 | 1177 | ||
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs index 32c4722..5467b9f 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs | |||
@@ -3228,17 +3228,13 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3228 | { | 3228 | { |
3229 | if (!childPrim && m_isphysical && Body != IntPtr.Zero && | 3229 | if (!childPrim && m_isphysical && Body != IntPtr.Zero && |
3230 | !m_disabled && !m_isSelected && !m_building && !m_outbounds) | 3230 | !m_disabled && !m_isSelected && !m_building && !m_outbounds) |
3231 | // !m_disabled && !m_isSelected && !m_building && !m_outbounds) | ||
3232 | { | 3231 | { |
3233 | // if (!d.BodyIsEnabled(Body)) d.BodyEnable(Body); // KF add 161009 | ||
3234 | |||
3235 | if (d.BodyIsEnabled(Body)) | 3232 | if (d.BodyIsEnabled(Body)) |
3236 | { | 3233 | { |
3237 | float timestep = _parent_scene.ODE_STEPSIZE; | 3234 | float timestep = _parent_scene.ODE_STEPSIZE; |
3238 | 3235 | ||
3239 | // check outside region | 3236 | // check outside region |
3240 | d.Vector3 lpos; | 3237 | d.Vector3 lpos = d.GeomGetPosition(prim_geom); // root position that is seem by rest of simulator |
3241 | d.GeomCopyPosition(prim_geom, out lpos); // root position that is seem by rest of simulator | ||
3242 | 3238 | ||
3243 | if (lpos.Z < -100 || lpos.Z > 100000f) | 3239 | if (lpos.Z < -100 || lpos.Z > 100000f) |
3244 | { | 3240 | { |
@@ -3321,12 +3317,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3321 | { | 3317 | { |
3322 | // 'VEHICLES' are dealt with in ODEDynamics.cs | 3318 | // 'VEHICLES' are dealt with in ODEDynamics.cs |
3323 | m_vehicle.Step(); | 3319 | m_vehicle.Step(); |
3324 | return; | ||
3325 | } | 3320 | } |
3326 | |||
3327 | else | 3321 | else |
3328 | { | 3322 | { |
3329 | |||
3330 | float fx = 0; | 3323 | float fx = 0; |
3331 | float fy = 0; | 3324 | float fy = 0; |
3332 | float fz = 0; | 3325 | float fz = 0; |
@@ -3512,10 +3505,39 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3512 | { | 3505 | { |
3513 | d.BodyAddTorque(Body, trq.X, trq.Y, trq.Z); | 3506 | d.BodyAddTorque(Body, trq.X, trq.Y, trq.Z); |
3514 | } | 3507 | } |
3515 | |||
3516 | } | 3508 | } |
3509 | |||
3510 | // update our ideia of velocities and acelerations | ||
3511 | d.Quaternion ori; | ||
3512 | d.Vector3 dtmpu; | ||
3513 | |||
3514 | _position.X = lpos.X; | ||
3515 | _position.Y = lpos.Y; | ||
3516 | _position.Z = lpos.Z; | ||
3517 | |||
3518 | d.GeomCopyQuaternion(prim_geom, out ori); | ||
3519 | _orientation.X = ori.X; | ||
3520 | _orientation.Y = ori.Y; | ||
3521 | _orientation.Z = ori.Z; | ||
3522 | _orientation.W = ori.W; | ||
3523 | |||
3524 | _acceleration = _velocity; | ||
3525 | |||
3526 | dtmpu = d.BodyGetLinearVel(Body); | ||
3527 | _velocity.X = dtmpu.X; | ||
3528 | _velocity.Y = dtmpu.Y; | ||
3529 | _velocity.Z = dtmpu.Z; | ||
3530 | |||
3531 | float invts = 1 / timestep; | ||
3532 | _acceleration = (_velocity - _acceleration) * invts; | ||
3533 | |||
3534 | dtmpu = d.BodyGetAngularVel(Body); | ||
3535 | m_rotationalVelocity.X = dtmpu.X; | ||
3536 | m_rotationalVelocity.Y = dtmpu.Y; | ||
3537 | m_rotationalVelocity.Z = dtmpu.Z; | ||
3517 | } | 3538 | } |
3518 | else // body disabled | 3539 | |
3540 | else // body disabled/sleeping | ||
3519 | { | 3541 | { |
3520 | // let vehicles sleep | 3542 | // let vehicles sleep |
3521 | if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) | 3543 | if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) |
@@ -3546,36 +3568,23 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3546 | { | 3568 | { |
3547 | if (Body != IntPtr.Zero) | 3569 | if (Body != IntPtr.Zero) |
3548 | { | 3570 | { |
3549 | Vector3 pv = Vector3.Zero; | ||
3550 | bool lastZeroFlag = _zeroFlag; | 3571 | bool lastZeroFlag = _zeroFlag; |
3551 | 3572 | ||
3552 | d.Vector3 lpos; | 3573 | if ((Math.Abs(m_lastposition.X - _position.X) < 0.01) |
3553 | d.GeomCopyPosition(prim_geom, out lpos); // root position that is seem by rest of simulator | 3574 | && (Math.Abs(m_lastposition.Y - _position.Y) < 0.01) |
3554 | 3575 | && (Math.Abs(m_lastposition.Z - _position.Z) < 0.01) | |
3555 | 3576 | && (Math.Abs(m_lastorientation.X - _orientation.X) < 0.0001) | |
3556 | d.Quaternion ori; | 3577 | && (Math.Abs(m_lastorientation.Y - _orientation.Y) < 0.0001) |
3557 | d.GeomCopyQuaternion(prim_geom, out ori); | 3578 | && (Math.Abs(m_lastorientation.Z - _orientation.Z) < 0.0001) |
3558 | d.Vector3 vel = d.BodyGetLinearVel(Body); | ||
3559 | d.Vector3 rotvel = d.BodyGetAngularVel(Body); | ||
3560 | |||
3561 | if ((Math.Abs(m_lastposition.X - lpos.X) < 0.01) | ||
3562 | && (Math.Abs(m_lastposition.Y - lpos.Y) < 0.01) | ||
3563 | && (Math.Abs(m_lastposition.Z - lpos.Z) < 0.01) | ||
3564 | && (Math.Abs(m_lastorientation.X - ori.X) < 0.0001) | ||
3565 | && (Math.Abs(m_lastorientation.Y - ori.Y) < 0.0001) | ||
3566 | && (Math.Abs(m_lastorientation.Z - ori.Z) < 0.0001) | ||
3567 | ) | 3579 | ) |
3568 | { | 3580 | { |
3569 | _zeroFlag = true; | 3581 | _zeroFlag = true; |
3570 | //Console.WriteLine("ZFT 2"); | ||
3571 | m_throttleUpdates = false; | 3582 | m_throttleUpdates = false; |
3572 | } | 3583 | } |
3573 | else | 3584 | else |
3574 | { | 3585 | { |
3575 | //m_log.Debug(Math.Abs(m_lastposition.X - l_position.X).ToString()); | ||
3576 | _zeroFlag = false; | 3586 | _zeroFlag = false; |
3577 | m_lastUpdateSent = false; | 3587 | m_lastUpdateSent = false; |
3578 | //m_throttleUpdates = false; | ||
3579 | } | 3588 | } |
3580 | 3589 | ||
3581 | if (_zeroFlag) | 3590 | if (_zeroFlag) |
@@ -3583,22 +3592,14 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3583 | m_lastposition = _position; | 3592 | m_lastposition = _position; |
3584 | m_lastorientation = _orientation; | 3593 | m_lastorientation = _orientation; |
3585 | 3594 | ||
3586 | _velocity.X = 0.0f; | 3595 | _velocity = Vector3.Zero; |
3587 | _velocity.Y = 0.0f; | 3596 | _acceleration = Vector3.Zero; |
3588 | _velocity.Z = 0.0f; | 3597 | m_rotationalVelocity = Vector3.Zero; |
3589 | 3598 | ||
3590 | _acceleration.X = 0; | ||
3591 | _acceleration.Y = 0; | ||
3592 | _acceleration.Z = 0; | ||
3593 | |||
3594 | m_rotationalVelocity.X = 0; | ||
3595 | m_rotationalVelocity.Y = 0; | ||
3596 | m_rotationalVelocity.Z = 0; | ||
3597 | if (!m_lastUpdateSent) | 3599 | if (!m_lastUpdateSent) |
3598 | { | 3600 | { |
3599 | m_throttleUpdates = false; | 3601 | m_throttleUpdates = false; |
3600 | throttleCounter = 0; | 3602 | throttleCounter = 0; |
3601 | m_rotationalVelocity = pv; | ||
3602 | 3603 | ||
3603 | base.RequestPhysicsterseUpdate(); | 3604 | base.RequestPhysicsterseUpdate(); |
3604 | 3605 | ||
@@ -3612,39 +3613,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3612 | base.RequestPhysicsterseUpdate(); | 3613 | base.RequestPhysicsterseUpdate(); |
3613 | } | 3614 | } |
3614 | 3615 | ||
3615 | m_lastVelocity = _velocity; | ||
3616 | |||
3617 | _position.X = lpos.X; | ||
3618 | _position.Y = lpos.Y; | ||
3619 | _position.Z = lpos.Z; | ||
3620 | |||
3621 | _velocity.X = vel.X; | ||
3622 | _velocity.Y = vel.Y; | ||
3623 | _velocity.Z = vel.Z; | ||
3624 | |||
3625 | _orientation.X = ori.X; | ||
3626 | _orientation.Y = ori.Y; | ||
3627 | _orientation.Z = ori.Z; | ||
3628 | _orientation.W = ori.W; | ||
3629 | |||
3630 | _acceleration = ((_velocity - m_lastVelocity) / simulatedtime); | ||
3631 | |||
3632 | if (m_rotationalVelocity.ApproxEquals(pv, 0.0001f)) | ||
3633 | { | ||
3634 | m_rotationalVelocity = pv; | ||
3635 | } | ||
3636 | else | ||
3637 | { | ||
3638 | m_rotationalVelocity.X = rotvel.X; | ||
3639 | m_rotationalVelocity.Y = rotvel.Y; | ||
3640 | m_rotationalVelocity.Z = rotvel.Z; | ||
3641 | } | ||
3642 | |||
3643 | m_lastUpdateSent = false; | 3616 | m_lastUpdateSent = false; |
3644 | if (!m_throttleUpdates || throttleCounter > _parent_scene.geomUpdatesPerThrottledUpdate) | 3617 | if (!m_throttleUpdates || throttleCounter > _parent_scene.geomUpdatesPerThrottledUpdate) |
3645 | { | 3618 | { |
3646 | m_lastposition = _position; | 3619 | m_lastposition = _position; |
3647 | m_lastorientation = _orientation; | 3620 | m_lastorientation = _orientation; |
3621 | m_lastVelocity = _velocity; | ||
3648 | base.RequestPhysicsterseUpdate(); | 3622 | base.RequestPhysicsterseUpdate(); |
3649 | } | 3623 | } |
3650 | else | 3624 | else |
@@ -3656,17 +3630,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3656 | else if (!m_lastUpdateSent || !_zeroFlag) | 3630 | else if (!m_lastUpdateSent || !_zeroFlag) |
3657 | { | 3631 | { |
3658 | // Not a body.. so Make sure the client isn't interpolating | 3632 | // Not a body.. so Make sure the client isn't interpolating |
3659 | _velocity.X = 0; | 3633 | _velocity = Vector3.Zero; |
3660 | _velocity.Y = 0; | 3634 | _acceleration = Vector3.Zero; |
3661 | _velocity.Z = 0; | 3635 | m_rotationalVelocity = Vector3.Zero; |
3662 | 3636 | m_lastVelocity = Vector3.Zero; | |
3663 | _acceleration.X = 0; | ||
3664 | _acceleration.Y = 0; | ||
3665 | _acceleration.Z = 0; | ||
3666 | 3637 | ||
3667 | m_rotationalVelocity.X = 0; | ||
3668 | m_rotationalVelocity.Y = 0; | ||
3669 | m_rotationalVelocity.Z = 0; | ||
3670 | _zeroFlag = true; | 3638 | _zeroFlag = true; |
3671 | 3639 | ||
3672 | if (!m_lastUpdateSent) | 3640 | if (!m_lastUpdateSent) |
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index 7632e25..9ca2d3f 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | |||
@@ -455,15 +455,15 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
455 | 455 | ||
456 | geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", geomDefaultDensity); | 456 | geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", geomDefaultDensity); |
457 | bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", bodyFramesAutoDisable); | 457 | bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", bodyFramesAutoDisable); |
458 | 458 | /* | |
459 | bodyPIDD = physicsconfig.GetFloat("body_pid_derivative", bodyPIDD); | 459 | bodyPIDD = physicsconfig.GetFloat("body_pid_derivative", bodyPIDD); |
460 | bodyPIDG = physicsconfig.GetFloat("body_pid_gain", bodyPIDG); | 460 | bodyPIDG = physicsconfig.GetFloat("body_pid_gain", bodyPIDG); |
461 | 461 | */ | |
462 | forceSimplePrimMeshing = physicsconfig.GetBoolean("force_simple_prim_meshing", forceSimplePrimMeshing); | 462 | forceSimplePrimMeshing = physicsconfig.GetBoolean("force_simple_prim_meshing", forceSimplePrimMeshing); |
463 | meshSculptedPrim = physicsconfig.GetBoolean("mesh_sculpted_prim", meshSculptedPrim); | 463 | meshSculptedPrim = physicsconfig.GetBoolean("mesh_sculpted_prim", meshSculptedPrim); |
464 | meshSculptLOD = physicsconfig.GetFloat("mesh_lod", meshSculptLOD); | 464 | meshSculptLOD = physicsconfig.GetFloat("mesh_lod", meshSculptLOD); |
465 | MeshSculptphysicalLOD = physicsconfig.GetFloat("mesh_physical_lod", MeshSculptphysicalLOD); | 465 | MeshSculptphysicalLOD = physicsconfig.GetFloat("mesh_physical_lod", MeshSculptphysicalLOD); |
466 | 466 | /* | |
467 | if (Environment.OSVersion.Platform == PlatformID.Unix) | 467 | if (Environment.OSVersion.Platform == PlatformID.Unix) |
468 | { | 468 | { |
469 | avPIDD = physicsconfig.GetFloat("av_pid_derivative_linux", avPIDD); | 469 | avPIDD = physicsconfig.GetFloat("av_pid_derivative_linux", avPIDD); |
@@ -471,10 +471,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
471 | } | 471 | } |
472 | else | 472 | else |
473 | { | 473 | { |
474 | |||
474 | avPIDD = physicsconfig.GetFloat("av_pid_derivative_win", avPIDD); | 475 | avPIDD = physicsconfig.GetFloat("av_pid_derivative_win", avPIDD); |
475 | avPIDP = physicsconfig.GetFloat("av_pid_proportional_win", avPIDP); | 476 | avPIDP = physicsconfig.GetFloat("av_pid_proportional_win", avPIDP); |
476 | } | 477 | } |
477 | 478 | */ | |
478 | physics_logging = physicsconfig.GetBoolean("physics_logging", false); | 479 | physics_logging = physicsconfig.GetBoolean("physics_logging", false); |
479 | physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0); | 480 | physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0); |
480 | physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false); | 481 | physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false); |
@@ -1860,6 +1861,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1860 | 1861 | ||
1861 | statstart = Util.EnvironmentTickCount(); | 1862 | statstart = Util.EnvironmentTickCount(); |
1862 | 1863 | ||
1864 | /* | ||
1865 | // now included in characters move() and done at ode rate | ||
1866 | // maybe be needed later if we need to do any extra work at hearbeat rate | ||
1863 | lock (_characters) | 1867 | lock (_characters) |
1864 | { | 1868 | { |
1865 | foreach (OdeCharacter actor in _characters) | 1869 | foreach (OdeCharacter actor in _characters) |
@@ -1873,7 +1877,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1873 | } | 1877 | } |
1874 | } | 1878 | } |
1875 | } | 1879 | } |
1876 | 1880 | */ | |
1877 | lock (_badCharacter) | 1881 | lock (_badCharacter) |
1878 | { | 1882 | { |
1879 | if (_badCharacter.Count > 0) | 1883 | if (_badCharacter.Count > 0) |