aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
authorUbitUmarov2018-12-28 13:52:59 +0000
committerUbitUmarov2018-12-28 13:52:59 +0000
commit4a73cc81dc4e03b2b7c46829cecfc0627c3fddb4 (patch)
tree6e8200b3b7a3c0465853e42bbd790a59ccd4e312 /OpenSim/Region/Framework
parentupdate pbs (diff)
downloadopensim-SC-4a73cc81dc4e03b2b7c46829cecfc0627c3fddb4.zip
opensim-SC-4a73cc81dc4e03b2b7c46829cecfc0627c3fddb4.tar.gz
opensim-SC-4a73cc81dc4e03b2b7c46829cecfc0627c3fddb4.tar.bz2
opensim-SC-4a73cc81dc4e03b2b7c46829cecfc0627c3fddb4.tar.xz
now break several things at same time... sog/sop updates, threads options,...
Diffstat (limited to '')
-rwxr-xr-xOpenSim/Region/Framework/Scenes/Scene.cs26
-rwxr-xr-xOpenSim/Region/Framework/Scenes/SceneGraph.cs126
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs27
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs448
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs145
5 files changed, 411 insertions, 361 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 502bbda..e5aa21e 100755
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -62,9 +62,23 @@ namespace OpenSim.Region.Framework.Scenes
62 private const long DEFAULT_MIN_TIME_FOR_PERSISTENCE = 60L; 62 private const long DEFAULT_MIN_TIME_FOR_PERSISTENCE = 60L;
63 private const long DEFAULT_MAX_TIME_FOR_PERSISTENCE = 600L; 63 private const long DEFAULT_MAX_TIME_FOR_PERSISTENCE = 600L;
64 64
65
66 public delegate void SynchronizeSceneHandler(Scene scene); 65 public delegate void SynchronizeSceneHandler(Scene scene);
67 66
67 protected static int m_animationSequenceNumber = (int)(Util.GetTimeStampTicks() & 0x5fffafL);
68
69 public int NextObjectAnimationSequenceNumber
70 {
71 get
72 {
73 int ret = Interlocked.Increment(ref m_animationSequenceNumber);
74 if (ret <= 0 )
75 {
76 m_animationSequenceNumber = (int)(Util.GetTimeStampTicks() & 0xafff5fL);
77 ret = Interlocked.Increment(ref m_animationSequenceNumber);
78 }
79 return ret;
80 }
81 }
68 #region Fields 82 #region Fields
69 83
70 /// <summary> 84 /// <summary>
@@ -945,6 +959,7 @@ namespace OpenSim.Region.Framework.Scenes
945 959
946 PhysicalPrims = startupConfig.GetBoolean("physical_prim", true); 960 PhysicalPrims = startupConfig.GetBoolean("physical_prim", true);
947 CollidablePrims = startupConfig.GetBoolean("collidable_prim", true); 961 CollidablePrims = startupConfig.GetBoolean("collidable_prim", true);
962
948 m_minNonphys = startupConfig.GetFloat("NonPhysicalPrimMin", m_minNonphys); 963 m_minNonphys = startupConfig.GetFloat("NonPhysicalPrimMin", m_minNonphys);
949 if (RegionInfo.NonphysPrimMin > 0) 964 if (RegionInfo.NonphysPrimMin > 0)
950 { 965 {
@@ -1547,10 +1562,9 @@ namespace OpenSim.Region.Framework.Scenes
1547 // tell physics to finish building actor 1562 // tell physics to finish building actor
1548 m_sceneGraph.ProcessPhysicsPreSimulation(); 1563 m_sceneGraph.ProcessPhysicsPreSimulation();
1549 1564
1550 m_heartbeatThread 1565 m_heartbeatThread = WorkManager.StartThread(
1551 = WorkManager.StartThread( 1566 Heartbeat, string.Format("Heartbeat-({0})", RegionInfo.RegionName.Replace(" ", "_")), ThreadPriority.Normal, false,
1552 Heartbeat, string.Format("Heartbeat-({0})", RegionInfo.RegionName.Replace(" ", "_")), ThreadPriority.Normal, false, false); 1567 false, null, 20000, false);
1553
1554 StartScripts(); 1568 StartScripts();
1555 } 1569 }
1556 1570
@@ -1943,7 +1957,7 @@ namespace OpenSim.Region.Framework.Scenes
1943 { 1957 {
1944 if (!m_backingup) 1958 if (!m_backingup)
1945 { 1959 {
1946 WorkManager.RunInThreadPool(o => Backup(false), null, string.Format("BackupWorker ({0}", Name), false); 1960 WorkManager.RunInThreadPool(o => Backup(false), null, string.Format("BackupWorker ({0})", Name), false);
1947 } 1961 }
1948 } 1962 }
1949 1963
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 61a243d..68864cc 100755
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Threading; 29using System.Threading;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Collections.Concurrent;
31using System.Reflection; 32using System.Reflection;
32using OpenMetaverse; 33using OpenMetaverse;
33using OpenMetaverse.Packets; 34using OpenMetaverse.Packets;
@@ -68,8 +69,10 @@ namespace OpenSim.Region.Framework.Scenes
68 69
69 #region Fields 70 #region Fields
70 71
71 protected OpenMetaverse.ReaderWriterLockSlim m_scenePresencesLock = new OpenMetaverse.ReaderWriterLockSlim(); 72 protected System.Threading.ReaderWriterLockSlim m_scenePresencesLock = new System.Threading.ReaderWriterLockSlim();
72 protected Dictionary<UUID, ScenePresence> m_scenePresenceMap = new Dictionary<UUID, ScenePresence>(); 73
74 protected ConcurrentDictionary<UUID, ScenePresence> m_scenePresenceMap = new ConcurrentDictionary<UUID, ScenePresence>();
75 protected ConcurrentDictionary<uint, ScenePresence> m_scenePresenceLocalIDMap = new ConcurrentDictionary<uint, ScenePresence>();
73 protected List<ScenePresence> m_scenePresenceArray = new List<ScenePresence>(); 76 protected List<ScenePresence> m_scenePresenceArray = new List<ScenePresence>();
74 77
75 protected internal EntityManager Entities = new EntityManager(); 78 protected internal EntityManager Entities = new EntityManager();
@@ -147,10 +150,9 @@ namespace OpenSim.Region.Framework.Scenes
147 m_scenePresencesLock.EnterWriteLock(); 150 m_scenePresencesLock.EnterWriteLock();
148 try 151 try
149 { 152 {
150 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(); 153 m_scenePresenceMap = new ConcurrentDictionary<UUID, ScenePresence>();
151 List<ScenePresence> newlist = new List<ScenePresence>(); 154 m_scenePresenceLocalIDMap = new ConcurrentDictionary<uint, ScenePresence>();
152 m_scenePresenceMap = newmap; 155 m_scenePresenceArray = new List<ScenePresence>();
153 m_scenePresenceArray = newlist;
154 } 156 }
155 finally 157 finally
156 { 158 {
@@ -165,22 +167,13 @@ namespace OpenSim.Region.Framework.Scenes
165 SceneObjectGroupsByLocalPartID.Clear(); 167 SceneObjectGroupsByLocalPartID.Clear();
166 168
167 Entities.Clear(); 169 Entities.Clear();
170 m_scenePresencesLock.Dispose();
168 } 171 }
169 172
170 #region Update Methods 173 #region Update Methods
171 174
172 protected internal void UpdatePreparePhysics() 175 protected internal void UpdatePreparePhysics()
173 { 176 {
174 // If we are using a threaded physics engine
175 // grab the latest scene from the engine before
176 // trying to process it.
177
178 // PhysX does this (runs in the background).
179
180 if (PhysicsScene.IsThreaded)
181 {
182 PhysicsScene.GetResults();
183 }
184 } 177 }
185 178
186 /// <summary> 179 /// <summary>
@@ -197,6 +190,14 @@ namespace OpenSim.Region.Framework.Scenes
197 }); 190 });
198 } 191 }
199 192
193 protected internal void UpdateScenePresenceMovement()
194 {
195 ForEachScenePresence(delegate (ScenePresence presence)
196 {
197 presence.UpdateMovement();
198 });
199 }
200
200 /// <summary> 201 /// <summary>
201 /// Perform a physics frame update. 202 /// Perform a physics frame update.
202 /// </summary> 203 /// </summary>
@@ -204,23 +205,9 @@ namespace OpenSim.Region.Framework.Scenes
204 /// <returns></returns> 205 /// <returns></returns>
205 protected internal float UpdatePhysics(double elapsed) 206 protected internal float UpdatePhysics(double elapsed)
206 { 207 {
207 // Here is where the Scene calls the PhysicsScene. This is a one-way 208 if (PhysicsScene != null)
208 // interaction; the PhysicsScene cannot access the calling Scene directly. 209 return PhysicsScene.Simulate((float)elapsed);
209 // But with joints, we want a PhysicsActor to be able to influence a 210 return 0;
210 // non-physics SceneObjectPart. In particular, a PhysicsActor that is connected
211 // with a joint should be able to move the SceneObjectPart which is the visual
212 // representation of that joint (for editing and serialization purposes).
213 // However the PhysicsActor normally cannot directly influence anything outside
214 // of the PhysicsScene, and the non-physical SceneObjectPart which represents
215 // the joint in the Scene does not exist in the PhysicsScene.
216 //
217 // To solve this, we have an event in the PhysicsScene that is fired when a joint
218 // has changed position (because one of its associated PhysicsActors has changed
219 // position).
220 //
221 // Therefore, JointMoved and JointDeactivated events will be fired as a result of the following Simulate().
222
223 return PhysicsScene.Simulate((float)elapsed);
224 } 211 }
225 212
226 protected internal void ProcessPhysicsPreSimulation() 213 protected internal void ProcessPhysicsPreSimulation()
@@ -229,14 +216,6 @@ namespace OpenSim.Region.Framework.Scenes
229 PhysicsScene.ProcessPreSimulation(); 216 PhysicsScene.ProcessPreSimulation();
230 } 217 }
231 218
232 protected internal void UpdateScenePresenceMovement()
233 {
234 ForEachScenePresence(delegate(ScenePresence presence)
235 {
236 presence.UpdateMovement();
237 });
238 }
239
240 public void GetCoarseLocations(out List<Vector3> coarseLocations, out List<UUID> avatarUUIDs, uint maxLocations) 219 public void GetCoarseLocations(out List<Vector3> coarseLocations, out List<UUID> avatarUUIDs, uint maxLocations)
241 { 220 {
242 coarseLocations = new List<Vector3>(); 221 coarseLocations = new List<Vector3>();
@@ -640,7 +619,7 @@ namespace OpenSim.Region.Framework.Scenes
640 lock (m_updateList) 619 lock (m_updateList)
641 { 620 {
642 updates = new List<SceneObjectGroup>(m_updateList.Values); 621 updates = new List<SceneObjectGroup>(m_updateList.Values);
643 m_updateList.Clear(); 622 m_updateList = new Dictionary<UUID, SceneObjectGroup>();
644 } 623 }
645 624
646 // Go through all updates 625 // Go through all updates
@@ -720,26 +699,32 @@ namespace OpenSim.Region.Framework.Scenes
720 { 699 {
721 m_numChildAgents++; 700 m_numChildAgents++;
722 701
723 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
724 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 702 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
725 703
726 if (!newmap.ContainsKey(presence.UUID)) 704 if (!m_scenePresenceMap.ContainsKey(presence.UUID))
727 { 705 {
728 newmap.Add(presence.UUID, presence); 706 m_scenePresenceMap[presence.UUID] = presence;
707 m_scenePresenceLocalIDMap[presence.LocalId] = presence;
729 newlist.Add(presence); 708 newlist.Add(presence);
730 } 709 }
731 else 710 else
732 { 711 {
733 // Remember the old presence reference from the dictionary 712 // Remember the old presence reference from the dictionary
734 ScenePresence oldref = newmap[presence.UUID]; 713 ScenePresence oldref = m_scenePresenceMap[presence.UUID];
714 uint oldLocalID = oldref.LocalId;
735 // Replace the presence reference in the dictionary with the new value 715 // Replace the presence reference in the dictionary with the new value
736 newmap[presence.UUID] = presence; 716 m_scenePresenceMap[presence.UUID] = presence;
737 // Find the index in the list where the old ref was stored and update the reference
738 newlist[newlist.IndexOf(oldref)] = presence; 717 newlist[newlist.IndexOf(oldref)] = presence;
718
719 if(presence.LocalId != oldLocalID)
720 {
721 m_scenePresenceLocalIDMap.TryRemove(oldLocalID, out oldref);
722 m_scenePresenceLocalIDMap[presence.LocalId] = presence;
723 }
724 // Find the index in the list where the old ref was stored and update the reference
739 } 725 }
740 726
741 // Swap out the dictionary and list with new references 727 // Swap out the dictionary and list with new references
742 m_scenePresenceMap = newmap;
743 m_scenePresenceArray = newlist; 728 m_scenePresenceArray = newlist;
744 } 729 }
745 finally 730 finally
@@ -765,20 +750,15 @@ namespace OpenSim.Region.Framework.Scenes
765 m_scenePresencesLock.EnterWriteLock(); 750 m_scenePresencesLock.EnterWriteLock();
766 try 751 try
767 { 752 {
768 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
769 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
770
771 // Remove the presence reference from the dictionary 753 // Remove the presence reference from the dictionary
772 if (newmap.ContainsKey(agentID)) 754 ScenePresence oldref;
755 if(m_scenePresenceMap.TryRemove(agentID, out oldref))
773 { 756 {
774 ScenePresence oldref = newmap[agentID];
775 newmap.Remove(agentID);
776
777 // Find the index in the list where the old ref was stored and remove the reference 757 // Find the index in the list where the old ref was stored and remove the reference
778 newlist.RemoveAt(newlist.IndexOf(oldref)); 758 List<ScenePresence> newsps = new List<ScenePresence>(m_scenePresenceArray);
779 // Swap out the dictionary and list with new references 759 newsps.RemoveAt(newsps.IndexOf(oldref));
780 m_scenePresenceMap = newmap; 760 m_scenePresenceArray = newsps;
781 m_scenePresenceArray = newlist; 761 m_scenePresenceLocalIDMap.TryRemove(oldref.LocalId, out oldref);
782 } 762 }
783 else 763 else
784 { 764 {
@@ -914,7 +894,16 @@ namespace OpenSim.Region.Framework.Scenes
914 /// <returns></returns> 894 /// <returns></returns>
915 protected internal List<ScenePresence> GetScenePresences() 895 protected internal List<ScenePresence> GetScenePresences()
916 { 896 {
917 return m_scenePresenceArray; 897
898 m_scenePresencesLock.EnterReadLock();
899 try
900 {
901 return m_scenePresenceArray;
902 }
903 finally
904 {
905 m_scenePresencesLock.ExitReadLock();
906 }
918 } 907 }
919 908
920 /// <summary> 909 /// <summary>
@@ -924,9 +913,8 @@ namespace OpenSim.Region.Framework.Scenes
924 /// <returns>null if the presence was not found</returns> 913 /// <returns>null if the presence was not found</returns>
925 protected internal ScenePresence GetScenePresence(UUID agentID) 914 protected internal ScenePresence GetScenePresence(UUID agentID)
926 { 915 {
927 Dictionary<UUID, ScenePresence> presences = m_scenePresenceMap;
928 ScenePresence presence; 916 ScenePresence presence;
929 presences.TryGetValue(agentID, out presence); 917 m_scenePresenceMap.TryGetValue(agentID, out presence);
930 return presence; 918 return presence;
931 } 919 }
932 920
@@ -955,24 +943,28 @@ namespace OpenSim.Region.Framework.Scenes
955 /// <returns>null if the presence was not found</returns> 943 /// <returns>null if the presence was not found</returns>
956 protected internal ScenePresence GetScenePresence(uint localID) 944 protected internal ScenePresence GetScenePresence(uint localID)
957 { 945 {
946 ScenePresence sp = null;
947 if(m_scenePresenceLocalIDMap.TryGetValue(localID, out sp))
948 return sp;
949/*
958 List<ScenePresence> presences = GetScenePresences(); 950 List<ScenePresence> presences = GetScenePresences();
959 foreach (ScenePresence presence in presences) 951 foreach (ScenePresence presence in presences)
960 if (presence.LocalId == localID) 952 if (presence.LocalId == localID)
961 return presence; 953 return presence;
954*/
962 return null; 955 return null;
963 } 956 }
964 957
965 protected internal bool TryGetScenePresence(UUID agentID, out ScenePresence avatar) 958 protected internal bool TryGetScenePresence(UUID agentID, out ScenePresence avatar)
966 { 959 {
967 Dictionary<UUID, ScenePresence> presences = m_scenePresenceMap; 960 return m_scenePresenceMap.TryGetValue(agentID, out avatar);
968 presences.TryGetValue(agentID, out avatar);
969 return (avatar != null);
970 } 961 }
971 962
972 protected internal bool TryGetAvatarByName(string name, out ScenePresence avatar) 963 protected internal bool TryGetAvatarByName(string name, out ScenePresence avatar)
973 { 964 {
974 avatar = null; 965 avatar = null;
975 foreach (ScenePresence presence in GetScenePresences()) 966 List<ScenePresence> presences = GetScenePresences();
967 foreach (ScenePresence presence in presences)
976 { 968 {
977 if (String.Compare(name, presence.ControllingClient.Name, true) == 0) 969 if (String.Compare(name, presence.ControllingClient.Name, true) == 0)
978 { 970 {
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 423fbc7..a78ed8b 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -2584,14 +2584,33 @@ namespace OpenSim.Region.Framework.Scenes
2584 /// <param name="remoteClient"></param> 2584 /// <param name="remoteClient"></param>
2585 public void SendFullUpdateToClient(IClientAPI remoteClient) 2585 public void SendFullUpdateToClient(IClientAPI remoteClient)
2586 { 2586 {
2587 RootPart.SendFullUpdate(remoteClient); 2587 PrimUpdateFlags update = PrimUpdateFlags.FullUpdate;
2588
2589 RootPart.SendFullUpdate(remoteClient, update);
2590
2591 SceneObjectPart[] parts = m_parts.GetArray();
2592 for (int i = 0; i < parts.Length; i++)
2593 {
2594 SceneObjectPart part = parts[i];
2595 if (part != RootPart)
2596 part.SendFullUpdate(remoteClient, update);
2597 }
2598 }
2599
2600 public void SendFullAnimUpdateToClient(IClientAPI remoteClient)
2601 {
2602 PrimUpdateFlags update = PrimUpdateFlags.FullUpdate;
2603 if (RootPart.Shape.MeshFlagEntry)
2604 update = PrimUpdateFlags.FullUpdatewithAnim;
2605
2606 RootPart.SendFullUpdate(remoteClient, update);
2588 2607
2589 SceneObjectPart[] parts = m_parts.GetArray(); 2608 SceneObjectPart[] parts = m_parts.GetArray();
2590 for (int i = 0; i < parts.Length; i++) 2609 for (int i = 0; i < parts.Length; i++)
2591 { 2610 {
2592 SceneObjectPart part = parts[i]; 2611 SceneObjectPart part = parts[i];
2593 if (part != RootPart) 2612 if (part != RootPart)
2594 part.SendFullUpdate(remoteClient); 2613 part.SendFullUpdate(remoteClient, update);
2595 } 2614 }
2596 } 2615 }
2597 2616
@@ -3110,7 +3129,7 @@ namespace OpenSim.Region.Framework.Scenes
3110 ScenePresence sp = m_scene.GetScenePresence(AttachedAvatar); 3129 ScenePresence sp = m_scene.GetScenePresence(AttachedAvatar);
3111 if (sp != null) 3130 if (sp != null)
3112 { 3131 {
3113 sp.SendAttachmentUpdate(this,UpdateRequired.FULL); 3132 sp.SendAttachmentUpdate(this, PrimUpdateFlags.FullUpdate);
3114 return; 3133 return;
3115 } 3134 }
3116 } 3135 }
@@ -3160,7 +3179,7 @@ namespace OpenSim.Region.Framework.Scenes
3160 ScenePresence sp = m_scene.GetScenePresence(AttachedAvatar); 3179 ScenePresence sp = m_scene.GetScenePresence(AttachedAvatar);
3161 if (sp != null) 3180 if (sp != null)
3162 { 3181 {
3163 sp.SendAttachmentUpdate(this, UpdateRequired.TERSE); 3182 sp.SendAttachmentUpdate(this, PrimUpdateFlags.TerseUpdate);
3164 return; 3183 return;
3165 } 3184 }
3166 } 3185 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 6c035f0..c549f5c 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -68,22 +68,6 @@ namespace OpenSim.Region.Framework.Scenes
68 POSITION = 32768 68 POSITION = 32768
69 } 69 }
70 70
71 // I don't really know where to put this except here.
72 // Can't access the OpenSim.Region.ScriptEngine.Common.LSL_BaseClass.Changed constants
73 [Flags]
74 public enum ExtraParamType
75 {
76 Something1 = 1,
77 Something2 = 2,
78 Something3 = 4,
79 Something4 = 8,
80 Flexible = 16,
81 Light = 32,
82 Sculpt = 48,
83 Something5 = 64,
84 Something6 = 128
85 }
86
87 [Flags] 71 [Flags]
88 public enum TextureAnimFlags : byte 72 public enum TextureAnimFlags : byte
89 { 73 {
@@ -109,13 +93,6 @@ namespace OpenSim.Region.Framework.Scenes
109 SCULPT = 7 93 SCULPT = 7
110 } 94 }
111 95
112 public enum UpdateRequired : byte
113 {
114 NONE = 0,
115 TERSE = 1,
116 FULL = 2
117 }
118
119 #endregion Enumerations 96 #endregion Enumerations
120 97
121 public class SceneObjectPart : ISceneEntity 98 public class SceneObjectPart : ISceneEntity
@@ -182,10 +159,13 @@ namespace OpenSim.Region.Framework.Scenes
182 { 159 {
183 get 160 get
184 { 161 {
185 return 162 // assume SitTargetOrientation is normalized (as needed elsewhere)
186 !(SitTargetPosition == Vector3.Zero 163 if( SitTargetPosition != Vector3.Zero ||
187 && (SitTargetOrientation == Quaternion.Identity // Valid Zero Rotation quaternion 164 SitTargetOrientation.X != 0f ||
188 || (SitTargetOrientation.W == 0f && SitTargetOrientation.X == 0f && SitTargetOrientation.Y == 0f && SitTargetOrientation.Z == 0f ))); // Invalid Quaternion 165 SitTargetOrientation.Y != 0f ||
166 SitTargetOrientation.Z != 0f)
167 return true;
168 return false;
189 } 169 }
190 } 170 }
191 171
@@ -1212,7 +1192,18 @@ namespace OpenSim.Region.Framework.Scenes
1212 return a * b; 1192 return a * b;
1213 } 1193 }
1214 1194
1215 public UpdateRequired UpdateFlag { get; set; } 1195 public PrimUpdateFlags UpdateFlag { get; set; }
1196
1197 public PrimUpdateFlags GetAndClearUpdateFlag()
1198 {
1199 lock(UpdateFlagLock)
1200 {
1201 PrimUpdateFlags ret = UpdateFlag;
1202 UpdateFlag = PrimUpdateFlags.None;
1203 return ret;
1204 }
1205 }
1206
1216 private object UpdateFlagLock = new object(); 1207 private object UpdateFlagLock = new object();
1217 1208
1218 /// <summary> 1209 /// <summary>
@@ -1503,11 +1494,16 @@ namespace OpenSim.Region.Framework.Scenes
1503 } 1494 }
1504 set 1495 set
1505 { 1496 {
1497 UUID old = m_collisionSound;
1498
1506 m_collisionSoundType = value; 1499 m_collisionSoundType = value;
1507 if (value == -1) 1500 if (value == -1)
1508 m_collisionSound = invalidCollisionSoundUUID; 1501 m_collisionSound = invalidCollisionSoundUUID;
1509 else if (value == 0) 1502 else if (value == 0)
1510 m_collisionSound = UUID.Zero; 1503 m_collisionSound = UUID.Zero;
1504
1505 if(m_collisionSound != old && ParentGroup != null)
1506 ParentGroup.HasGroupChanged = true;
1511 } 1507 }
1512 } 1508 }
1513 1509
@@ -1516,6 +1512,7 @@ namespace OpenSim.Region.Framework.Scenes
1516 get { return m_collisionSound; } 1512 get { return m_collisionSound; }
1517 set 1513 set
1518 { 1514 {
1515 UUID olds = m_collisionSound;
1519 m_collisionSound = value; 1516 m_collisionSound = value;
1520 1517
1521 if (value == invalidCollisionSoundUUID) 1518 if (value == invalidCollisionSoundUUID)
@@ -1525,13 +1522,24 @@ namespace OpenSim.Region.Framework.Scenes
1525 else 1522 else
1526 m_collisionSoundType = 1; 1523 m_collisionSoundType = 1;
1527 1524
1525 if(m_collisionSound != olds && ParentGroup != null)
1526 ParentGroup.HasGroupChanged = true;
1528 } 1527 }
1529 } 1528 }
1530 1529
1531 public float CollisionSoundVolume 1530 public float CollisionSoundVolume
1532 { 1531 {
1533 get { return m_collisionSoundVolume; } 1532 get { return m_collisionSoundVolume; }
1534 set { m_collisionSoundVolume = value; } 1533 set
1534 {
1535 float oldvalue = m_collisionSoundVolume;
1536 if(value >= 0)
1537 m_collisionSoundVolume = value;
1538 else
1539 m_collisionSoundVolume = 0.0f;
1540 if(m_collisionSoundVolume != oldvalue && ParentGroup != null)
1541 ParentGroup.HasGroupChanged = true;
1542 }
1535 } 1543 }
1536 1544
1537 public float Buoyancy 1545 public float Buoyancy
@@ -1884,7 +1892,7 @@ namespace OpenSim.Region.Framework.Scenes
1884 public void ClearUpdateSchedule() 1892 public void ClearUpdateSchedule()
1885 { 1893 {
1886 lock(UpdateFlagLock) 1894 lock(UpdateFlagLock)
1887 UpdateFlag = UpdateRequired.NONE; 1895 UpdateFlag = PrimUpdateFlags.None;
1888 } 1896 }
1889 1897
1890 /// <summary> 1898 /// <summary>
@@ -3276,40 +3284,27 @@ namespace OpenSim.Region.Framework.Scenes
3276 { 3284 {
3277// m_log.DebugFormat("[SCENE OBJECT PART]: Scheduling full update for {0} {1}", Name, LocalId); 3285// m_log.DebugFormat("[SCENE OBJECT PART]: Scheduling full update for {0} {1}", Name, LocalId);
3278 3286
3279 if (ParentGroup == null) 3287 if (ParentGroup == null || ParentGroup.IsDeleted || ParentGroup.Scene == null)
3280 return;
3281 if (ParentGroup.Scene == null)
3282 return; 3288 return;
3283 3289
3284 if(ParentGroup.Scene.GetNumberOfClients() == 0) 3290 if(ParentGroup.Scene.GetNumberOfClients() == 0)
3285 return; 3291 return;
3286 3292
3287 ParentGroup.QueueForUpdateCheck(); // just in case 3293 ParentGroup.QueueForUpdateCheck(); // just in case
3288 3294
3289 lock(UpdateFlagLock) 3295 lock(UpdateFlagLock)
3290 { 3296 UpdateFlag |= PrimUpdateFlags.FullUpdate;
3291 if(UpdateFlag != UpdateRequired.FULL)
3292 {
3293 UpdateFlag = UpdateRequired.FULL;
3294 3297
3295 // m_log.DebugFormat(
3296 // "[SCENE OBJECT PART]: Scheduling full update for {0}, {1} at {2}",
3297 // UUID, Name, TimeStampFull);
3298
3299 }
3300 }
3301 ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, true); 3298 ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, true);
3302 } 3299 }
3303 3300
3304 /// <summary> 3301 /// <summary>
3305 /// Schedule a terse update for this prim. Terse updates only send position, 3302 /// Schedule a terse update for this prim. Terse updates only send position,
3306 /// rotation, velocity and rotational velocity information. WRONG!!!! 3303 /// rotation, velocity and rotational velocity information.
3307 /// </summary> 3304 /// </summary>
3308 public void ScheduleTerseUpdate() 3305 public void ScheduleTerseUpdate()
3309 { 3306 {
3310 if (ParentGroup == null) 3307 if (ParentGroup == null || ParentGroup.IsDeleted || ParentGroup.Scene == null)
3311 return;
3312 if (ParentGroup.Scene == null)
3313 return; 3308 return;
3314 3309
3315 ParentGroup.HasGroupChanged = true; 3310 ParentGroup.HasGroupChanged = true;
@@ -3317,28 +3312,47 @@ namespace OpenSim.Region.Framework.Scenes
3317 if(ParentGroup.Scene.GetNumberOfClients() == 0) 3312 if(ParentGroup.Scene.GetNumberOfClients() == 0)
3318 return; 3313 return;
3319 3314
3320 // This was pulled from SceneViewer. Attachments always receive full updates. 3315 ParentGroup.QueueForUpdateCheck();
3321 // This is needed because otherwise if only the root prim changes position, then 3316
3322 // it looks as if the entire object has moved (including the other prims). 3317 bool isfull = false;
3323 if (ParentGroup.IsAttachment) 3318 lock (UpdateFlagLock)
3324 { 3319 {
3325 ScheduleFullUpdate(); 3320 if (ParentGroup.IsAttachment)
3326 return; 3321 {
3322 UpdateFlag |= PrimUpdateFlags.FullUpdate;
3323 isfull = true;
3324 }
3325 else
3326 UpdateFlag |= PrimUpdateFlags.TerseUpdate;
3327 } 3327 }
3328 ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, isfull);
3329 }
3330
3331 public void ScheduleUpdate(PrimUpdateFlags update)
3332 {
3333 if (ParentGroup == null || ParentGroup.IsDeleted || ParentGroup.Scene == null)
3334 return;
3335
3336 ParentGroup.HasGroupChanged = true;
3337
3338 if (ParentGroup.Scene.GetNumberOfClients() == 0)
3339 return;
3328 3340
3329 ParentGroup.QueueForUpdateCheck(); 3341 ParentGroup.QueueForUpdateCheck();
3330 lock(UpdateFlagLock) 3342
3343 bool isfull = false;
3344 lock (UpdateFlagLock)
3331 { 3345 {
3332 if (UpdateFlag == UpdateRequired.NONE) 3346 if (ParentGroup.IsAttachment)
3333 { 3347 {
3334 UpdateFlag = UpdateRequired.TERSE; 3348 UpdateFlag |= update | PrimUpdateFlags.FullUpdate;
3335 3349 isfull = true;
3336 // m_log.DebugFormat(
3337 // "[SCENE OBJECT PART]: Scheduling terse update for {0}, {1}",
3338 // UUID, Name);
3339 } 3350 }
3351 else
3352 UpdateFlag |= update;
3340 } 3353 }
3341 ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, false); 3354
3355 ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, isfull);
3342 } 3356 }
3343 3357
3344 public void ScriptSetPhysicsStatus(bool UsePhysics) 3358 public void ScriptSetPhysicsStatus(bool UsePhysics)
@@ -3364,7 +3378,7 @@ namespace OpenSim.Region.Framework.Scenes
3364 ScenePresence sp = ParentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar); 3378 ScenePresence sp = ParentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar);
3365 if (sp != null) 3379 if (sp != null)
3366 { 3380 {
3367 sp.SendAttachmentUpdate(this, UpdateRequired.FULL); 3381 sp.SendAttachmentUpdate(this, PrimUpdateFlags.FullUpdate);
3368 } 3382 }
3369 } 3383 }
3370 else 3384 else
@@ -3373,6 +3387,29 @@ namespace OpenSim.Region.Framework.Scenes
3373 } 3387 }
3374 } 3388 }
3375 3389
3390 protected internal void SendFullUpdate(IClientAPI remoteClient, PrimUpdateFlags update)
3391 {
3392 if (ParentGroup == null)
3393 return;
3394
3395 // m_log.DebugFormat(
3396 // "[SOG]: Sendinging part full update to {0} for {1} {2}", remoteClient.Name, part.Name, part.LocalId);
3397
3398
3399 if (ParentGroup.IsAttachment)
3400 {
3401 ScenePresence sp = ParentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar);
3402 if (sp != null)
3403 {
3404 sp.SendAttachmentUpdate(this, update);
3405 }
3406 }
3407 else
3408 {
3409 SendUpdateToClient(remoteClient, update);
3410 }
3411 }
3412
3376 /// <summary> 3413 /// <summary>
3377 /// Send a full update for this part to all clients. 3414 /// Send a full update for this part to all clients.
3378 /// </summary> 3415 /// </summary>
@@ -3419,7 +3456,7 @@ namespace OpenSim.Region.Framework.Scenes
3419 ScenePresence sp = ParentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar); 3456 ScenePresence sp = ParentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar);
3420 if (sp != null) 3457 if (sp != null)
3421 { 3458 {
3422 sp.SendAttachmentUpdate(this, UpdateRequired.FULL); 3459 sp.SendAttachmentUpdate(this, PrimUpdateFlags.FullUpdate);
3423 } 3460 }
3424 } 3461 }
3425 else 3462 else
@@ -3469,136 +3506,109 @@ namespace OpenSim.Region.Framework.Scenes
3469 /// </summary> 3506 /// </summary>
3470 public void SendScheduledUpdates(double now) 3507 public void SendScheduledUpdates(double now)
3471 { 3508 {
3472 bool sendterse = false; 3509 PrimUpdateFlags current;
3473 bool sendfull = false; 3510 lock (UpdateFlagLock)
3474
3475 lock(UpdateFlagLock)
3476 { 3511 {
3477 switch (UpdateFlag) 3512 current = UpdateFlag;
3478 {
3479 case UpdateRequired.NONE:
3480 break;
3481 3513
3482 case UpdateRequired.TERSE: 3514 if (current == PrimUpdateFlags.None)
3483 sendterse = true; 3515 return;
3484 3516
3485 Vector3 curvel = Velocity; 3517 if(current == PrimUpdateFlags.TerseUpdate)
3486 Vector3 curacc = Acceleration; 3518 {
3487 Vector3 angvel = AngularVelocity; 3519 Vector3 curvel = Velocity;
3520 Vector3 curacc = Acceleration;
3521 Vector3 angvel = AngularVelocity;
3488 3522
3489 while(true) // just to avoid ugly goto 3523 while(true) // just to avoid ugly goto
3490 { 3524 {
3491 double elapsed = now - m_lastUpdateSentTime; 3525 double elapsed = now - m_lastUpdateSentTime;
3492 if (elapsed > TIME_MS_TOLERANCE) 3526 if (elapsed > TIME_MS_TOLERANCE)
3493 break; 3527 break;
3494 3528
3495 if( Math.Abs(curacc.X - m_lastAcceleration.X) > VELOCITY_TOLERANCE || 3529 if( Math.Abs(curacc.X - m_lastAcceleration.X) > VELOCITY_TOLERANCE ||
3496 Math.Abs(curacc.Y - m_lastAcceleration.Y) > VELOCITY_TOLERANCE || 3530 Math.Abs(curacc.Y - m_lastAcceleration.Y) > VELOCITY_TOLERANCE ||
3497 Math.Abs(curacc.Z - m_lastAcceleration.Z) > VELOCITY_TOLERANCE) 3531 Math.Abs(curacc.Z - m_lastAcceleration.Z) > VELOCITY_TOLERANCE)
3498 break; 3532 break;
3499 3533
3500 if( Math.Abs(curvel.X - m_lastVelocity.X) > VELOCITY_TOLERANCE || 3534 if( Math.Abs(curvel.X - m_lastVelocity.X) > VELOCITY_TOLERANCE ||
3501 Math.Abs(curvel.Y - m_lastVelocity.Y) > VELOCITY_TOLERANCE || 3535 Math.Abs(curvel.Y - m_lastVelocity.Y) > VELOCITY_TOLERANCE ||
3502 Math.Abs(curvel.Z - m_lastVelocity.Z) > VELOCITY_TOLERANCE) 3536 Math.Abs(curvel.Z - m_lastVelocity.Z) > VELOCITY_TOLERANCE)
3503 break; 3537 break;
3504 3538
3505 float vx = Math.Abs(curvel.X); 3539 float vx = Math.Abs(curvel.X);
3506 if(vx > 128.0) 3540 if(vx > 128.0)
3507 break; 3541 break;
3508 float vy = Math.Abs(curvel.Y); 3542 float vy = Math.Abs(curvel.Y);
3509 if(vy > 128.0) 3543 if(vy > 128.0)
3510 break; 3544 break;
3511 float vz = Math.Abs(curvel.Z); 3545 float vz = Math.Abs(curvel.Z);
3512 if(vz > 128.0) 3546 if(vz > 128.0)
3513 break; 3547 break;
3514 3548
3515 if ( 3549 if(
3516 vx < VELOCITY_TOLERANCE && 3550 vx < VELOCITY_TOLERANCE &&
3517 vy < VELOCITY_TOLERANCE && 3551 vy < VELOCITY_TOLERANCE &&
3518 vz < VELOCITY_TOLERANCE 3552 vz < VELOCITY_TOLERANCE
3519 ) 3553 )
3520 { 3554 {
3521 if(!AbsolutePosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)) 3555 if(!AbsolutePosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
3522 break; 3556 break;
3523 3557 if(vx < 1e-4 &&
3524 if (vx < 1e-4 &&
3525 vy < 1e-4 && 3558 vy < 1e-4 &&
3526 vz < 1e-4 && 3559 vz < 1e-4 &&
3527 ( 3560 (
3528 Math.Abs(m_lastVelocity.X) > 1e-4 || 3561 Math.Abs(m_lastVelocity.X) > 1e-4 ||
3529 Math.Abs(m_lastVelocity.Y) > 1e-4 || 3562 Math.Abs(m_lastVelocity.Y) > 1e-4 ||
3530 Math.Abs(m_lastVelocity.Z) > 1e-4 3563 Math.Abs(m_lastVelocity.Z) > 1e-4
3531 )) 3564 ))
3532 break; 3565 break;
3533 } 3566 }
3534 3567
3535 if( Math.Abs(angvel.X - m_lastAngularVelocity.X) > ANGVELOCITY_TOLERANCE || 3568 if( Math.Abs(angvel.X - m_lastAngularVelocity.X) > ANGVELOCITY_TOLERANCE ||
3536 Math.Abs(angvel.Y - m_lastAngularVelocity.Y) > ANGVELOCITY_TOLERANCE || 3569 Math.Abs(angvel.Y - m_lastAngularVelocity.Y) > ANGVELOCITY_TOLERANCE ||
3537 Math.Abs(angvel.Z - m_lastAngularVelocity.Z) > ANGVELOCITY_TOLERANCE) 3570 Math.Abs(angvel.Z - m_lastAngularVelocity.Z) > ANGVELOCITY_TOLERANCE)
3538 break; 3571 break;
3539 3572
3540 // viewer interpolators have a limit of 64rad/s 3573 // viewer interpolators have a limit of 64rad/s
3541 float ax = Math.Abs(angvel.X); 3574 float ax = Math.Abs(angvel.X);
3542 if(ax > 64.0) 3575 if(ax > 64.0)
3543 break; 3576 break;
3544 float ay = Math.Abs(angvel.Y); 3577 float ay = Math.Abs(angvel.Y);
3545 if(ay > 64.0) 3578 if(ay > 64.0)
3546 break; 3579 break;
3547 float az = Math.Abs(angvel.Z); 3580 float az = Math.Abs(angvel.Z);
3548 if(az > 64.0) 3581 if(az > 64.0)
3549 break; 3582 break;
3550 3583
3551 if ( 3584 if (
3552 ax < ANGVELOCITY_TOLERANCE && 3585 ax < ANGVELOCITY_TOLERANCE &&
3553 ay < ANGVELOCITY_TOLERANCE && 3586 ay < ANGVELOCITY_TOLERANCE &&
3554 az < ANGVELOCITY_TOLERANCE && 3587 az < ANGVELOCITY_TOLERANCE &&
3555 !RotationOffset.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) 3588 !RotationOffset.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
3556 ) 3589 )
3557 break;
3558
3559 sendterse = false;
3560 break; 3590 break;
3561 } 3591 return;
3562 3592 }
3563 if(sendterse)
3564 {
3565 // Update the "last" values
3566 m_lastPosition = AbsolutePosition;
3567 m_lastRotation = RotationOffset;
3568 m_lastVelocity = curvel;
3569 m_lastAcceleration = curacc;
3570 m_lastAngularVelocity = angvel;
3571 m_lastUpdateSentTime = now;
3572 ClearUpdateSchedule();
3573 }
3574 break;
3575
3576 case UpdateRequired.FULL:
3577 m_lastPosition = AbsolutePosition;
3578 m_lastRotation = RotationOffset;
3579 m_lastVelocity = Velocity;
3580 m_lastAcceleration = Acceleration;
3581 m_lastAngularVelocity = AngularVelocity;
3582 m_lastUpdateSentTime = now;
3583 ClearUpdateSchedule();
3584 sendfull = true;
3585 break;
3586 } 3593 }
3587 } 3594
3588 if(sendterse) 3595 if((current & PrimUpdateFlags.TerseUpdate) != 0)
3589 {
3590 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
3591 { 3596 {
3592 SendTerseUpdateToClient(client); 3597 m_lastPosition = AbsolutePosition;
3593 }); 3598 m_lastRotation = RotationOffset;
3599 m_lastVelocity = Velocity;
3600 m_lastAcceleration = Acceleration;
3601 m_lastAngularVelocity = AngularVelocity;
3602 m_lastUpdateSentTime = now;
3603 }
3604
3605 UpdateFlag = PrimUpdateFlags.None;
3594 } 3606 }
3595 else if(sendfull) 3607
3608 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
3596 { 3609 {
3597 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) 3610 SendUpdateToClient(avatar.ControllingClient, current);
3598 { 3611 });
3599 SendFullUpdate(avatar.ControllingClient);
3600 });
3601 }
3602 } 3612 }
3603 3613
3604 /// <summary> 3614 /// <summary>
@@ -3608,10 +3618,10 @@ namespace OpenSim.Region.Framework.Scenes
3608 { 3618 {
3609 if (ParentGroup == null || ParentGroup.Scene == null) 3619 if (ParentGroup == null || ParentGroup.Scene == null)
3610 return; 3620 return;
3621
3611 lock(UpdateFlagLock) 3622 lock(UpdateFlagLock)
3612 { 3623 {
3613 if(UpdateFlag != UpdateRequired.NONE) 3624 UpdateFlag &= ~PrimUpdateFlags.TerseUpdate;
3614 return;
3615 3625
3616 // Update the "last" values 3626 // Update the "last" values
3617 m_lastPosition = AbsolutePosition; 3627 m_lastPosition = AbsolutePosition;
@@ -3635,8 +3645,7 @@ namespace OpenSim.Region.Framework.Scenes
3635 3645
3636 lock(UpdateFlagLock) 3646 lock(UpdateFlagLock)
3637 { 3647 {
3638 if(UpdateFlag != UpdateRequired.NONE) 3648 UpdateFlag &= ~PrimUpdateFlags.TerseUpdate;
3639 return;
3640 3649
3641 // Update the "last" values 3650 // Update the "last" values
3642 m_lastPosition = AbsolutePosition; 3651 m_lastPosition = AbsolutePosition;
@@ -3652,7 +3661,7 @@ namespace OpenSim.Region.Framework.Scenes
3652 ScenePresence sp = ParentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar); 3661 ScenePresence sp = ParentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar);
3653 if (sp != null) 3662 if (sp != null)
3654 { 3663 {
3655 sp.SendAttachmentUpdate(this, UpdateRequired.TERSE); 3664 sp.SendAttachmentUpdate(this, PrimUpdateFlags.TerseUpdate);
3656 } 3665 }
3657 } 3666 }
3658 else 3667 else
@@ -3682,12 +3691,6 @@ namespace OpenSim.Region.Framework.Scenes
3682 public void SetBuoyancy(float fvalue) 3691 public void SetBuoyancy(float fvalue)
3683 { 3692 {
3684 Buoyancy = fvalue; 3693 Buoyancy = fvalue;
3685/*
3686 if (PhysActor != null)
3687 {
3688 PhysActor.Buoyancy = fvalue;
3689 }
3690 */
3691 } 3694 }
3692 3695
3693 public void SetDieAtEdge(bool p) 3696 public void SetDieAtEdge(bool p)
@@ -4085,7 +4088,8 @@ namespace OpenSim.Region.Framework.Scenes
4085 GroupID = groupID; 4088 GroupID = groupID;
4086// if (client != null) 4089// if (client != null)
4087// SendPropertiesToClient(client); 4090// SendPropertiesToClient(client);
4088 UpdateFlag = UpdateRequired.FULL; 4091 lock(UpdateFlagLock)
4092 UpdateFlag |= PrimUpdateFlags.FullUpdate;
4089 } 4093 }
4090 4094
4091 /// <summary> 4095 /// <summary>
@@ -4273,8 +4277,6 @@ namespace OpenSim.Region.Framework.Scenes
4273 Vector3 pos = GetWorldPosition(); 4277 Vector3 pos = GetWorldPosition();
4274 Quaternion rot = GetWorldRotation(); 4278 Quaternion rot = GetWorldRotation();
4275 4279
4276 // Variables prefixed with AX are Axiom.Math copies of the LL variety.
4277
4278 Quaternion AXrot = rot; 4280 Quaternion AXrot = rot;
4279 AXrot.Normalize(); 4281 AXrot.Normalize();
4280 4282
@@ -4645,7 +4647,7 @@ namespace OpenSim.Region.Framework.Scenes
4645 { 4647 {
4646 if (ParentGroup.RootPart.GetStatusSandbox()) 4648 if (ParentGroup.RootPart.GetStatusSandbox())
4647 { 4649 {
4648 if (Util.GetDistanceTo(ParentGroup.RootPart.StatusSandboxPos, newPos) > 10) 4650 if (Vector3.DistanceSquared(ParentGroup.RootPart.StatusSandboxPos, newPos) > 100)
4649 { 4651 {
4650 ParentGroup.RootPart.ScriptSetPhysicsStatus(false); 4652 ParentGroup.RootPart.ScriptSetPhysicsStatus(false);
4651 newPos = OffsetPosition; 4653 newPos = OffsetPosition;
@@ -5230,7 +5232,7 @@ namespace OpenSim.Region.Framework.Scenes
5230 // Materials capable viewers can send a ObjectImage packet 5232 // Materials capable viewers can send a ObjectImage packet
5231 // when nothing in TE has changed. MaterialID should be updated 5233 // when nothing in TE has changed. MaterialID should be updated
5232 // by the RenderMaterials CAP handler, so updating it here may cause a 5234 // by the RenderMaterials CAP handler, so updating it here may cause a
5233 // race condtion. Therefore, if no non-materials TE fields have changed, 5235 // race condtion. Therefore, if no non-materials TE fields have not changed,
5234 // we should ignore any changes and not update Shape.TextureEntry 5236 // we should ignore any changes and not update Shape.TextureEntry
5235 5237
5236 bool otherFieldsChanged = false; 5238 bool otherFieldsChanged = false;
@@ -5279,7 +5281,7 @@ namespace OpenSim.Region.Framework.Scenes
5279 } 5281 }
5280 5282
5281 if (changeFlags == 0) 5283 if (changeFlags == 0)
5282 return; 5284 return;
5283 m_shape.TextureEntry = newTex.GetBytes(); 5285 m_shape.TextureEntry = newTex.GetBytes();
5284 TriggerScriptChangedEvent(changeFlags); 5286 TriggerScriptChangedEvent(changeFlags);
5285 ParentGroup.HasGroupChanged = true; 5287 ParentGroup.HasGroupChanged = true;
@@ -5412,6 +5414,21 @@ namespace OpenSim.Region.Framework.Scenes
5412 5414
5413 #endregion Public Methods 5415 #endregion Public Methods
5414 5416
5417 public void SendUpdateToClient(IClientAPI remoteClient, PrimUpdateFlags PrimUpdateFlags)
5418 {
5419 if (ParentGroup.IsDeleted)
5420 return;
5421
5422 if (ParentGroup.IsAttachment &&
5423 (ParentGroup.RootPart != this || ParentGroup.AttachedAvatar != remoteClient.AgentId && ParentGroup.HasPrivateAttachmentPoint))
5424 return;
5425
5426 remoteClient.SendEntityUpdate(this, PrimUpdateFlags);
5427
5428 ParentGroup.Scene.StatsReporter.AddObjectUpdates(1);
5429 }
5430
5431
5415 public void SendTerseUpdateToClient(IClientAPI remoteClient) 5432 public void SendTerseUpdateToClient(IClientAPI remoteClient)
5416 { 5433 {
5417 if (ParentGroup.IsDeleted) 5434 if (ParentGroup.IsDeleted)
@@ -5424,10 +5441,7 @@ namespace OpenSim.Region.Framework.Scenes
5424 5441
5425 // Causes this thread to dig into the Client Thread Data. 5442 // Causes this thread to dig into the Client Thread Data.
5426 // Remember your locking here! 5443 // Remember your locking here!
5427 remoteClient.SendEntityUpdate( 5444 remoteClient.SendEntityUpdate(this, PrimUpdateFlags.TerseUpdate);
5428 this,
5429 PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
5430 | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity);
5431 5445
5432 ParentGroup.Scene.StatsReporter.AddObjectUpdates(1); 5446 ParentGroup.Scene.StatsReporter.AddObjectUpdates(1);
5433 } 5447 }
@@ -5691,5 +5705,75 @@ namespace OpenSim.Region.Framework.Scenes
5691 PhysActor.Building = true; 5705 PhysActor.Building = true;
5692 UpdatePrimFlags(wasUsingPhysics,wasTemporary,wasPhantom,makeVolumeDetect,false); 5706 UpdatePrimFlags(wasUsingPhysics,wasTemporary,wasPhantom,makeVolumeDetect,false);
5693 } 5707 }
5708
5709 private object animsLock = new object();
5710 public Dictionary<UUID, int> Animations = null;
5711 public Dictionary<UUID, string> AnimationsNames = null;
5712
5713 public bool AddAnimation(UUID animId, string animName)
5714 {
5715 if (ParentGroup == null || ParentGroup.IsDeleted || ParentGroup.inTransit)
5716 return false;
5717
5718 lock (animsLock)
5719 {
5720 if (Animations == null)
5721 Animations = new Dictionary<UUID, int>(1);
5722 if (AnimationsNames == null)
5723 AnimationsNames = new Dictionary<UUID, string>(1);
5724
5725 if (Animations.ContainsKey(animId))
5726 return false;
5727
5728 Animations[animId] = ParentGroup.Scene.NextObjectAnimationSequenceNumber;
5729 AnimationsNames[animId] = animName;
5730 ScheduleUpdate(PrimUpdateFlags.Animations);
5731 }
5732 return true;
5733 }
5734
5735 public bool RemoveAnimation(UUID animId)
5736 {
5737 if (ParentGroup == null || ParentGroup.IsDeleted || ParentGroup.inTransit)
5738 return false;
5739
5740 lock (animsLock)
5741 {
5742 if (Animations == null)
5743 return false;
5744
5745 if (Animations.ContainsKey(animId))
5746 {
5747 Animations.Remove(animId);
5748 if(AnimationsNames!=null)
5749 AnimationsNames.Remove(animId);
5750 ScheduleUpdate(PrimUpdateFlags.Animations);
5751 return true;
5752 }
5753 }
5754 return false;
5755 }
5756
5757 public int GetAnimations(out UUID[] ids, out int[] seqs)
5758 {
5759 ids = null;
5760 seqs = null;
5761
5762 if (ParentGroup == null || ParentGroup.IsDeleted || ParentGroup.inTransit)
5763 return -1;
5764
5765 lock (animsLock)
5766 {
5767 if (Animations == null)
5768 return -1;
5769 if(Animations.Count == 0)
5770 return 0;
5771 ids = new UUID[Animations.Count];
5772 Animations.Keys.CopyTo(ids, 0);
5773 seqs = new int[Animations.Count];
5774 Animations.Values.CopyTo(seqs, 0);
5775 return Animations.Count;
5776 }
5777 }
5694 } 5778 }
5695} 5779}
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 3312ace..a308abb 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -2173,7 +2173,7 @@ namespace OpenSim.Region.Framework.Scenes
2173// if(root.LocalId != ParentPart.LocalId) 2173// if(root.LocalId != ParentPart.LocalId)
2174// ControllingClient.SendEntityTerseUpdateImmediate(root); 2174// ControllingClient.SendEntityTerseUpdateImmediate(root);
2175// ControllingClient.SendEntityTerseUpdateImmediate(ParentPart); 2175// ControllingClient.SendEntityTerseUpdateImmediate(ParentPart);
2176 ParentPart.ParentGroup.SendFullUpdateToClient(ControllingClient); 2176 ParentPart.ParentGroup.SendFullAnimUpdateToClient(ControllingClient);
2177 } 2177 }
2178 2178
2179 // verify baked textures and cache 2179 // verify baked textures and cache
@@ -4036,7 +4036,7 @@ namespace OpenSim.Region.Framework.Scenes
4036 foreach (EntityBase e in entities) 4036 foreach (EntityBase e in entities)
4037 { 4037 {
4038 if (e != null && e is SceneObjectGroup && !((SceneObjectGroup)e).IsAttachment) 4038 if (e != null && e is SceneObjectGroup && !((SceneObjectGroup)e).IsAttachment)
4039 ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient); 4039 ((SceneObjectGroup)e).SendFullAnimUpdateToClient(ControllingClient);
4040 } 4040 }
4041 4041
4042 m_reprioritizationLastPosition = AbsolutePosition; 4042 m_reprioritizationLastPosition = AbsolutePosition;
@@ -4883,18 +4883,31 @@ namespace OpenSim.Region.Framework.Scenes
4883 Animator.ResetAnimations(); 4883 Animator.ResetAnimations();
4884 4884
4885 Overrides.CopyAOPairsFrom(cAgent.MovementAnimationOverRides); 4885 Overrides.CopyAOPairsFrom(cAgent.MovementAnimationOverRides);
4886 4886 int nanim = ControllingClient.NextAnimationSequenceNumber;
4887 // FIXME: Why is this null check necessary? Where are the cases where we get a null Anims object? 4887 // FIXME: Why is this null check necessary? Where are the cases where we get a null Anims object?
4888 if (cAgent.DefaultAnim != null) 4888 if (cAgent.DefaultAnim != null)
4889 {
4890 if (cAgent.DefaultAnim.SequenceNum > nanim)
4891 nanim = cAgent.DefaultAnim.SequenceNum;
4889 Animator.Animations.SetDefaultAnimation(cAgent.DefaultAnim.AnimID, cAgent.DefaultAnim.SequenceNum, UUID.Zero); 4892 Animator.Animations.SetDefaultAnimation(cAgent.DefaultAnim.AnimID, cAgent.DefaultAnim.SequenceNum, UUID.Zero);
4893 }
4890 if (cAgent.AnimState != null) 4894 if (cAgent.AnimState != null)
4895 {
4896 if (cAgent.AnimState.SequenceNum > nanim)
4897 nanim = cAgent.AnimState.SequenceNum;
4891 Animator.Animations.SetImplicitDefaultAnimation(cAgent.AnimState.AnimID, cAgent.AnimState.SequenceNum, UUID.Zero); 4898 Animator.Animations.SetImplicitDefaultAnimation(cAgent.AnimState.AnimID, cAgent.AnimState.SequenceNum, UUID.Zero);
4899 }
4892 if (cAgent.Anims != null) 4900 if (cAgent.Anims != null)
4893 Animator.Animations.FromArray(cAgent.Anims); 4901 {
4902 int canim = Animator.Animations.FromArray(cAgent.Anims);
4903 if(canim > nanim)
4904 nanim = canim;
4905 }
4906 ControllingClient.NextAnimationSequenceNumber = ++nanim;
4907
4894 if (cAgent.MotionState != 0) 4908 if (cAgent.MotionState != 0)
4895 Animator.currentControlState = (ScenePresenceAnimator.motionControlStates) cAgent.MotionState; 4909 Animator.currentControlState = (ScenePresenceAnimator.motionControlStates) cAgent.MotionState;
4896 4910
4897
4898 crossingFlags = cAgent.CrossingFlags; 4911 crossingFlags = cAgent.CrossingFlags;
4899 gotCrossUpdate = (crossingFlags != 0); 4912 gotCrossUpdate = (crossingFlags != 0);
4900 if(gotCrossUpdate) 4913 if(gotCrossUpdate)
@@ -5401,14 +5414,18 @@ namespace OpenSim.Region.Framework.Scenes
5401 SceneObjectPart[] parts = sog.Parts; 5414 SceneObjectPart[] parts = sog.Parts;
5402 SceneObjectPart rootpart = sog.RootPart; 5415 SceneObjectPart rootpart = sog.RootPart;
5403 5416
5404 p.ControllingClient.SendEntityUpdate(rootpart, PrimUpdateFlags.FullUpdate); 5417 PrimUpdateFlags update = PrimUpdateFlags.FullUpdate;
5418 if (rootpart.Shape.MeshFlagEntry)
5419 update = PrimUpdateFlags.FullUpdatewithAnim;
5420
5421 p.ControllingClient.SendEntityUpdate(rootpart, update);
5405 5422
5406 for (int i = 0; i < parts.Length; i++) 5423 for (int i = 0; i < parts.Length; i++)
5407 { 5424 {
5408 SceneObjectPart part = parts[i]; 5425 SceneObjectPart part = parts[i];
5409 if (part == rootpart) 5426 if (part == rootpart)
5410 continue; 5427 continue;
5411 p.ControllingClient.SendEntityUpdate(part, PrimUpdateFlags.FullUpdate); 5428 p.ControllingClient.SendEntityUpdate(part, update);
5412 } 5429 }
5413 } 5430 }
5414 5431
@@ -5422,51 +5439,30 @@ namespace OpenSim.Region.Framework.Scenes
5422 PrimUpdateFlags[] flags = new PrimUpdateFlags[origparts.Length]; 5439 PrimUpdateFlags[] flags = new PrimUpdateFlags[origparts.Length];
5423 5440
5424 SceneObjectPart rootpart = sog.RootPart; 5441 SceneObjectPart rootpart = sog.RootPart;
5425 UpdateRequired rootreq = sog.RootPart.UpdateFlag; 5442 PrimUpdateFlags rootreq = sog.RootPart.GetAndClearUpdateFlag();
5426 5443
5427 int j = 0; 5444 int j = 0;
5428 bool allterse = true; 5445
5446 PrimUpdateFlags cur;
5429 for (int i = 0; i < origparts.Length; i++) 5447 for (int i = 0; i < origparts.Length; i++)
5430 { 5448 {
5431 if (origparts[i] != rootpart) 5449 if (origparts[i] != rootpart)
5432 { 5450 {
5433 switch (origparts[i].UpdateFlag) 5451 cur = origparts[i].GetAndClearUpdateFlag();
5434 { 5452 if(cur == PrimUpdateFlags.None)
5435 case UpdateRequired.NONE: 5453 continue;
5436 break; 5454 flags[j] = cur;
5437 5455 parts[j] = origparts[i];
5438 case UpdateRequired.TERSE: 5456 j++;
5439 flags[j] = PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
5440 | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity;
5441 parts[j] = origparts[i];
5442 j++;
5443 break;
5444
5445 case UpdateRequired.FULL:
5446 flags[j] = PrimUpdateFlags.FullUpdate;
5447 allterse = false;
5448 parts[j] = origparts[i];
5449 j++;
5450 break;
5451 }
5452 } 5457 }
5453 origparts[i].UpdateFlag = 0;
5454 } 5458 }
5455 5459
5456 if (j == 0 && rootreq == UpdateRequired.NONE) 5460 if (j == 0 && rootreq == PrimUpdateFlags.None)
5457 return; 5461 return;
5458 5462
5459 PrimUpdateFlags rootflag = PrimUpdateFlags.FullUpdate;
5460
5461 if (rootreq != UpdateRequired.FULL && allterse)
5462 {
5463 rootflag = PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
5464 | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity;
5465 }
5466
5467 int nparts = j; 5463 int nparts = j;
5468 5464
5469 ControllingClient.SendEntityUpdate(rootpart, rootflag); 5465 ControllingClient.SendEntityUpdate(rootpart, rootreq);
5470 5466
5471 for (int i = 0; i < nparts; i++) 5467 for (int i = 0; i < nparts; i++)
5472 { 5468 {
@@ -5485,7 +5481,7 @@ namespace OpenSim.Region.Framework.Scenes
5485 if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && !p.IsViewerUIGod) 5481 if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && !p.IsViewerUIGod)
5486 continue; 5482 continue;
5487 5483
5488 p.ControllingClient.SendEntityUpdate(rootpart, rootflag); 5484 p.ControllingClient.SendEntityUpdate(rootpart, rootreq);
5489 5485
5490 for (int i = 0; i < nparts; i++) 5486 for (int i = 0; i < nparts; i++)
5491 { 5487 {
@@ -5494,41 +5490,22 @@ namespace OpenSim.Region.Framework.Scenes
5494 } 5490 }
5495 } 5491 }
5496 5492
5497 public void SendAttachmentUpdate(SceneObjectGroup sog, UpdateRequired UpdateFlag) 5493 public void SendAttachmentUpdate(SceneObjectGroup sog, PrimUpdateFlags update)
5498 { 5494 {
5499 if (IsChildAgent || IsInTransit) 5495 if (IsChildAgent || IsInTransit)
5500 return; 5496 return;
5501 5497
5502 PrimUpdateFlags flag;
5503 switch (UpdateFlag)
5504 {
5505 case UpdateRequired.TERSE:
5506 flag = PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
5507 | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity;
5508 break;
5509
5510 case UpdateRequired.FULL:
5511 flag = PrimUpdateFlags.FullUpdate;
5512 break;
5513
5514 default:
5515 return;
5516 }
5517
5518 SceneObjectPart[] parts = sog.Parts; 5498 SceneObjectPart[] parts = sog.Parts;
5519 SceneObjectPart rootpart = sog.RootPart; 5499 SceneObjectPart rootpart = sog.RootPart;
5520 5500
5521// rootpart.UpdateFlag = 0; 5501 ControllingClient.SendEntityUpdate(rootpart, update);
5522
5523 ControllingClient.SendEntityUpdate(rootpart, flag);
5524 5502
5525 for (int i = 0; i < parts.Length; i++) 5503 for (int i = 0; i < parts.Length; i++)
5526 { 5504 {
5527 SceneObjectPart part = parts[i]; 5505 SceneObjectPart part = parts[i];
5528 if (part == rootpart) 5506 if (part == rootpart)
5529 continue; 5507 continue;
5530 ControllingClient.SendEntityUpdate(part, flag); 5508 ControllingClient.SendEntityUpdate(part, update);
5531// part.UpdateFlag = 0;
5532 } 5509 }
5533 5510
5534 if (sog.HasPrivateAttachmentPoint) 5511 if (sog.HasPrivateAttachmentPoint)
@@ -5543,14 +5520,14 @@ namespace OpenSim.Region.Framework.Scenes
5543 if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && !p.IsViewerUIGod) 5520 if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && !p.IsViewerUIGod)
5544 continue; 5521 continue;
5545 5522
5546 p.ControllingClient.SendEntityUpdate(rootpart, flag); 5523 p.ControllingClient.SendEntityUpdate(rootpart, update);
5547 5524
5548 for (int i = 0; i < parts.Length; i++) 5525 for (int i = 0; i < parts.Length; i++)
5549 { 5526 {
5550 SceneObjectPart part = parts[i]; 5527 SceneObjectPart part = parts[i];
5551 if (part == rootpart) 5528 if (part == rootpart)
5552 continue; 5529 continue;
5553 p.ControllingClient.SendEntityUpdate(part, flag); 5530 p.ControllingClient.SendEntityUpdate(part, update);
5554 } 5531 }
5555 } 5532 }
5556 } 5533 }
@@ -5560,24 +5537,7 @@ namespace OpenSim.Region.Framework.Scenes
5560 if (IsChildAgent || IsInTransit) 5537 if (IsChildAgent || IsInTransit)
5561 return; 5538 return;
5562 5539
5563 5540 PrimUpdateFlags flag = part.GetAndClearUpdateFlag();
5564 PrimUpdateFlags flag;
5565 switch (part.UpdateFlag)
5566 {
5567 case UpdateRequired.TERSE:
5568 flag = PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
5569 | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity;
5570 break;
5571
5572 case UpdateRequired.FULL:
5573 flag = PrimUpdateFlags.FullUpdate;
5574 break;
5575
5576 default:
5577 return;
5578 }
5579
5580 part.UpdateFlag = 0;
5581 5541
5582 ControllingClient.SendEntityUpdate(part, flag); 5542 ControllingClient.SendEntityUpdate(part, flag);
5583 5543
@@ -5597,30 +5557,11 @@ namespace OpenSim.Region.Framework.Scenes
5597 } 5557 }
5598 } 5558 }
5599 5559
5600 5560 public void SendAttachmentUpdate(SceneObjectPart part, PrimUpdateFlags flag)
5601 public void SendAttachmentUpdate(SceneObjectPart part, UpdateRequired UpdateFlag)
5602 { 5561 {
5603 if (IsChildAgent || IsInTransit) 5562 if (IsChildAgent || IsInTransit)
5604 return; 5563 return;
5605 5564
5606 PrimUpdateFlags flag;
5607 switch (UpdateFlag)
5608 {
5609 case UpdateRequired.TERSE:
5610 flag = PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
5611 | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity;
5612 break;
5613
5614 case UpdateRequired.FULL:
5615 flag = PrimUpdateFlags.FullUpdate;
5616 break;
5617
5618 default:
5619 return;
5620 }
5621
5622// part.UpdateFlag = 0;
5623
5624 ControllingClient.SendEntityUpdate(part, flag); 5565 ControllingClient.SendEntityUpdate(part, flag);
5625 5566
5626 if (part.ParentGroup.HasPrivateAttachmentPoint) 5567 if (part.ParentGroup.HasPrivateAttachmentPoint)