diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPart.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 196 |
1 files changed, 149 insertions, 47 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 8979659..1cfa8ed 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -198,7 +198,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
198 | 198 | ||
199 | public bool RETURN_AT_EDGE; | 199 | public bool RETURN_AT_EDGE; |
200 | 200 | ||
201 | public bool BlockGrab; | 201 | public bool BlockGrab { get; set; } |
202 | 202 | ||
203 | public bool StatusSandbox; | 203 | public bool StatusSandbox; |
204 | 204 | ||
@@ -286,7 +286,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
286 | 286 | ||
287 | public Quaternion SpinOldOrientation = Quaternion.Identity; | 287 | public Quaternion SpinOldOrientation = Quaternion.Identity; |
288 | 288 | ||
289 | protected int m_APIDIterations = 0; | 289 | protected bool m_APIDActive = false; |
290 | protected Quaternion m_APIDTarget = Quaternion.Identity; | 290 | protected Quaternion m_APIDTarget = Quaternion.Identity; |
291 | protected float m_APIDDamp = 0; | 291 | protected float m_APIDDamp = 0; |
292 | protected float m_APIDStrength = 0; | 292 | protected float m_APIDStrength = 0; |
@@ -680,6 +680,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
680 | } | 680 | } |
681 | } | 681 | } |
682 | 682 | ||
683 | protected bool APIDActive | ||
684 | { | ||
685 | get { return m_APIDActive; } | ||
686 | set { m_APIDActive = value; } | ||
687 | } | ||
688 | |||
683 | protected Quaternion APIDTarget | 689 | protected Quaternion APIDTarget |
684 | { | 690 | { |
685 | get { return m_APIDTarget; } | 691 | get { return m_APIDTarget; } |
@@ -1001,14 +1007,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
1001 | 1007 | ||
1002 | set | 1008 | set |
1003 | { | 1009 | { |
1004 | m_velocity = value; | 1010 | if (Util.IsNanOrInfinity(value)) |
1011 | m_velocity = Vector3.Zero; | ||
1012 | else | ||
1013 | m_velocity = value; | ||
1005 | 1014 | ||
1006 | PhysicsActor actor = PhysActor; | 1015 | PhysicsActor actor = PhysActor; |
1007 | if (actor != null) | 1016 | if (actor != null) |
1008 | { | 1017 | { |
1009 | if (actor.IsPhysical) | 1018 | if (actor.IsPhysical) |
1010 | { | 1019 | { |
1011 | actor.Velocity = value; | 1020 | actor.Velocity = m_velocity; |
1012 | ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); | 1021 | ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); |
1013 | } | 1022 | } |
1014 | } | 1023 | } |
@@ -1037,18 +1046,39 @@ namespace OpenSim.Region.Framework.Scenes | |||
1037 | } | 1046 | } |
1038 | set | 1047 | set |
1039 | { | 1048 | { |
1049 | <<<<<<< HEAD | ||
1050 | if (Util.IsNanOrInfinity(value)) | ||
1051 | m_angularVelocity = Vector3.Zero; | ||
1052 | else | ||
1053 | m_angularVelocity = value; | ||
1054 | |||
1055 | PhysicsActor actor = PhysActor; | ||
1056 | if ((actor != null) && actor.IsPhysical) | ||
1057 | actor.RotationalVelocity = m_angularVelocity; | ||
1058 | ======= | ||
1040 | m_angularVelocity = value; | 1059 | m_angularVelocity = value; |
1041 | PhysicsActor actor = PhysActor; | 1060 | PhysicsActor actor = PhysActor; |
1042 | if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this && VehicleType == (int)Vehicle.TYPE_NONE) | 1061 | if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this && VehicleType == (int)Vehicle.TYPE_NONE) |
1043 | { | 1062 | { |
1044 | actor.RotationalVelocity = m_angularVelocity; | 1063 | actor.RotationalVelocity = m_angularVelocity; |
1045 | } | 1064 | } |
1065 | >>>>>>> avn/ubitvar | ||
1046 | } | 1066 | } |
1047 | } | 1067 | } |
1048 | 1068 | ||
1049 | /// <summary></summary> | 1069 | /// <summary></summary> |
1050 | public Vector3 Acceleration | 1070 | public Vector3 Acceleration |
1051 | { | 1071 | { |
1072 | <<<<<<< HEAD | ||
1073 | get { return m_acceleration; } | ||
1074 | set | ||
1075 | { | ||
1076 | if (Util.IsNanOrInfinity(value)) | ||
1077 | m_acceleration = Vector3.Zero; | ||
1078 | else | ||
1079 | m_acceleration = value; | ||
1080 | } | ||
1081 | ======= | ||
1052 | get | 1082 | get |
1053 | { | 1083 | { |
1054 | PhysicsActor actor = PhysActor; | 1084 | PhysicsActor actor = PhysActor; |
@@ -1060,6 +1090,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1060 | } | 1090 | } |
1061 | 1091 | ||
1062 | set { m_acceleration = value; } | 1092 | set { m_acceleration = value; } |
1093 | >>>>>>> avn/ubitvar | ||
1063 | } | 1094 | } |
1064 | 1095 | ||
1065 | public string Description { get; set; } | 1096 | public string Description { get; set; } |
@@ -1400,7 +1431,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1400 | /// <value> | 1431 | /// <value> |
1401 | /// null if there are no sitting avatars. This is to save us create a hashset for every prim in a scene. | 1432 | /// null if there are no sitting avatars. This is to save us create a hashset for every prim in a scene. |
1402 | /// </value> | 1433 | /// </value> |
1403 | private HashSet<UUID> m_sittingAvatars; | 1434 | private HashSet<ScenePresence> m_sittingAvatars; |
1404 | 1435 | ||
1405 | public virtual UUID RegionID | 1436 | public virtual UUID RegionID |
1406 | { | 1437 | { |
@@ -1901,11 +1932,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
1901 | 1932 | ||
1902 | public void AddTextureAnimation(Primitive.TextureAnimation pTexAnim) | 1933 | public void AddTextureAnimation(Primitive.TextureAnimation pTexAnim) |
1903 | { | 1934 | { |
1935 | <<<<<<< HEAD | ||
1936 | byte[] data; | ||
1937 | |||
1938 | if (pTexAnim.Flags == Primitive.TextureAnimMode.ANIM_OFF) | ||
1939 | { | ||
1940 | data = Utils.EmptyBytes; | ||
1941 | } | ||
1942 | else | ||
1943 | { | ||
1944 | data = new byte[16]; | ||
1945 | int pos = 0; | ||
1946 | |||
1947 | ======= | ||
1904 | if (((int)pTexAnim.Flags & 1) != 0) // ANIM_ON | 1948 | if (((int)pTexAnim.Flags & 1) != 0) // ANIM_ON |
1905 | { | 1949 | { |
1906 | byte[] data = new byte[16]; | 1950 | byte[] data = new byte[16]; |
1907 | int pos = 0; | 1951 | int pos = 0; |
1908 | 1952 | ||
1953 | >>>>>>> avn/ubitvar | ||
1909 | // The flags don't like conversion from uint to byte, so we have to do | 1954 | // The flags don't like conversion from uint to byte, so we have to do |
1910 | // it the crappy way. See the above function :( | 1955 | // it the crappy way. See the above function :( |
1911 | 1956 | ||
@@ -1917,6 +1962,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
1917 | Utils.FloatToBytes(pTexAnim.Start).CopyTo(data, pos); | 1962 | Utils.FloatToBytes(pTexAnim.Start).CopyTo(data, pos); |
1918 | Utils.FloatToBytes(pTexAnim.Length).CopyTo(data, pos + 4); | 1963 | Utils.FloatToBytes(pTexAnim.Length).CopyTo(data, pos + 4); |
1919 | Utils.FloatToBytes(pTexAnim.Rate).CopyTo(data, pos + 8); | 1964 | Utils.FloatToBytes(pTexAnim.Rate).CopyTo(data, pos + 8); |
1965 | <<<<<<< HEAD | ||
1966 | } | ||
1967 | ======= | ||
1968 | >>>>>>> avn/ubitvar | ||
1920 | 1969 | ||
1921 | m_TextureAnimation = data; | 1970 | m_TextureAnimation = data; |
1922 | } | 1971 | } |
@@ -2134,7 +2183,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
2134 | /// <returns></returns> | 2183 | /// <returns></returns> |
2135 | public SceneObjectPart Copy(uint plocalID, UUID AgentID, UUID GroupID, int linkNum, bool userExposed) | 2184 | public SceneObjectPart Copy(uint plocalID, UUID AgentID, UUID GroupID, int linkNum, bool userExposed) |
2136 | { | 2185 | { |
2186 | // FIXME: This is dangerous since it's easy to forget to reset some references when necessary and end up | ||
2187 | // with bugs that only occur in some circumstances (e.g. crossing between regions on the same simulator | ||
2188 | // but not between regions on different simulators). Really, all copying should be done explicitly. | ||
2137 | SceneObjectPart dupe = (SceneObjectPart)MemberwiseClone(); | 2189 | SceneObjectPart dupe = (SceneObjectPart)MemberwiseClone(); |
2190 | |||
2138 | dupe.m_shape = m_shape.Copy(); | 2191 | dupe.m_shape = m_shape.Copy(); |
2139 | dupe.m_regionHandle = m_regionHandle; | 2192 | dupe.m_regionHandle = m_regionHandle; |
2140 | if (userExposed) | 2193 | if (userExposed) |
@@ -2187,6 +2240,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2187 | Array.Copy(Shape.ExtraParams, extraP, extraP.Length); | 2240 | Array.Copy(Shape.ExtraParams, extraP, extraP.Length); |
2188 | dupe.Shape.ExtraParams = extraP; | 2241 | dupe.Shape.ExtraParams = extraP; |
2189 | 2242 | ||
2243 | dupe.m_sittingAvatars = new HashSet<ScenePresence>(); | ||
2244 | |||
2190 | // safeguard actual copy is done in sog.copy | 2245 | // safeguard actual copy is done in sog.copy |
2191 | dupe.KeyframeMotion = null; | 2246 | dupe.KeyframeMotion = null; |
2192 | dupe.PayPrice = (int[])PayPrice.Clone(); | 2247 | dupe.PayPrice = (int[])PayPrice.Clone(); |
@@ -2436,7 +2491,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2436 | /// </summary> | 2491 | /// </summary> |
2437 | /// <param name="xmlReader"></param> | 2492 | /// <param name="xmlReader"></param> |
2438 | /// <returns></returns> | 2493 | /// <returns></returns> |
2439 | public static SceneObjectPart FromXml(XmlTextReader xmlReader) | 2494 | public static SceneObjectPart FromXml(XmlReader xmlReader) |
2440 | { | 2495 | { |
2441 | SceneObjectPart part = SceneObjectSerializer.Xml2ToSOP(xmlReader); | 2496 | SceneObjectPart part = SceneObjectSerializer.Xml2ToSOP(xmlReader); |
2442 | 2497 | ||
@@ -2471,22 +2526,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2471 | ParentGroup.RootPart.RETURN_AT_EDGE = p; | 2526 | ParentGroup.RootPart.RETURN_AT_EDGE = p; |
2472 | } | 2527 | } |
2473 | 2528 | ||
2474 | public bool GetBlockGrab() | ||
2475 | { | ||
2476 | if (ParentGroup.IsDeleted) | ||
2477 | return false; | ||
2478 | |||
2479 | return ParentGroup.RootPart.BlockGrab; | ||
2480 | } | ||
2481 | |||
2482 | public void SetBlockGrab(bool p) | ||
2483 | { | ||
2484 | if (ParentGroup.IsDeleted) | ||
2485 | return; | ||
2486 | |||
2487 | ParentGroup.RootPart.BlockGrab = p; | ||
2488 | } | ||
2489 | |||
2490 | public void SetStatusSandbox(bool p) | 2529 | public void SetStatusSandbox(bool p) |
2491 | { | 2530 | { |
2492 | if (ParentGroup.IsDeleted) | 2531 | if (ParentGroup.IsDeleted) |
@@ -2649,7 +2688,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2649 | { | 2688 | { |
2650 | if (tau > 0) | 2689 | if (tau > 0) |
2651 | { | 2690 | { |
2652 | ParentGroup.moveToTarget(target, tau); | 2691 | ParentGroup.MoveToTarget(target, tau); |
2653 | } | 2692 | } |
2654 | else | 2693 | else |
2655 | { | 2694 | { |
@@ -2790,7 +2829,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2790 | CollidingMessage = CreateColliderArgs(this, colliders); | 2829 | CollidingMessage = CreateColliderArgs(this, colliders); |
2791 | 2830 | ||
2792 | if (CollidingMessage.Colliders.Count > 0) | 2831 | if (CollidingMessage.Colliders.Count > 0) |
2793 | notify(LocalId, CollidingMessage); | 2832 | DoNotify(notify, LocalId, CollidingMessage); |
2794 | 2833 | ||
2795 | if (PassCollisions) | 2834 | if (PassCollisions) |
2796 | sendToRoot = true; | 2835 | sendToRoot = true; |
@@ -2804,7 +2843,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2804 | { | 2843 | { |
2805 | CollidingMessage = CreateColliderArgs(ParentGroup.RootPart, colliders); | 2844 | CollidingMessage = CreateColliderArgs(ParentGroup.RootPart, colliders); |
2806 | if (CollidingMessage.Colliders.Count > 0) | 2845 | if (CollidingMessage.Colliders.Count > 0) |
2807 | notify(ParentGroup.RootPart.LocalId, CollidingMessage); | 2846 | DoNotify(notify, ParentGroup.RootPart.LocalId, CollidingMessage); |
2808 | } | 2847 | } |
2809 | } | 2848 | } |
2810 | } | 2849 | } |
@@ -2819,6 +2858,35 @@ namespace OpenSim.Region.Framework.Scenes | |||
2819 | colliding.Add(CreateDetObjectForGround()); | 2858 | colliding.Add(CreateDetObjectForGround()); |
2820 | LandCollidingMessage.Colliders = colliding; | 2859 | LandCollidingMessage.Colliders = colliding; |
2821 | 2860 | ||
2861 | <<<<<<< HEAD | ||
2862 | DoNotify(notify, LocalId, LandCollidingMessage); | ||
2863 | } | ||
2864 | } | ||
2865 | |||
2866 | private void DoNotify(ScriptCollidingNotification notify, uint id, ColliderArgs collargs) | ||
2867 | { | ||
2868 | if (m_parentGroup != null && ParentGroup.Scene != null && ParentGroup.Scene.ShouldUseFireAndForgetForCollisions) | ||
2869 | { | ||
2870 | // For those learning C#, FireAndForget takes a function, an object to pass | ||
2871 | // to that function and an ID string. The "oo => {}" construct is a lambda expression | ||
2872 | // for a function with one arguement ('oo'). The 'new Object[] {}" construct creates an Object | ||
2873 | // that is an object array and initializes it with three items (the parameters | ||
2874 | // being passed). The parameters passed are the function to call ('notify') and | ||
2875 | // its two arguements. Finally, once in the function (called later by the FireAndForget | ||
2876 | // thread scheduler), the passed object is cast to an object array and then each | ||
2877 | // of its items (aoo[0] to aoo[2]) are individually cast to what they are and | ||
2878 | // then used in a call of the passed ScriptCollidingNotification function. | ||
2879 | Util.FireAndForget(oo => | ||
2880 | { | ||
2881 | Object[] aoo = (Object[])oo; | ||
2882 | ((ScriptCollidingNotification)aoo[0])((uint)aoo[1], (ColliderArgs)aoo[2]); | ||
2883 | |||
2884 | }, new Object[] { notify, id, collargs }, "SOP.Collision"); | ||
2885 | } | ||
2886 | else | ||
2887 | { | ||
2888 | notify(id, collargs); | ||
2889 | ======= | ||
2822 | if (Inventory.ContainsScripts()) | 2890 | if (Inventory.ContainsScripts()) |
2823 | { | 2891 | { |
2824 | if (!PassCollisions) | 2892 | if (!PassCollisions) |
@@ -2830,6 +2898,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2830 | if ((ParentGroup.RootPart.ScriptEvents & ev) != 0 && sendToRoot) | 2898 | if ((ParentGroup.RootPart.ScriptEvents & ev) != 0 && sendToRoot) |
2831 | { | 2899 | { |
2832 | notify(ParentGroup.RootPart.LocalId, LandCollidingMessage); | 2900 | notify(ParentGroup.RootPart.LocalId, LandCollidingMessage); |
2901 | >>>>>>> avn/ubitvar | ||
2833 | } | 2902 | } |
2834 | } | 2903 | } |
2835 | 2904 | ||
@@ -2977,10 +3046,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
2977 | 3046 | ||
2978 | if (pa != null) | 3047 | if (pa != null) |
2979 | { | 3048 | { |
3049 | <<<<<<< HEAD | ||
3050 | Vector3 newpos = pa.Position; | ||
3051 | ======= | ||
2980 | Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); | 3052 | Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); |
2981 | 3053 | ||
3054 | >>>>>>> avn/ubitvar | ||
2982 | if (!ParentGroup.Scene.PositionIsInCurrentRegion(newpos)) | 3055 | if (!ParentGroup.Scene.PositionIsInCurrentRegion(newpos)) |
2983 | { | 3056 | { |
3057 | // Setting position outside current region will start region crossing | ||
2984 | ParentGroup.AbsolutePosition = newpos; | 3058 | ParentGroup.AbsolutePosition = newpos; |
2985 | return; | 3059 | return; |
2986 | } | 3060 | } |
@@ -3109,7 +3183,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3109 | return; | 3183 | return; |
3110 | } | 3184 | } |
3111 | 3185 | ||
3112 | m_APIDIterations = 1 + (int)(Math.PI * APIDStrength); | 3186 | APIDActive = true; |
3113 | } | 3187 | } |
3114 | 3188 | ||
3115 | // Necessary to get the lookat deltas applied | 3189 | // Necessary to get the lookat deltas applied |
@@ -3123,7 +3197,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3123 | 3197 | ||
3124 | public void StopLookAt() | 3198 | public void StopLookAt() |
3125 | { | 3199 | { |
3126 | APIDTarget = Quaternion.Identity; | 3200 | APIDActive = false; |
3127 | } | 3201 | } |
3128 | 3202 | ||
3129 | 3203 | ||
@@ -3922,10 +3996,14 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter | |||
3922 | 3996 | ||
3923 | public void StopMoveToTarget() | 3997 | public void StopMoveToTarget() |
3924 | { | 3998 | { |
3999 | <<<<<<< HEAD | ||
4000 | ParentGroup.StopMoveToTarget(); | ||
4001 | ======= | ||
3925 | ParentGroup.stopMoveToTarget(); | 4002 | ParentGroup.stopMoveToTarget(); |
3926 | 4003 | ||
3927 | // ParentGroup.ScheduleGroupForTerseUpdate(); | 4004 | // ParentGroup.ScheduleGroupForTerseUpdate(); |
3928 | //ParentGroup.ScheduleGroupForFullUpdate(); | 4005 | //ParentGroup.ScheduleGroupForFullUpdate(); |
4006 | >>>>>>> avn/ubitvar | ||
3929 | } | 4007 | } |
3930 | 4008 | ||
3931 | public void StoreUndoState(ObjectChangeType change) | 4009 | public void StoreUndoState(ObjectChangeType change) |
@@ -4773,6 +4851,12 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter | |||
4773 | } | 4851 | } |
4774 | else // it already has a physical representation | 4852 | else // it already has a physical representation |
4775 | { | 4853 | { |
4854 | <<<<<<< HEAD | ||
4855 | pa.SetMaterial(Material); | ||
4856 | pa.Position = GetWorldPosition(); | ||
4857 | pa.Orientation = GetWorldRotation(); | ||
4858 | DoPhysicsPropertyUpdate(UsePhysics, true); | ||
4859 | ======= | ||
4776 | DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. | 4860 | DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. |
4777 | /* moved into DoPhysicsPropertyUpdate | 4861 | /* moved into DoPhysicsPropertyUpdate |
4778 | if(VolumeDetectActive) | 4862 | if(VolumeDetectActive) |
@@ -4780,6 +4864,7 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter | |||
4780 | else | 4864 | else |
4781 | pa.SetVolumeDetect(0); | 4865 | pa.SetVolumeDetect(0); |
4782 | */ | 4866 | */ |
4867 | >>>>>>> avn/ubitvar | ||
4783 | 4868 | ||
4784 | if (pa.Building != building) | 4869 | if (pa.Building != building) |
4785 | pa.Building = building; | 4870 | pa.Building = building; |
@@ -5434,7 +5519,10 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter | |||
5434 | if (OwnerID != item.Owner) | 5519 | if (OwnerID != item.Owner) |
5435 | { | 5520 | { |
5436 | //LogPermissions("Before ApplyNextOwnerPermissions"); | 5521 | //LogPermissions("Before ApplyNextOwnerPermissions"); |
5437 | ApplyNextOwnerPermissions(); | 5522 | |
5523 | if (scene.Permissions.PropagatePermissions()) | ||
5524 | ApplyNextOwnerPermissions(); | ||
5525 | |||
5438 | //LogPermissions("After ApplyNextOwnerPermissions"); | 5526 | //LogPermissions("After ApplyNextOwnerPermissions"); |
5439 | 5527 | ||
5440 | LastOwnerID = OwnerID; | 5528 | LastOwnerID = OwnerID; |
@@ -5468,20 +5556,34 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter | |||
5468 | { | 5556 | { |
5469 | try | 5557 | try |
5470 | { | 5558 | { |
5471 | if (APIDTarget != Quaternion.Identity) | 5559 | if (APIDActive) |
5472 | { | 5560 | { |
5473 | if (m_APIDIterations <= 1) | 5561 | PhysicsActor pa = ParentGroup.RootPart.PhysActor; |
5562 | if (pa == null || !pa.IsPhysical || APIDStrength < 0.04) | ||
5474 | { | 5563 | { |
5475 | UpdateRotation(APIDTarget); | 5564 | StopLookAt(); |
5476 | APIDTarget = Quaternion.Identity; | ||
5477 | return; | 5565 | return; |
5478 | } | 5566 | } |
5479 | 5567 | ||
5480 | Quaternion rot = Quaternion.Slerp(RotationOffset,APIDTarget,1.0f/(float)m_APIDIterations); | 5568 | Quaternion currRot = GetWorldRotation(); |
5481 | rot.Normalize(); | 5569 | currRot.Normalize(); |
5482 | UpdateRotation(rot); | 5570 | |
5571 | // difference between current orientation and desired orientation | ||
5572 | Quaternion dR = currRot / APIDTarget; | ||
5573 | |||
5574 | // find axis and angle of rotation to rotate to desired orientation | ||
5575 | Vector3 axis = Vector3.UnitX; | ||
5576 | float angle; | ||
5577 | dR.GetAxisAngle(out axis, out angle); | ||
5578 | axis = axis * currRot; | ||
5579 | |||
5580 | // clamp strength to avoid overshoot | ||
5581 | float strength = 1.0f / APIDStrength; | ||
5582 | if (strength > 1.0) strength = 1.0f; | ||
5483 | 5583 | ||
5484 | m_APIDIterations--; | 5584 | // set angular velocity to rotate to desired orientation |
5585 | // with velocity proportional to strength and angle | ||
5586 | AngularVelocity = axis * angle * strength * (float)Math.PI; | ||
5485 | 5587 | ||
5486 | // This ensures that we'll check this object on the next iteration | 5588 | // This ensures that we'll check this object on the next iteration |
5487 | ParentGroup.QueueForUpdateCheck(); | 5589 | ParentGroup.QueueForUpdateCheck(); |
@@ -5519,19 +5621,19 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter | |||
5519 | /// true if the avatar was not already recorded, false otherwise. | 5621 | /// true if the avatar was not already recorded, false otherwise. |
5520 | /// </returns> | 5622 | /// </returns> |
5521 | /// <param name='avatarId'></param> | 5623 | /// <param name='avatarId'></param> |
5522 | protected internal bool AddSittingAvatar(UUID avatarId) | 5624 | protected internal bool AddSittingAvatar(ScenePresence sp) |
5523 | { | 5625 | { |
5524 | lock (ParentGroup.m_sittingAvatars) | 5626 | lock (ParentGroup.m_sittingAvatars) |
5525 | { | 5627 | { |
5526 | if (IsSitTargetSet && SitTargetAvatar == UUID.Zero) | 5628 | if (IsSitTargetSet && SitTargetAvatar == UUID.Zero) |
5527 | SitTargetAvatar = avatarId; | 5629 | SitTargetAvatar = sp.UUID; |
5528 | 5630 | ||
5529 | if (m_sittingAvatars == null) | 5631 | if (m_sittingAvatars == null) |
5530 | m_sittingAvatars = new HashSet<UUID>(); | 5632 | m_sittingAvatars = new HashSet<ScenePresence>(); |
5531 | 5633 | ||
5532 | if (m_sittingAvatars.Add(avatarId)) | 5634 | if (m_sittingAvatars.Add(sp)) |
5533 | { | 5635 | { |
5534 | ParentGroup.m_sittingAvatars.Add(avatarId); | 5636 | ParentGroup.m_sittingAvatars.Add(sp); |
5535 | 5637 | ||
5536 | return true; | 5638 | return true; |
5537 | } | 5639 | } |
@@ -5548,22 +5650,22 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter | |||
5548 | /// true if the avatar was present and removed, false if it was not present. | 5650 | /// true if the avatar was present and removed, false if it was not present. |
5549 | /// </returns> | 5651 | /// </returns> |
5550 | /// <param name='avatarId'></param> | 5652 | /// <param name='avatarId'></param> |
5551 | protected internal bool RemoveSittingAvatar(UUID avatarId) | 5653 | protected internal bool RemoveSittingAvatar(ScenePresence sp) |
5552 | { | 5654 | { |
5553 | lock (ParentGroup.m_sittingAvatars) | 5655 | lock (ParentGroup.m_sittingAvatars) |
5554 | { | 5656 | { |
5555 | if (SitTargetAvatar == avatarId) | 5657 | if (SitTargetAvatar == sp.UUID) |
5556 | SitTargetAvatar = UUID.Zero; | 5658 | SitTargetAvatar = UUID.Zero; |
5557 | 5659 | ||
5558 | if (m_sittingAvatars == null) | 5660 | if (m_sittingAvatars == null) |
5559 | return false; | 5661 | return false; |
5560 | 5662 | ||
5561 | if (m_sittingAvatars.Remove(avatarId)) | 5663 | if (m_sittingAvatars.Remove(sp)) |
5562 | { | 5664 | { |
5563 | if (m_sittingAvatars.Count == 0) | 5665 | if (m_sittingAvatars.Count == 0) |
5564 | m_sittingAvatars = null; | 5666 | m_sittingAvatars = null; |
5565 | 5667 | ||
5566 | ParentGroup.m_sittingAvatars.Remove(avatarId); | 5668 | ParentGroup.m_sittingAvatars.Remove(sp); |
5567 | 5669 | ||
5568 | return true; | 5670 | return true; |
5569 | } | 5671 | } |
@@ -5577,14 +5679,14 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter | |||
5577 | /// </summary> | 5679 | /// </summary> |
5578 | /// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks> | 5680 | /// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks> |
5579 | /// <returns>A hashset of the sitting avatars. Returns null if there are no sitting avatars.</returns> | 5681 | /// <returns>A hashset of the sitting avatars. Returns null if there are no sitting avatars.</returns> |
5580 | public HashSet<UUID> GetSittingAvatars() | 5682 | public HashSet<ScenePresence> GetSittingAvatars() |
5581 | { | 5683 | { |
5582 | lock (ParentGroup.m_sittingAvatars) | 5684 | lock (ParentGroup.m_sittingAvatars) |
5583 | { | 5685 | { |
5584 | if (m_sittingAvatars == null) | 5686 | if (m_sittingAvatars == null) |
5585 | return null; | 5687 | return null; |
5586 | else | 5688 | else |
5587 | return new HashSet<UUID>(m_sittingAvatars); | 5689 | return new HashSet<ScenePresence>(m_sittingAvatars); |
5588 | } | 5690 | } |
5589 | } | 5691 | } |
5590 | 5692 | ||