aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
-rw-r--r--OpenSim/Region/Framework/Scenes/AnimationSet.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs7
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs154
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneBase.cs7
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs160
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneManager.cs53
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs65
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs318
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs174
9 files changed, 526 insertions, 414 deletions
diff --git a/OpenSim/Region/Framework/Scenes/AnimationSet.cs b/OpenSim/Region/Framework/Scenes/AnimationSet.cs
index aa0c8b8..740d168 100644
--- a/OpenSim/Region/Framework/Scenes/AnimationSet.cs
+++ b/OpenSim/Region/Framework/Scenes/AnimationSet.cs
@@ -30,6 +30,8 @@ using System.Collections.Generic;
30using OpenSim.Framework; 30using OpenSim.Framework;
31using OpenMetaverse; 31using OpenMetaverse;
32 32
33using Animation = OpenSim.Framework.Animation;
34
33namespace OpenSim.Region.Framework.Scenes 35namespace OpenSim.Region.Framework.Scenes
34{ 36{
35 [Serializable] 37 [Serializable]
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
index ac89f7b..1a91f0c 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -394,7 +394,7 @@ namespace OpenSim.Region.Framework.Scenes
394 void ProcessViewerEffect(IClientAPI remoteClient, List<ViewerEffectEventHandlerArg> args) 394 void ProcessViewerEffect(IClientAPI remoteClient, List<ViewerEffectEventHandlerArg> args)
395 { 395 {
396 // TODO: don't create new blocks if recycling an old packet 396 // TODO: don't create new blocks if recycling an old packet
397 List<ViewerEffectPacket.EffectBlock> effectBlock = new List<ViewerEffectPacket.EffectBlock>(); 397 ViewerEffectPacket.EffectBlock[] effectBlockArray = new ViewerEffectPacket.EffectBlock[args.Count];
398 for (int i = 0; i < args.Count; i++) 398 for (int i = 0; i < args.Count; i++)
399 { 399 {
400 ViewerEffectPacket.EffectBlock effect = new ViewerEffectPacket.EffectBlock(); 400 ViewerEffectPacket.EffectBlock effect = new ViewerEffectPacket.EffectBlock();
@@ -404,11 +404,10 @@ namespace OpenSim.Region.Framework.Scenes
404 effect.ID = args[i].ID; 404 effect.ID = args[i].ID;
405 effect.Type = args[i].Type; 405 effect.Type = args[i].Type;
406 effect.TypeData = args[i].TypeData; 406 effect.TypeData = args[i].TypeData;
407 effectBlock.Add(effect); 407 effectBlockArray[i] = effect;
408 } 408 }
409 ViewerEffectPacket.EffectBlock[] effectBlockArray = effectBlock.ToArray();
410 409
411 ClientManager.ForEach( 410 ForEachClient(
412 delegate(IClientAPI client) 411 delegate(IClientAPI client)
413 { 412 {
414 if (client.AgentId != remoteClient.AgentId) 413 if (client.AgentId != remoteClient.AgentId)
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 5005ac9..7c3875d 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -61,6 +61,7 @@ namespace OpenSim.Region.Framework.Scenes
61 Time = 0, 61 Time = 0,
62 Distance = 1, 62 Distance = 1,
63 SimpleAngularDistance = 2, 63 SimpleAngularDistance = 2,
64 FrontBack = 3,
64 } 65 }
65 66
66 public delegate void SynchronizeSceneHandler(Scene scene); 67 public delegate void SynchronizeSceneHandler(Scene scene);
@@ -81,8 +82,6 @@ namespace OpenSim.Region.Framework.Scenes
81 82
82 protected Timer m_restartWaitTimer = new Timer(); 83 protected Timer m_restartWaitTimer = new Timer();
83 84
84 protected Thread m_updateEntitiesThread;
85
86 public SimStatsReporter StatsReporter; 85 public SimStatsReporter StatsReporter;
87 86
88 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>(); 87 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>();
@@ -107,11 +106,11 @@ namespace OpenSim.Region.Framework.Scenes
107 public bool m_physicalPrim; 106 public bool m_physicalPrim;
108 public float m_maxNonphys = 256; 107 public float m_maxNonphys = 256;
109 public float m_maxPhys = 10; 108 public float m_maxPhys = 10;
110 public bool m_clampPrimSize = false; 109 public bool m_clampPrimSize;
111 public bool m_trustBinaries = false; 110 public bool m_trustBinaries;
112 public bool m_allowScriptCrossings = false; 111 public bool m_allowScriptCrossings;
113 public bool m_useFlySlow = false; 112 public bool m_useFlySlow;
114 public bool m_usePreJump = false; 113 public bool m_usePreJump;
115 public bool m_seeIntoRegionFromNeighbor; 114 public bool m_seeIntoRegionFromNeighbor;
116 // TODO: need to figure out how allow client agents but deny 115 // TODO: need to figure out how allow client agents but deny
117 // root agents when ACL denies access to root agent 116 // root agents when ACL denies access to root agent
@@ -119,11 +118,11 @@ namespace OpenSim.Region.Framework.Scenes
119 public int MaxUndoCount = 5; 118 public int MaxUndoCount = 5;
120 private int m_RestartTimerCounter; 119 private int m_RestartTimerCounter;
121 private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing 120 private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing
122 private int m_incrementsof15seconds = 0; 121 private int m_incrementsof15seconds;
123 private volatile bool m_backingup = false; 122 private volatile bool m_backingup;
123 private bool m_useAsyncWhenPossible;
124 124
125 private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>(); 125 private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>();
126
127 private Dictionary<UUID, SceneObjectGroup> m_groupsWithTargets = new Dictionary<UUID, SceneObjectGroup>(); 126 private Dictionary<UUID, SceneObjectGroup> m_groupsWithTargets = new Dictionary<UUID, SceneObjectGroup>();
128 127
129 protected string m_simulatorVersion = "OpenSimulator Server"; 128 protected string m_simulatorVersion = "OpenSimulator Server";
@@ -143,8 +142,8 @@ namespace OpenSim.Region.Framework.Scenes
143 142
144 public IXfer XferManager; 143 public IXfer XferManager;
145 144
146 protected IAssetService m_AssetService = null; 145 protected IAssetService m_AssetService;
147 protected IAuthorizationService m_AuthorizationService = null; 146 protected IAuthorizationService m_AuthorizationService;
148 147
149 private Object m_heartbeatLock = new Object(); 148 private Object m_heartbeatLock = new Object();
150 149
@@ -185,7 +184,7 @@ namespace OpenSim.Region.Framework.Scenes
185 } 184 }
186 } 185 }
187 186
188 protected IInventoryService m_InventoryService = null; 187 protected IInventoryService m_InventoryService;
189 188
190 public IInventoryService InventoryService 189 public IInventoryService InventoryService
191 { 190 {
@@ -205,7 +204,7 @@ namespace OpenSim.Region.Framework.Scenes
205 } 204 }
206 } 205 }
207 206
208 protected IGridService m_GridService = null; 207 protected IGridService m_GridService;
209 208
210 public IGridService GridService 209 public IGridService GridService
211 { 210 {
@@ -253,9 +252,9 @@ namespace OpenSim.Region.Framework.Scenes
253 // Central Update Loop 252 // Central Update Loop
254 253
255 protected int m_fps = 10; 254 protected int m_fps = 10;
256 protected int m_frame = 0; 255 protected int m_frame;
257 protected float m_timespan = 0.089f; 256 protected float m_timespan = 0.089f;
258 protected DateTime m_lastupdate = DateTime.Now; 257 protected DateTime m_lastupdate = DateTime.UtcNow;
259 258
260 private int m_update_physics = 1; 259 private int m_update_physics = 1;
261 private int m_update_entitymovement = 1; 260 private int m_update_entitymovement = 1;
@@ -266,26 +265,26 @@ namespace OpenSim.Region.Framework.Scenes
266 private int m_update_terrain = 50; 265 private int m_update_terrain = 50;
267 private int m_update_land = 1; 266 private int m_update_land = 1;
268 267
269 private int frameMS = 0; 268 private int frameMS;
270 private int physicsMS2 = 0; 269 private int physicsMS2;
271 private int physicsMS = 0; 270 private int physicsMS;
272 private int otherMS = 0; 271 private int otherMS;
273 272
274 private bool m_physics_enabled = true; 273 private bool m_physics_enabled = true;
275 private bool m_scripts_enabled = true; 274 private bool m_scripts_enabled = true;
276 private string m_defaultScriptEngine; 275 private string m_defaultScriptEngine;
277 private int m_LastLogin = 0; 276 private int m_LastLogin;
278 private Thread HeartbeatThread = null; 277 private Thread HeartbeatThread;
279 private volatile bool shuttingdown = false; 278 private volatile bool shuttingdown;
280 279
281 private int m_lastUpdate = Environment.TickCount; 280 private int m_lastUpdate = Environment.TickCount;
282 private bool m_firstHeartbeat = true; 281 private bool m_firstHeartbeat = true;
283 282
284 private UpdatePrioritizationSchemes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; 283 private UpdatePrioritizationSchemes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
285 private bool m_reprioritization_enabled = true; 284 private bool m_reprioritization_enabled = true;
286 private double m_reprioritization_interval = 2000.0; 285 private double m_reprioritization_interval = 5000.0;
287 private double m_root_reprioritization_distance = 5.0; 286 private double m_root_reprioritization_distance = 10.0;
288 private double m_child_reprioritization_distance = 10.0; 287 private double m_child_reprioritization_distance = 20.0;
289 288
290 private object m_deleting_scene_object = new object(); 289 private object m_deleting_scene_object = new object();
291 290
@@ -480,6 +479,9 @@ namespace OpenSim.Region.Framework.Scenes
480 // 479 //
481 IConfig startupConfig = m_config.Configs["Startup"]; 480 IConfig startupConfig = m_config.Configs["Startup"];
482 481
482 // Should we try to run loops synchronously or asynchronously?
483 m_useAsyncWhenPossible = startupConfig.GetBoolean("use_async_when_possible", false);
484
483 //Animation states 485 //Animation states
484 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); 486 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
485 // TODO: Change default to true once the feature is supported 487 // TODO: Change default to true once the feature is supported
@@ -542,6 +544,9 @@ namespace OpenSim.Region.Framework.Scenes
542 case "simpleangulardistance": 544 case "simpleangulardistance":
543 m_update_prioritization_scheme = UpdatePrioritizationSchemes.SimpleAngularDistance; 545 m_update_prioritization_scheme = UpdatePrioritizationSchemes.SimpleAngularDistance;
544 break; 546 break;
547 case "frontback":
548 m_update_prioritization_scheme = UpdatePrioritizationSchemes.FrontBack;
549 break;
545 default: 550 default:
546 m_log.Warn("[SCENE]: UpdatePrioritizationScheme was not recognized, setting to default settomg of Time"); 551 m_log.Warn("[SCENE]: UpdatePrioritizationScheme was not recognized, setting to default settomg of Time");
547 m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; 552 m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
@@ -889,6 +894,9 @@ namespace OpenSim.Region.Framework.Scenes
889 { 894 {
890 m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName); 895 m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName);
891 896
897 m_restartTimer.Stop();
898 m_restartTimer.Close();
899
892 // Kick all ROOT agents with the message, 'The simulator is going down' 900 // Kick all ROOT agents with the message, 'The simulator is going down'
893 ForEachScenePresence(delegate(ScenePresence avatar) 901 ForEachScenePresence(delegate(ScenePresence avatar)
894 { 902 {
@@ -945,11 +953,8 @@ namespace OpenSim.Region.Framework.Scenes
945 HeartbeatThread = null; 953 HeartbeatThread = null;
946 } 954 }
947 m_lastUpdate = Environment.TickCount; 955 m_lastUpdate = Environment.TickCount;
948 HeartbeatThread = new Thread(new ParameterizedThreadStart(Heartbeat)); 956
949 HeartbeatThread.SetApartmentState(ApartmentState.MTA); 957 HeartbeatThread = Watchdog.StartThread(Heartbeat, "Heartbeat for region " + RegionInfo.RegionName, ThreadPriority.Normal, false);
950 HeartbeatThread.Name = string.Format("Heartbeat for region {0}", RegionInfo.RegionName);
951 HeartbeatThread.Priority = ThreadPriority.AboveNormal;
952 HeartbeatThread.Start();
953 } 958 }
954 959
955 /// <summary> 960 /// <summary>
@@ -976,12 +981,13 @@ namespace OpenSim.Region.Framework.Scenes
976 /// <summary> 981 /// <summary>
977 /// Performs per-frame updates regularly 982 /// Performs per-frame updates regularly
978 /// </summary> 983 /// </summary>
979 /// <param name="sender"></param> 984 private void Heartbeat()
980 /// <param name="e"></param>
981 private void Heartbeat(object sender)
982 { 985 {
983 if (!Monitor.TryEnter(m_heartbeatLock)) 986 if (!Monitor.TryEnter(m_heartbeatLock))
987 {
988 Watchdog.RemoveThread();
984 return; 989 return;
990 }
985 991
986 try 992 try
987 { 993 {
@@ -998,6 +1004,8 @@ namespace OpenSim.Region.Framework.Scenes
998 Monitor.Pulse(m_heartbeatLock); 1004 Monitor.Pulse(m_heartbeatLock);
999 Monitor.Exit(m_heartbeatLock); 1005 Monitor.Exit(m_heartbeatLock);
1000 } 1006 }
1007
1008 Watchdog.RemoveThread();
1001 } 1009 }
1002 1010
1003 /// <summary> 1011 /// <summary>
@@ -1016,10 +1024,11 @@ namespace OpenSim.Region.Framework.Scenes
1016//#endif 1024//#endif
1017 maintc = Environment.TickCount; 1025 maintc = Environment.TickCount;
1018 1026
1019 TimeSpan SinceLastFrame = DateTime.Now - m_lastupdate; 1027 TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastupdate;
1020 float physicsFPS = 0; 1028 float physicsFPS = 0;
1021 1029
1022 frameMS = Environment.TickCount; 1030 frameMS = Environment.TickCount;
1031
1023 try 1032 try
1024 { 1033 {
1025 // Increment the frame counter 1034 // Increment the frame counter
@@ -1101,6 +1110,11 @@ namespace OpenSim.Region.Framework.Scenes
1101 } 1110 }
1102 if (loginsdisabled && (m_frame > 20)) 1111 if (loginsdisabled && (m_frame > 20))
1103 { 1112 {
1113 // In 99.9% of cases it is a bad idea to manually force garbage collection. However,
1114 // this is a rare case where we know we have just went through a long cycle of heap
1115 // allocations, and there is no more work to be done until someone logs in
1116 GC.Collect();
1117
1104 m_log.Debug("[REGION]: Enabling Logins"); 1118 m_log.Debug("[REGION]: Enabling Logins");
1105 loginsdisabled = false; 1119 loginsdisabled = false;
1106 } 1120 }
@@ -1139,13 +1153,16 @@ namespace OpenSim.Region.Framework.Scenes
1139 } 1153 }
1140 m_timedilation = tmpval; 1154 m_timedilation = tmpval;
1141 1155
1142 m_lastupdate = DateTime.Now; 1156 m_lastupdate = DateTime.UtcNow;
1143 } 1157 }
1144 maintc = Environment.TickCount - maintc; 1158 maintc = Environment.TickCount - maintc;
1145 maintc = (int)(m_timespan * 1000) - maintc; 1159 maintc = (int)(m_timespan * 1000) - maintc;
1146 1160
1147 if ((maintc < (m_timespan * 1000)) && maintc > 0) 1161 if ((maintc < (m_timespan * 1000)) && maintc > 0)
1148 Thread.Sleep(maintc); 1162 Thread.Sleep(maintc);
1163
1164 // Tell the watchdog that this thread is still alive
1165 Watchdog.UpdateThread();
1149 } 1166 }
1150 } 1167 }
1151 1168
@@ -1219,10 +1236,7 @@ namespace OpenSim.Region.Framework.Scenes
1219 if (!m_backingup) 1236 if (!m_backingup)
1220 { 1237 {
1221 m_backingup = true; 1238 m_backingup = true;
1222 1239 Util.FireAndForget(BackupWaitCallback);
1223 System.ComponentModel.BackgroundWorker backupWorker = new System.ComponentModel.BackgroundWorker();
1224 backupWorker.DoWork += delegate(object sender, System.ComponentModel.DoWorkEventArgs e) { Backup(); };
1225 backupWorker.RunWorkerAsync();
1226 } 1240 }
1227 } 1241 }
1228 1242
@@ -1235,6 +1249,14 @@ namespace OpenSim.Region.Framework.Scenes
1235 } 1249 }
1236 1250
1237 /// <summary> 1251 /// <summary>
1252 /// Wrapper for Backup() that can be called with Util.FireAndForget()
1253 /// </summary>
1254 private void BackupWaitCallback(object o)
1255 {
1256 Backup();
1257 }
1258
1259 /// <summary>
1238 /// Backup the scene. This acts as the main method of the backup thread. 1260 /// Backup the scene. This acts as the main method of the backup thread.
1239 /// </summary> 1261 /// </summary>
1240 /// <returns></returns> 1262 /// <returns></returns>
@@ -2460,7 +2482,7 @@ namespace OpenSim.Region.Framework.Scenes
2460 /// <param name="client"></param> 2482 /// <param name="client"></param>
2461 public override void AddNewClient(IClientAPI client) 2483 public override void AddNewClient(IClientAPI client)
2462 { 2484 {
2463 ClientManager.Add(client); 2485 m_clientManager.Add(client);
2464 2486
2465 CheckHeartbeat(); 2487 CheckHeartbeat();
2466 SubscribeToClientEvents(client); 2488 SubscribeToClientEvents(client);
@@ -3099,7 +3121,7 @@ namespace OpenSim.Region.Framework.Scenes
3099 3121
3100 // Remove the avatar from the scene 3122 // Remove the avatar from the scene
3101 m_sceneGraph.RemoveScenePresence(agentID); 3123 m_sceneGraph.RemoveScenePresence(agentID);
3102 ClientManager.Remove(agentID); 3124 m_clientManager.Remove(agentID);
3103 3125
3104 try 3126 try
3105 { 3127 {
@@ -3496,9 +3518,7 @@ namespace OpenSim.Region.Framework.Scenes
3496 public virtual void AgentCrossing(UUID agentID, Vector3 position, bool isFlying) 3518 public virtual void AgentCrossing(UUID agentID, Vector3 position, bool isFlying)
3497 { 3519 {
3498 ScenePresence presence; 3520 ScenePresence presence;
3499 3521 m_sceneGraph.TryGetAvatar(agentID, out presence);
3500 lock (m_sceneGraph.ScenePresences)
3501 m_sceneGraph.ScenePresences.TryGetValue(agentID, out presence);
3502 3522
3503 if (presence != null) 3523 if (presence != null)
3504 { 3524 {
@@ -3709,8 +3729,7 @@ namespace OpenSim.Region.Framework.Scenes
3709 Vector3 lookAt, uint teleportFlags) 3729 Vector3 lookAt, uint teleportFlags)
3710 { 3730 {
3711 ScenePresence sp; 3731 ScenePresence sp;
3712 lock (m_sceneGraph.ScenePresences) 3732 m_sceneGraph.TryGetAvatar(remoteClient.AgentId, out sp);
3713 m_sceneGraph.ScenePresences.TryGetValue(remoteClient.AgentId, out sp);
3714 3733
3715 if (sp != null) 3734 if (sp != null)
3716 { 3735 {
@@ -4112,7 +4131,7 @@ namespace OpenSim.Region.Framework.Scenes
4112 /// This list is a new object, so it can be iterated over without locking. 4131 /// This list is a new object, so it can be iterated over without locking.
4113 /// </summary> 4132 /// </summary>
4114 /// <returns></returns> 4133 /// <returns></returns>
4115 public List<ScenePresence> GetScenePresences() 4134 public ScenePresence[] GetScenePresences()
4116 { 4135 {
4117 return m_sceneGraph.GetScenePresences(); 4136 return m_sceneGraph.GetScenePresences();
4118 } 4137 }
@@ -4159,15 +4178,13 @@ namespace OpenSim.Region.Framework.Scenes
4159 public void ForEachScenePresence(Action<ScenePresence> action) 4178 public void ForEachScenePresence(Action<ScenePresence> action)
4160 { 4179 {
4161 // We don't want to try to send messages if there are no avatars. 4180 // We don't want to try to send messages if there are no avatars.
4162 if (m_sceneGraph != null && m_sceneGraph.ScenePresences != null) 4181 if (m_sceneGraph != null)
4163 { 4182 {
4164 try 4183 try
4165 { 4184 {
4166 List<ScenePresence> presenceList = GetScenePresences(); 4185 ScenePresence[] presences = GetScenePresences();
4167 foreach (ScenePresence presence in presenceList) 4186 for (int i = 0; i < presences.Length; i++)
4168 { 4187 action(presences[i]);
4169 action(presence);
4170 }
4171 } 4188 }
4172 catch (Exception e) 4189 catch (Exception e)
4173 { 4190 {
@@ -4239,7 +4256,30 @@ namespace OpenSim.Region.Framework.Scenes
4239 4256
4240 public void ForEachClient(Action<IClientAPI> action) 4257 public void ForEachClient(Action<IClientAPI> action)
4241 { 4258 {
4242 ClientManager.ForEach(action); 4259 ForEachClient(action, m_useAsyncWhenPossible);
4260 }
4261
4262 public void ForEachClient(Action<IClientAPI> action, bool doAsynchronous)
4263 {
4264 // FIXME: Asynchronous iteration is disabled until we have a threading model that
4265 // can support calling this function from an async packet handler without
4266 // potentially deadlocking
4267 m_clientManager.ForEachSync(action);
4268
4269 //if (doAsynchronous)
4270 // m_clientManager.ForEach(action);
4271 //else
4272 // m_clientManager.ForEachSync(action);
4273 }
4274
4275 public bool TryGetClient(UUID avatarID, out IClientAPI client)
4276 {
4277 return m_clientManager.TryGetValue(avatarID, out client);
4278 }
4279
4280 public bool TryGetClient(System.Net.IPEndPoint remoteEndPoint, out IClientAPI client)
4281 {
4282 return m_clientManager.TryGetValue(remoteEndPoint, out client);
4243 } 4283 }
4244 4284
4245 public void ForEachSOG(Action<SceneObjectGroup> action) 4285 public void ForEachSOG(Action<SceneObjectGroup> action)
@@ -4571,7 +4611,7 @@ namespace OpenSim.Region.Framework.Scenes
4571 { 4611 {
4572 case PhysicsJointType.Ball: 4612 case PhysicsJointType.Ball:
4573 { 4613 {
4574 PhysicsVector jointAnchor = PhysicsScene.GetJointAnchor(joint); 4614 Vector3 jointAnchor = PhysicsScene.GetJointAnchor(joint);
4575 Vector3 proxyPos = new Vector3(jointAnchor.X, jointAnchor.Y, jointAnchor.Z); 4615 Vector3 proxyPos = new Vector3(jointAnchor.X, jointAnchor.Y, jointAnchor.Z);
4576 jointProxyObject.ParentGroup.UpdateGroupPosition(proxyPos); // schedules the entire group for a terse update 4616 jointProxyObject.ParentGroup.UpdateGroupPosition(proxyPos); // schedules the entire group for a terse update
4577 } 4617 }
@@ -4579,7 +4619,7 @@ namespace OpenSim.Region.Framework.Scenes
4579 4619
4580 case PhysicsJointType.Hinge: 4620 case PhysicsJointType.Hinge:
4581 { 4621 {
4582 PhysicsVector jointAnchor = PhysicsScene.GetJointAnchor(joint); 4622 Vector3 jointAnchor = PhysicsScene.GetJointAnchor(joint);
4583 4623
4584 // Normally, we would just ask the physics scene to return the axis for the joint. 4624 // Normally, we would just ask the physics scene to return the axis for the joint.
4585 // Unfortunately, ODE sometimes returns <0,0,0> for the joint axis, which should 4625 // Unfortunately, ODE sometimes returns <0,0,0> for the joint axis, which should
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs
index cf5c3c8..82731d1 100644
--- a/OpenSim/Region/Framework/Scenes/SceneBase.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs
@@ -102,12 +102,7 @@ namespace OpenSim.Region.Framework.Scenes
102 102
103 private readonly Mutex _primAllocateMutex = new Mutex(false); 103 private readonly Mutex _primAllocateMutex = new Mutex(false);
104 104
105 private readonly ClientManager m_clientManager = new ClientManager(); 105 protected readonly ClientManager m_clientManager = new ClientManager();
106
107 public ClientManager ClientManager
108 {
109 get { return m_clientManager; }
110 }
111 106
112 public float TimeDilation 107 public float TimeDilation
113 { 108 {
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index deee6c3..db055f9 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -66,7 +66,9 @@ namespace OpenSim.Region.Framework.Scenes
66 66
67 #region Fields 67 #region Fields
68 68
69 protected internal Dictionary<UUID, ScenePresence> ScenePresences = new Dictionary<UUID, ScenePresence>(); 69 protected Dictionary<UUID, ScenePresence> m_scenePresences = new Dictionary<UUID, ScenePresence>();
70 protected ScenePresence[] m_scenePresenceArray = new ScenePresence[0];
71
70 // SceneObjects is not currently populated or used. 72 // SceneObjects is not currently populated or used.
71 //public Dictionary<UUID, SceneObjectGroup> SceneObjects; 73 //public Dictionary<UUID, SceneObjectGroup> SceneObjects;
72 protected internal EntityManager Entities = new EntityManager(); 74 protected internal EntityManager Entities = new EntityManager();
@@ -126,10 +128,12 @@ namespace OpenSim.Region.Framework.Scenes
126 128
127 protected internal void Close() 129 protected internal void Close()
128 { 130 {
129 lock (ScenePresences) 131 lock (m_scenePresences)
130 { 132 {
131 ScenePresences.Clear(); 133 m_scenePresences.Clear();
134 m_scenePresenceArray = new ScenePresence[0];
132 } 135 }
136
133 lock (m_dictionary_lock) 137 lock (m_dictionary_lock)
134 { 138 {
135 SceneObjectGroupsByFullID.Clear(); 139 SceneObjectGroupsByFullID.Clear();
@@ -157,11 +161,9 @@ namespace OpenSim.Region.Framework.Scenes
157 161
158 protected internal void UpdatePresences() 162 protected internal void UpdatePresences()
159 { 163 {
160 List<ScenePresence> updateScenePresences = GetScenePresences(); 164 ScenePresence[] updateScenePresences = GetScenePresences();
161 foreach (ScenePresence pres in updateScenePresences) 165 for (int i = 0; i < updateScenePresences.Length; i++)
162 { 166 updateScenePresences[i].Update();
163 pres.Update();
164 }
165 } 167 }
166 168
167 protected internal float UpdatePhysics(double elapsed) 169 protected internal float UpdatePhysics(double elapsed)
@@ -190,15 +192,9 @@ namespace OpenSim.Region.Framework.Scenes
190 192
191 protected internal void UpdateScenePresenceMovement() 193 protected internal void UpdateScenePresenceMovement()
192 { 194 {
193 List<ScenePresence> moveEntities = GetScenePresences(); 195 ScenePresence[] moveEntities = GetScenePresences();
194 196 for (int i = 0; i < moveEntities.Length; i++)
195 foreach (EntityBase entity in moveEntities) 197 moveEntities[i].UpdateMovement();
196 {
197 //cfk. This throws occaisional exceptions on a heavily used region
198 //and I added this null check to try to preclude the exception.
199 if (entity != null)
200 entity.UpdateMovement();
201 }
202 } 198 }
203 199
204 #endregion 200 #endregion
@@ -645,9 +641,34 @@ namespace OpenSim.Region.Framework.Scenes
645 641
646 Entities[presence.UUID] = presence; 642 Entities[presence.UUID] = presence;
647 643
648 lock (ScenePresences) 644 lock (m_scenePresences)
649 { 645 {
650 ScenePresences[presence.UUID] = presence; 646 if (!m_scenePresences.ContainsKey(presence.UUID))
647 {
648 m_scenePresences.Add(presence.UUID, presence);
649
650 // Create a new array of ScenePresence references
651 int oldLength = m_scenePresenceArray.Length;
652 ScenePresence[] newArray = new ScenePresence[oldLength + 1];
653 Array.Copy(m_scenePresenceArray, newArray, oldLength);
654 newArray[oldLength] = presence;
655 m_scenePresenceArray = newArray;
656 }
657 else
658 {
659 m_scenePresences[presence.UUID] = presence;
660
661 // Do a linear search through the array of ScenePresence references
662 // and update the modified entry
663 for (int i = 0; i < m_scenePresenceArray.Length; i++)
664 {
665 if (m_scenePresenceArray[i].UUID == presence.UUID)
666 {
667 m_scenePresenceArray[i] = presence;
668 break;
669 }
670 }
671 }
651 } 672 }
652 } 673 }
653 674
@@ -663,16 +684,30 @@ namespace OpenSim.Region.Framework.Scenes
663 agentID); 684 agentID);
664 } 685 }
665 686
666 lock (ScenePresences) 687 lock (m_scenePresences)
667 { 688 {
668 if (!ScenePresences.Remove(agentID)) 689 if (m_scenePresences.Remove(agentID))
690 {
691 // Copy all of the elements from the previous array
692 // into the new array except the removed element
693 int oldLength = m_scenePresenceArray.Length;
694 ScenePresence[] newArray = new ScenePresence[oldLength - 1];
695 int j = 0;
696 for (int i = 0; i < m_scenePresenceArray.Length; i++)
697 {
698 ScenePresence presence = m_scenePresenceArray[i];
699 if (presence.UUID != agentID)
700 {
701 newArray[j] = presence;
702 ++j;
703 }
704 }
705 m_scenePresenceArray = newArray;
706 }
707 else
669 { 708 {
670 m_log.WarnFormat("[SCENE] Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); 709 m_log.WarnFormat("[SCENE] Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
671 } 710 }
672// else
673// {
674// m_log.InfoFormat("[SCENE] Removed scene presence {0} from scene presences list", agentID);
675// }
676 } 711 }
677 } 712 }
678 713
@@ -704,20 +739,21 @@ namespace OpenSim.Region.Framework.Scenes
704 739
705 public void RecalculateStats() 740 public void RecalculateStats()
706 { 741 {
707 List<ScenePresence> SPList = GetScenePresences(); 742 ScenePresence[] presences = GetScenePresences();
708 int rootcount = 0; 743 int rootcount = 0;
709 int childcount = 0; 744 int childcount = 0;
710 745
711 foreach (ScenePresence user in SPList) 746 for (int i = 0; i < presences.Length; i++)
712 { 747 {
748 ScenePresence user = presences[i];
713 if (user.IsChildAgent) 749 if (user.IsChildAgent)
714 childcount++; 750 ++childcount;
715 else 751 else
716 rootcount++; 752 ++rootcount;
717 } 753 }
754
718 m_numRootAgents = rootcount; 755 m_numRootAgents = rootcount;
719 m_numChildAgents = childcount; 756 m_numChildAgents = childcount;
720
721 } 757 }
722 758
723 public int GetChildAgentCount() 759 public int GetChildAgentCount()
@@ -767,12 +803,9 @@ namespace OpenSim.Region.Framework.Scenes
767 /// locking is required to iterate over it. 803 /// locking is required to iterate over it.
768 /// </summary> 804 /// </summary>
769 /// <returns></returns> 805 /// <returns></returns>
770 protected internal List<ScenePresence> GetScenePresences() 806 protected internal ScenePresence[] GetScenePresences()
771 { 807 {
772 lock (ScenePresences) 808 return m_scenePresenceArray;
773 {
774 return new List<ScenePresence>(ScenePresences.Values);
775 }
776 } 809 }
777 810
778 protected internal List<ScenePresence> GetAvatars() 811 protected internal List<ScenePresence> GetAvatars()
@@ -817,14 +850,13 @@ namespace OpenSim.Region.Framework.Scenes
817 // No locking of scene presences here since we're passing back a list... 850 // No locking of scene presences here since we're passing back a list...
818 851
819 List<ScenePresence> result = new List<ScenePresence>(); 852 List<ScenePresence> result = new List<ScenePresence>();
820 List<ScenePresence> ScenePresencesList = GetScenePresences(); 853 ScenePresence[] scenePresences = GetScenePresences();
821 854
822 foreach (ScenePresence avatar in ScenePresencesList) 855 for (int i = 0; i < scenePresences.Length; i++)
823 { 856 {
857 ScenePresence avatar = scenePresences[i];
824 if (filter(avatar)) 858 if (filter(avatar))
825 {
826 result.Add(avatar); 859 result.Add(avatar);
827 }
828 } 860 }
829 861
830 return result; 862 return result;
@@ -839,9 +871,9 @@ namespace OpenSim.Region.Framework.Scenes
839 { 871 {
840 ScenePresence sp; 872 ScenePresence sp;
841 873
842 lock (ScenePresences) 874 lock (m_scenePresences)
843 { 875 {
844 ScenePresences.TryGetValue(agentID, out sp); 876 m_scenePresences.TryGetValue(agentID, out sp);
845 } 877 }
846 878
847 return sp; 879 return sp;
@@ -1000,48 +1032,24 @@ namespace OpenSim.Region.Framework.Scenes
1000 1032
1001 protected internal bool TryGetAvatar(UUID avatarId, out ScenePresence avatar) 1033 protected internal bool TryGetAvatar(UUID avatarId, out ScenePresence avatar)
1002 { 1034 {
1003 ScenePresence presence; 1035 lock (m_scenePresences)
1004 1036 return m_scenePresences.TryGetValue(avatarId, out avatar);
1005 lock (ScenePresences)
1006 {
1007 if (ScenePresences.TryGetValue(avatarId, out presence))
1008 {
1009 avatar = presence;
1010 return true;
1011
1012 //if (!presence.IsChildAgent)
1013 //{
1014 // avatar = presence;
1015 // return true;
1016 //}
1017 //else
1018 //{
1019 // m_log.WarnFormat(
1020 // "[INNER SCENE]: Requested avatar {0} could not be found in scene {1} since it is only registered as a child agent!",
1021 // avatarId, m_parentScene.RegionInfo.RegionName);
1022 //}
1023 }
1024 }
1025
1026 avatar = null;
1027 return false;
1028 } 1037 }
1029 1038
1030 protected internal bool TryGetAvatarByName(string avatarName, out ScenePresence avatar) 1039 protected internal bool TryGetAvatarByName(string avatarName, out ScenePresence avatar)
1031 { 1040 {
1032 lock (ScenePresences) 1041 ScenePresence[] presences = GetScenePresences();
1042
1043 for (int i = 0; i < presences.Length; i++)
1033 { 1044 {
1034 foreach (ScenePresence presence in ScenePresences.Values) 1045 ScenePresence presence = presences[i];
1046
1047 if (!presence.IsChildAgent)
1035 { 1048 {
1036 if (!presence.IsChildAgent) 1049 if (String.Compare(avatarName, presence.ControllingClient.Name, true) == 0)
1037 { 1050 {
1038 string name = presence.ControllingClient.Name; 1051 avatar = presence;
1039 1052 return true;
1040 if (String.Compare(avatarName, name, true) == 0)
1041 {
1042 avatar = presence;
1043 return true;
1044 }
1045 } 1053 }
1046 } 1054 }
1047 } 1055 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneManager.cs b/OpenSim/Region/Framework/Scenes/SceneManager.cs
index 3097929..dfaa7ea 100644
--- a/OpenSim/Region/Framework/Scenes/SceneManager.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneManager.cs
@@ -411,41 +411,46 @@ namespace OpenSim.Region.Framework.Scenes
411 /// <param name="newDebug"></param> 411 /// <param name="newDebug"></param>
412 public void SetDebugPacketLevelOnCurrentScene(int newDebug) 412 public void SetDebugPacketLevelOnCurrentScene(int newDebug)
413 { 413 {
414 ForEachCurrentScene(delegate(Scene scene) 414 ForEachCurrentScene(
415 { 415 delegate(Scene scene)
416 List<ScenePresence> scenePresences = scene.GetScenePresences(); 416 {
417 ScenePresence[] scenePresences = scene.GetScenePresences();
418
419 for (int i = 0; i < scenePresences.Length; i++)
420 {
421 ScenePresence scenePresence = scenePresences[i];
417 422
418 foreach (ScenePresence scenePresence in scenePresences) 423 if (!scenePresence.IsChildAgent)
419 { 424 {
420 if (!scenePresence.IsChildAgent) 425 m_log.ErrorFormat("Packet debug for {0} {1} set to {2}",
421 { 426 scenePresence.Firstname,
422 m_log.ErrorFormat("Packet debug for {0} {1} set to {2}", 427 scenePresence.Lastname,
423 scenePresence.Firstname, 428 newDebug);
424 scenePresence.Lastname,
425 newDebug);
426 429
427 scenePresence.ControllingClient.SetDebugPacketLevel(newDebug); 430 scenePresence.ControllingClient.SetDebugPacketLevel(newDebug);
428 } 431 }
429 } 432 }
430 }); 433 }
434 );
431 } 435 }
432 436
433 public List<ScenePresence> GetCurrentSceneAvatars() 437 public List<ScenePresence> GetCurrentSceneAvatars()
434 { 438 {
435 List<ScenePresence> avatars = new List<ScenePresence>(); 439 List<ScenePresence> avatars = new List<ScenePresence>();
436 440
437 ForEachCurrentScene(delegate(Scene scene) 441 ForEachCurrentScene(
438 { 442 delegate(Scene scene)
439 List<ScenePresence> scenePresences = scene.GetScenePresences();
440
441 foreach (ScenePresence scenePresence in scenePresences)
442 { 443 {
443 if (!scenePresence.IsChildAgent) 444 ScenePresence[] scenePresences = scene.GetScenePresences();
445
446 for (int i = 0; i < scenePresences.Length; i++)
444 { 447 {
445 avatars.Add(scenePresence); 448 ScenePresence scenePresence = scenePresences[i];
449 if (!scenePresence.IsChildAgent)
450 avatars.Add(scenePresence);
446 } 451 }
447 } 452 }
448 }); 453 );
449 454
450 return avatars; 455 return avatars;
451 } 456 }
@@ -456,7 +461,7 @@ namespace OpenSim.Region.Framework.Scenes
456 461
457 ForEachCurrentScene(delegate(Scene scene) 462 ForEachCurrentScene(delegate(Scene scene)
458 { 463 {
459 List<ScenePresence> scenePresences = scene.GetScenePresences(); 464 ScenePresence[] scenePresences = scene.GetScenePresences();
460 presences.AddRange(scenePresences); 465 presences.AddRange(scenePresences);
461 }); 466 });
462 467
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index fff807a..ab7abbe 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -493,8 +493,8 @@ namespace OpenSim.Region.Framework.Scenes
493 493
494 public Vector3 GroupScale() 494 public Vector3 GroupScale()
495 { 495 {
496 Vector3 minScale = new Vector3(Constants.RegionSize,Constants.RegionSize,Constants.RegionSize); 496 Vector3 minScale = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionSize);
497 Vector3 maxScale = new Vector3(0f,0f,0f); 497 Vector3 maxScale = Vector3.Zero;
498 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); 498 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
499 499
500 lock (m_parts) 500 lock (m_parts)
@@ -577,7 +577,6 @@ namespace OpenSim.Region.Framework.Scenes
577 { 577 {
578 foreach (SceneObjectPart part in m_parts.Values) 578 foreach (SceneObjectPart part in m_parts.Values)
579 { 579 {
580
581 Vector3 worldPos = part.GetWorldPosition(); 580 Vector3 worldPos = part.GetWorldPosition();
582 Vector3 offset = worldPos - AbsolutePosition; 581 Vector3 offset = worldPos - AbsolutePosition;
583 Quaternion worldRot; 582 Quaternion worldRot;
@@ -1182,8 +1181,8 @@ namespace OpenSim.Region.Framework.Scenes
1182 { 1181 {
1183// part.Inventory.RemoveScriptInstances(); 1182// part.Inventory.RemoveScriptInstances();
1184 1183
1185 List<ScenePresence> avatars = Scene.GetScenePresences(); 1184 ScenePresence[] avatars = Scene.GetScenePresences();
1186 for (int i = 0; i < avatars.Count; i++) 1185 for (int i = 0; i < avatars.Length; i++)
1187 { 1186 {
1188 if (avatars[i].ParentID == LocalId) 1187 if (avatars[i].ParentID == LocalId)
1189 { 1188 {
@@ -1335,7 +1334,7 @@ namespace OpenSim.Region.Framework.Scenes
1335 (parcel.LandData.GroupID != GroupID || 1334 (parcel.LandData.GroupID != GroupID ||
1336 parcel.LandData.GroupID == UUID.Zero)) 1335 parcel.LandData.GroupID == UUID.Zero))
1337 { 1336 {
1338 if ((DateTime.Now - RootPart.Rezzed).TotalMinutes > 1337 if ((DateTime.UtcNow - RootPart.Rezzed).TotalMinutes >
1339 parcel.LandData.OtherCleanTime) 1338 parcel.LandData.OtherCleanTime)
1340 { 1339 {
1341 DetachFromBackup(); 1340 DetachFromBackup();
@@ -1480,8 +1479,8 @@ namespace OpenSim.Region.Framework.Scenes
1480 dupe.RootPart.PhysActor = m_scene.PhysicsScene.AddPrimShape( 1479 dupe.RootPart.PhysActor = m_scene.PhysicsScene.AddPrimShape(
1481 dupe.RootPart.Name, 1480 dupe.RootPart.Name,
1482 pbs, 1481 pbs,
1483 new PhysicsVector(dupe.RootPart.AbsolutePosition.X, dupe.RootPart.AbsolutePosition.Y, dupe.RootPart.AbsolutePosition.Z), 1482 dupe.RootPart.AbsolutePosition,
1484 new PhysicsVector(dupe.RootPart.Scale.X, dupe.RootPart.Scale.Y, dupe.RootPart.Scale.Z), 1483 dupe.RootPart.Scale,
1485 dupe.RootPart.RotationOffset, 1484 dupe.RootPart.RotationOffset,
1486 dupe.RootPart.PhysActor.IsPhysical); 1485 dupe.RootPart.PhysActor.IsPhysical);
1487 1486
@@ -1596,7 +1595,7 @@ namespace OpenSim.Region.Framework.Scenes
1596 */ 1595 */
1597 } 1596 }
1598 1597
1599 public void applyImpulse(PhysicsVector impulse) 1598 public void applyImpulse(Vector3 impulse)
1600 { 1599 {
1601 // We check if rootpart is null here because scripts don't delete if you delete the host. 1600 // We check if rootpart is null here because scripts don't delete if you delete the host.
1602 // This means that unfortunately, we can pass a null physics actor to Simulate! 1601 // This means that unfortunately, we can pass a null physics actor to Simulate!
@@ -1623,7 +1622,7 @@ namespace OpenSim.Region.Framework.Scenes
1623 } 1622 }
1624 } 1623 }
1625 1624
1626 public void applyAngularImpulse(PhysicsVector impulse) 1625 public void applyAngularImpulse(Vector3 impulse)
1627 { 1626 {
1628 // We check if rootpart is null here because scripts don't delete if you delete the host. 1627 // We check if rootpart is null here because scripts don't delete if you delete the host.
1629 // This means that unfortunately, we can pass a null physics actor to Simulate! 1628 // This means that unfortunately, we can pass a null physics actor to Simulate!
@@ -1642,7 +1641,7 @@ namespace OpenSim.Region.Framework.Scenes
1642 } 1641 }
1643 } 1642 }
1644 1643
1645 public void setAngularImpulse(PhysicsVector impulse) 1644 public void setAngularImpulse(Vector3 impulse)
1646 { 1645 {
1647 // We check if rootpart is null here because scripts don't delete if you delete the host. 1646 // We check if rootpart is null here because scripts don't delete if you delete the host.
1648 // This means that unfortunately, we can pass a null physics actor to Simulate! 1647 // This means that unfortunately, we can pass a null physics actor to Simulate!
@@ -1673,8 +1672,8 @@ namespace OpenSim.Region.Framework.Scenes
1673 { 1672 {
1674 if (!IsAttachment) 1673 if (!IsAttachment)
1675 { 1674 {
1676 PhysicsVector torque = rootpart.PhysActor.Torque; 1675 Vector3 torque = rootpart.PhysActor.Torque;
1677 return new Vector3(torque.X, torque.Y, torque.Z); 1676 return torque;
1678 } 1677 }
1679 } 1678 }
1680 } 1679 }
@@ -1707,7 +1706,7 @@ namespace OpenSim.Region.Framework.Scenes
1707 { 1706 {
1708 if (rootpart.PhysActor != null) 1707 if (rootpart.PhysActor != null)
1709 { 1708 {
1710 rootpart.PhysActor.PIDTarget = new PhysicsVector(target.X, target.Y, target.Z); 1709 rootpart.PhysActor.PIDTarget = target;
1711 rootpart.PhysActor.PIDTau = tau; 1710 rootpart.PhysActor.PIDTau = tau;
1712 rootpart.PhysActor.PIDActive = true; 1711 rootpart.PhysActor.PIDActive = true;
1713 } 1712 }
@@ -2414,7 +2413,7 @@ namespace OpenSim.Region.Framework.Scenes
2414 if (m_rootPart.PhysActor.IsPhysical) 2413 if (m_rootPart.PhysActor.IsPhysical)
2415 { 2414 {
2416 Vector3 llmoveforce = pos - AbsolutePosition; 2415 Vector3 llmoveforce = pos - AbsolutePosition;
2417 PhysicsVector grabforce = new PhysicsVector(llmoveforce.X, llmoveforce.Y, llmoveforce.Z); 2416 Vector3 grabforce = llmoveforce;
2418 grabforce = (grabforce / 10) * m_rootPart.PhysActor.Mass; 2417 grabforce = (grabforce / 10) * m_rootPart.PhysActor.Mass;
2419 m_rootPart.PhysActor.AddForce(grabforce,true); 2418 m_rootPart.PhysActor.AddForce(grabforce,true);
2420 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 2419 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
@@ -2519,7 +2518,7 @@ namespace OpenSim.Region.Framework.Scenes
2519 rotationAxis.Normalize(); 2518 rotationAxis.Normalize();
2520 2519
2521 //m_log.Error("SCENE OBJECT GROUP]: rotation axis is " + rotationAxis); 2520 //m_log.Error("SCENE OBJECT GROUP]: rotation axis is " + rotationAxis);
2522 PhysicsVector spinforce = new PhysicsVector(rotationAxis.X, rotationAxis.Y, rotationAxis.Z); 2521 Vector3 spinforce = new Vector3(rotationAxis.X, rotationAxis.Y, rotationAxis.Z);
2523 spinforce = (spinforce/8) * m_rootPart.PhysActor.Mass; // 8 is an arbitrary torque scaling factor 2522 spinforce = (spinforce/8) * m_rootPart.PhysActor.Mass; // 8 is an arbitrary torque scaling factor
2524 m_rootPart.PhysActor.AddAngularForce(spinforce,true); 2523 m_rootPart.PhysActor.AddAngularForce(spinforce,true);
2525 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 2524 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
@@ -2746,8 +2745,7 @@ namespace OpenSim.Region.Framework.Scenes
2746 if (scale.Z > m_scene.m_maxPhys) 2745 if (scale.Z > m_scene.m_maxPhys)
2747 scale.Z = m_scene.m_maxPhys; 2746 scale.Z = m_scene.m_maxPhys;
2748 } 2747 }
2749 part.PhysActor.Size = 2748 part.PhysActor.Size = scale;
2750 new PhysicsVector(scale.X, scale.Y, scale.Z);
2751 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); 2749 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
2752 } 2750 }
2753 //if (part.UUID != m_rootPart.UUID) 2751 //if (part.UUID != m_rootPart.UUID)
@@ -2891,8 +2889,7 @@ namespace OpenSim.Region.Framework.Scenes
2891 2889
2892 if (part.PhysActor != null) 2890 if (part.PhysActor != null)
2893 { 2891 {
2894 part.PhysActor.Size = 2892 part.PhysActor.Size = prevScale;
2895 new PhysicsVector(prevScale.X, prevScale.Y, prevScale.Z);
2896 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); 2893 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
2897 } 2894 }
2898 2895
@@ -3405,6 +3402,8 @@ namespace OpenSim.Region.Framework.Scenes
3405 return GetPriorityByDistance(client); 3402 return GetPriorityByDistance(client);
3406 case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance: 3403 case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance:
3407 return GetPriorityBySimpleAngularDistance(client); 3404 return GetPriorityBySimpleAngularDistance(client);
3405 case Scenes.Scene.UpdatePrioritizationSchemes.FrontBack:
3406 return GetPriorityByFrontBack(client);
3408 default: 3407 default:
3409 throw new InvalidOperationException("UpdatePrioritizationScheme not defined"); 3408 throw new InvalidOperationException("UpdatePrioritizationScheme not defined");
3410 } 3409 }
@@ -3437,6 +3436,16 @@ namespace OpenSim.Region.Framework.Scenes
3437 return double.NaN; 3436 return double.NaN;
3438 } 3437 }
3439 3438
3439 private double GetPriorityByFrontBack(IClientAPI client)
3440 {
3441 ScenePresence presence = Scene.GetScenePresence(client.AgentId);
3442 if (presence != null)
3443 {
3444 return GetPriorityByFrontBack(presence.CameraPosition, presence.CameraAtAxis);
3445 }
3446 return double.NaN;
3447 }
3448
3440 public double GetPriorityByDistance(Vector3 position) 3449 public double GetPriorityByDistance(Vector3 position)
3441 { 3450 {
3442 return Vector3.Distance(AbsolutePosition, position); 3451 return Vector3.Distance(AbsolutePosition, position);
@@ -3466,5 +3475,21 @@ namespace OpenSim.Region.Framework.Scenes
3466 else 3475 else
3467 return double.MinValue; 3476 return double.MinValue;
3468 } 3477 }
3478
3479 public double GetPriorityByFrontBack(Vector3 camPosition, Vector3 camAtAxis)
3480 {
3481 // Distance
3482 double priority = Vector3.Distance(camPosition, AbsolutePosition);
3483
3484 // Scale
3485 //priority -= GroupScale().Length();
3486
3487 // Plane equation
3488 float d = -Vector3.Dot(camPosition, camAtAxis);
3489 float p = Vector3.Dot(camAtAxis, AbsolutePosition) + d;
3490 if (p < 0.0f) priority *= 2.0f;
3491
3492 return priority;
3493 }
3469 } 3494 }
3470} 3495}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 5f46f6f..7d889ee 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -102,16 +102,16 @@ namespace OpenSim.Region.Framework.Scenes
102 102
103 #region Fields 103 #region Fields
104 104
105 public bool AllowedDrop = false; 105 public bool AllowedDrop;
106 106
107 [XmlIgnore] 107 [XmlIgnore]
108 public bool DIE_AT_EDGE = false; 108 public bool DIE_AT_EDGE;
109 109
110 // TODO: This needs to be persisted in next XML version update! 110 // TODO: This needs to be persisted in next XML version update!
111 [XmlIgnore] 111 [XmlIgnore]
112 public int[] PayPrice = {-2,-2,-2,-2,-2}; 112 public readonly int[] PayPrice = {-2,-2,-2,-2,-2};
113 [XmlIgnore] 113 [XmlIgnore]
114 public PhysicsActor PhysActor = null; 114 public PhysicsActor PhysActor;
115 115
116 //Xantor 20080528 Sound stuff: 116 //Xantor 20080528 Sound stuff:
117 // Note: This isn't persisted in the database right now, as the fields for that aren't just there yet. 117 // Note: This isn't persisted in the database right now, as the fields for that aren't just there yet.
@@ -130,55 +130,56 @@ namespace OpenSim.Region.Framework.Scenes
130 public double SoundRadius; 130 public double SoundRadius;
131 131
132 [XmlIgnore] 132 [XmlIgnore]
133 public uint TimeStampFull = 0; 133 public uint TimeStampFull;
134 134
135 [XmlIgnore] 135 [XmlIgnore]
136 public uint TimeStampLastActivity = 0; // Will be used for AutoReturn 136 public uint TimeStampLastActivity; // Will be used for AutoReturn
137 137
138 [XmlIgnore] 138 [XmlIgnore]
139 public uint TimeStampTerse = 0; 139 public uint TimeStampTerse;
140 140
141 [XmlIgnore] 141 [XmlIgnore]
142 public UUID FromItemID = UUID.Zero; 142 public UUID FromItemID;
143 143
144 /// <value> 144 /// <value>
145 /// The UUID of the user inventory item from which this object was rezzed if this is a root part. 145 /// The UUID of the user inventory item from which this object was rezzed if this is a root part.
146 /// If UUID.Zero then either this is not a root part or there is no connection with a user inventory item. 146 /// If UUID.Zero then either this is not a root part or there is no connection with a user inventory item.
147 /// </value> 147 /// </value>
148 private UUID m_fromUserInventoryItemID = UUID.Zero; 148 private UUID m_fromUserInventoryItemID;
149 149
150 [XmlIgnore] 150 [XmlIgnore]
151 public UUID FromUserInventoryItemID 151 public UUID FromUserInventoryItemID
152 { 152 {
153 get { return m_fromUserInventoryItemID; } 153 get { return m_fromUserInventoryItemID; }
154 } 154 }
155 155
156 [XmlIgnore] 156 [XmlIgnore]
157 public bool IsAttachment = false; 157 public bool IsAttachment;
158 158
159 [XmlIgnore] 159 [XmlIgnore]
160 public scriptEvents AggregateScriptEvents = 0; 160 public scriptEvents AggregateScriptEvents;
161 161
162 [XmlIgnore] 162 [XmlIgnore]
163 public UUID AttachedAvatar = UUID.Zero; 163 public UUID AttachedAvatar;
164 164
165 [XmlIgnore] 165 [XmlIgnore]
166 public Vector3 AttachedPos = Vector3.Zero; 166 public Vector3 AttachedPos;
167 167
168 [XmlIgnore] 168 [XmlIgnore]
169 public uint AttachmentPoint = (byte)0; 169 public uint AttachmentPoint;
170 170
171 [XmlIgnore] 171 [XmlIgnore]
172 public PhysicsVector RotationAxis = new PhysicsVector(1f,1f,1f); 172 public Vector3 RotationAxis = Vector3.One;
173 173
174 [XmlIgnore] 174 [XmlIgnore]
175 public bool VolumeDetectActive = false; // XmlIgnore set to avoid problems with persistance until I come to care for this 175 public bool VolumeDetectActive; // XmlIgnore set to avoid problems with persistance until I come to care for this
176 // Certainly this must be a persistant setting finally 176 // Certainly this must be a persistant setting finally
177 177
178 [XmlIgnore] 178 [XmlIgnore]
179 public bool IsWaitingForFirstSpinUpdatePacket = false; 179 public bool IsWaitingForFirstSpinUpdatePacket;
180
180 [XmlIgnore] 181 [XmlIgnore]
181 public Quaternion SpinOldOrientation = new Quaternion(); 182 public Quaternion SpinOldOrientation = Quaternion.Identity;
182 183
183 /// <summary> 184 /// <summary>
184 /// This part's inventory 185 /// This part's inventory
@@ -191,34 +192,32 @@ namespace OpenSim.Region.Framework.Scenes
191 protected SceneObjectPartInventory m_inventory; 192 protected SceneObjectPartInventory m_inventory;
192 193
193 [XmlIgnore] 194 [XmlIgnore]
194 public bool Undoing = false; 195 public bool Undoing;
195 196
196 [XmlIgnore] 197 [XmlIgnore]
197 private PrimFlags LocalFlags = 0; 198 private PrimFlags LocalFlags;
198 [XmlIgnore] 199 [XmlIgnore]
199 private float m_damage = -1.0f; 200 private float m_damage = -1.0f;
200 private byte[] m_TextureAnimation; 201 private byte[] m_TextureAnimation;
201 private byte m_clickAction = 0; 202 private byte m_clickAction;
202 private Color m_color = Color.Black; 203 private Color m_color = Color.Black;
203 private string m_description = String.Empty; 204 private string m_description = String.Empty;
204 private readonly List<uint> m_lastColliders = new List<uint>(); 205 private readonly List<uint> m_lastColliders = new List<uint>();
205 // private PhysicsVector m_lastRotationalVelocity = PhysicsVector.Zero; 206 private int m_linkNum;
206 private int m_linkNum = 0;
207 [XmlIgnore] 207 [XmlIgnore]
208 private int m_scriptAccessPin = 0; 208 private int m_scriptAccessPin;
209 [XmlIgnore] 209 [XmlIgnore]
210 private readonly Dictionary<UUID, scriptEvents> m_scriptEvents = new Dictionary<UUID, scriptEvents>(); 210 private readonly Dictionary<UUID, scriptEvents> m_scriptEvents = new Dictionary<UUID, scriptEvents>();
211 private string m_sitName = String.Empty; 211 private string m_sitName = String.Empty;
212 private Quaternion m_sitTargetOrientation = Quaternion.Identity; 212 private Quaternion m_sitTargetOrientation = Quaternion.Identity;
213 private Vector3 m_sitTargetPosition = Vector3.Zero; 213 private Vector3 m_sitTargetPosition;
214 private string m_sitAnimation = "SIT"; 214 private string m_sitAnimation = "SIT";
215 private string m_text = String.Empty; 215 private string m_text = String.Empty;
216 private string m_touchName = String.Empty; 216 private string m_touchName = String.Empty;
217 private readonly UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5); 217 private readonly UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5);
218 private UUID _creatorID; 218 private UUID _creatorID;
219 219
220 220 private bool m_passTouches;
221 private bool m_passTouches = false;
222 221
223 /// <summary> 222 /// <summary>
224 /// Only used internally to schedule client updates. 223 /// Only used internally to schedule client updates.
@@ -236,28 +235,34 @@ namespace OpenSim.Region.Framework.Scenes
236 //unkown if this will be kept, added as a way of removing the group position from the group class 235 //unkown if this will be kept, added as a way of removing the group position from the group class
237 protected Vector3 m_groupPosition; 236 protected Vector3 m_groupPosition;
238 protected uint m_localId; 237 protected uint m_localId;
239 protected Material m_material = (Material)3; // Wood 238 protected Material m_material = OpenMetaverse.Material.Wood;
240 protected string m_name; 239 protected string m_name;
241 protected Vector3 m_offsetPosition; 240 protected Vector3 m_offsetPosition;
242 241
243 // FIXME, TODO, ERROR: 'ParentGroup' can't be in here, move it out. 242 // FIXME, TODO, ERROR: 'ParentGroup' can't be in here, move it out.
244 protected SceneObjectGroup m_parentGroup; 243 protected SceneObjectGroup m_parentGroup;
245 protected byte[] m_particleSystem = new byte[0]; 244 protected byte[] m_particleSystem = Utils.EmptyBytes;
246 protected ulong m_regionHandle; 245 protected ulong m_regionHandle;
247 protected Quaternion m_rotationOffset; 246 protected Quaternion m_rotationOffset;
248 protected PrimitiveBaseShape m_shape = null; 247 protected PrimitiveBaseShape m_shape;
249 protected UUID m_uuid; 248 protected UUID m_uuid;
250 protected Vector3 m_velocity; 249 protected Vector3 m_velocity;
251 250
251 protected Vector3 m_lastPosition;
252 protected Quaternion m_lastRotation;
253 protected Vector3 m_lastVelocity;
254 protected Vector3 m_lastAcceleration;
255 protected Vector3 m_lastAngularVelocity;
256
252 // TODO: Those have to be changed into persistent properties at some later point, 257 // TODO: Those have to be changed into persistent properties at some later point,
253 // or sit-camera on vehicles will break on sim-crossing. 258 // or sit-camera on vehicles will break on sim-crossing.
254 private Vector3 m_cameraEyeOffset = new Vector3(0.0f, 0.0f, 0.0f); 259 private Vector3 m_cameraEyeOffset;
255 private Vector3 m_cameraAtOffset = new Vector3(0.0f, 0.0f, 0.0f); 260 private Vector3 m_cameraAtOffset;
256 private bool m_forceMouselook = false; 261 private bool m_forceMouselook;
257 262
258 // TODO: Collision sound should have default. 263 // TODO: Collision sound should have default.
259 private UUID m_collisionSound = UUID.Zero; 264 private UUID m_collisionSound;
260 private float m_collisionSoundVolume = 0.0f; 265 private float m_collisionSoundVolume;
261 266
262 #endregion Fields 267 #endregion Fields
263 268
@@ -269,9 +274,9 @@ namespace OpenSim.Region.Framework.Scenes
269 public SceneObjectPart() 274 public SceneObjectPart()
270 { 275 {
271 // It's not necessary to persist this 276 // It's not necessary to persist this
272 m_TextureAnimation = new byte[0]; 277 m_TextureAnimation = Utils.EmptyBytes;
273 m_particleSystem = new byte[0]; 278 m_particleSystem = Utils.EmptyBytes;
274 Rezzed = DateTime.Now; 279 Rezzed = DateTime.UtcNow;
275 280
276 m_inventory = new SceneObjectPartInventory(this); 281 m_inventory = new SceneObjectPartInventory(this);
277 } 282 }
@@ -290,8 +295,8 @@ namespace OpenSim.Region.Framework.Scenes
290 { 295 {
291 m_name = "Primitive"; 296 m_name = "Primitive";
292 297
293 Rezzed = DateTime.Now; 298 Rezzed = DateTime.UtcNow;
294 _creationDate = (Int32) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; 299 _creationDate = (int)Utils.DateTimeToUnixTime(Rezzed);
295 _ownerID = ownerID; 300 _ownerID = ownerID;
296 _creatorID = _ownerID; 301 _creatorID = _ownerID;
297 _lastOwnerID = UUID.Zero; 302 _lastOwnerID = UUID.Zero;
@@ -299,19 +304,19 @@ namespace OpenSim.Region.Framework.Scenes
299 Shape = shape; 304 Shape = shape;
300 // Todo: Add More Object Parameter from above! 305 // Todo: Add More Object Parameter from above!
301 _ownershipCost = 0; 306 _ownershipCost = 0;
302 _objectSaleType = (byte) 0; 307 _objectSaleType = 0;
303 _salePrice = 0; 308 _salePrice = 0;
304 _category = (uint) 0; 309 _category = 0;
305 _lastOwnerID = _creatorID; 310 _lastOwnerID = _creatorID;
306 // End Todo: /// 311 // End Todo: ///
307 GroupPosition = groupPosition; 312 GroupPosition = groupPosition;
308 OffsetPosition = offsetPosition; 313 OffsetPosition = offsetPosition;
309 RotationOffset = rotationOffset; 314 RotationOffset = rotationOffset;
310 Velocity = new Vector3(0, 0, 0); 315 Velocity = Vector3.Zero;
311 AngularVelocity = new Vector3(0, 0, 0); 316 AngularVelocity = Vector3.Zero;
312 Acceleration = new Vector3(0, 0, 0); 317 Acceleration = Vector3.Zero;
313 m_TextureAnimation = new byte[0]; 318 m_TextureAnimation = Utils.EmptyBytes;
314 m_particleSystem = new byte[0]; 319 m_particleSystem = Utils.EmptyBytes;
315 320
316 // Prims currently only contain a single folder (Contents). From looking at the Second Life protocol, 321 // Prims currently only contain a single folder (Contents). From looking at the Second Life protocol,
317 // this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from 322 // this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from
@@ -532,13 +537,13 @@ namespace OpenSim.Region.Framework.Scenes
532 // Root prim actually goes at Position 537 // Root prim actually goes at Position
533 if (_parentID == 0) 538 if (_parentID == 0)
534 { 539 {
535 PhysActor.Position = new PhysicsVector(value.X, value.Y, value.Z); 540 PhysActor.Position = value;
536 } 541 }
537 else 542 else
538 { 543 {
539 // To move the child prim in respect to the group position and rotation we have to calculate 544 // To move the child prim in respect to the group position and rotation we have to calculate
540 Vector3 resultingposition = GetWorldPosition(); 545 Vector3 resultingposition = GetWorldPosition();
541 PhysActor.Position = new PhysicsVector(resultingposition.X, resultingposition.Y, resultingposition.Z); 546 PhysActor.Position = resultingposition;
542 Quaternion resultingrot = GetWorldRotation(); 547 Quaternion resultingrot = GetWorldRotation();
543 PhysActor.Orientation = resultingrot; 548 PhysActor.Orientation = resultingrot;
544 } 549 }
@@ -580,7 +585,7 @@ namespace OpenSim.Region.Framework.Scenes
580 if (_parentID != 0 && PhysActor != null) 585 if (_parentID != 0 && PhysActor != null)
581 { 586 {
582 Vector3 resultingposition = GetWorldPosition(); 587 Vector3 resultingposition = GetWorldPosition();
583 PhysActor.Position = new PhysicsVector(resultingposition.X, resultingposition.Y, resultingposition.Z); 588 PhysActor.Position = resultingposition;
584 Quaternion resultingrot = GetWorldRotation(); 589 Quaternion resultingrot = GetWorldRotation();
585 PhysActor.Orientation = resultingrot; 590 PhysActor.Orientation = resultingrot;
586 591
@@ -670,7 +675,7 @@ namespace OpenSim.Region.Framework.Scenes
670 { 675 {
671 if (PhysActor.IsPhysical) 676 if (PhysActor.IsPhysical)
672 { 677 {
673 PhysActor.Velocity = new PhysicsVector(value.X, value.Y, value.Z); 678 PhysActor.Velocity = value;
674 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); 679 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
675 } 680 }
676 } 681 }
@@ -812,7 +817,7 @@ if (m_shape != null) {
812 { 817 {
813 if (m_parentGroup.Scene.PhysicsScene != null) 818 if (m_parentGroup.Scene.PhysicsScene != null)
814 { 819 {
815 PhysActor.Size = new PhysicsVector(m_shape.Scale.X, m_shape.Scale.Y, m_shape.Scale.Z); 820 PhysActor.Size = m_shape.Scale;
816 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); 821 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
817 } 822 }
818 } 823 }
@@ -1077,8 +1082,8 @@ if (m_shape != null) {
1077 1082
1078 private void SendObjectPropertiesToClient(UUID AgentID) 1083 private void SendObjectPropertiesToClient(UUID AgentID)
1079 { 1084 {
1080 List<ScenePresence> avatars = m_parentGroup.Scene.GetScenePresences(); 1085 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
1081 for (int i = 0; i < avatars.Count; i++) 1086 for (int i = 0; i < avatars.Length; i++)
1082 { 1087 {
1083 // Ugly reference :( 1088 // Ugly reference :(
1084 if (avatars[i].UUID == AgentID) 1089 if (avatars[i].UUID == AgentID)
@@ -1140,8 +1145,8 @@ if (m_shape != null) {
1140 /// </summary> 1145 /// </summary>
1141 public void AddFullUpdateToAllAvatars() 1146 public void AddFullUpdateToAllAvatars()
1142 { 1147 {
1143 List<ScenePresence> avatars = m_parentGroup.Scene.GetScenePresences(); 1148 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
1144 for (int i = 0; i < avatars.Count; i++) 1149 for (int i = 0; i < avatars.Length; i++)
1145 { 1150 {
1146 avatars[i].SceneViewer.QueuePartForUpdate(this); 1151 avatars[i].SceneViewer.QueuePartForUpdate(this);
1147 } 1152 }
@@ -1165,8 +1170,8 @@ if (m_shape != null) {
1165 /// Terse updates 1170 /// Terse updates
1166 public void AddTerseUpdateToAllAvatars() 1171 public void AddTerseUpdateToAllAvatars()
1167 { 1172 {
1168 List<ScenePresence> avatars = m_parentGroup.Scene.GetScenePresences(); 1173 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
1169 for (int i = 0; i < avatars.Count; i++) 1174 for (int i = 0; i < avatars.Length; i++)
1170 { 1175 {
1171 avatars[i].SceneViewer.QueuePartForUpdate(this); 1176 avatars[i].SceneViewer.QueuePartForUpdate(this);
1172 } 1177 }
@@ -1220,7 +1225,7 @@ if (m_shape != null) {
1220 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param> 1225 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param>
1221 public void ApplyImpulse(Vector3 impulsei, bool localGlobalTF) 1226 public void ApplyImpulse(Vector3 impulsei, bool localGlobalTF)
1222 { 1227 {
1223 PhysicsVector impulse = new PhysicsVector(impulsei.X, impulsei.Y, impulsei.Z); 1228 Vector3 impulse = impulsei;
1224 1229
1225 if (localGlobalTF) 1230 if (localGlobalTF)
1226 { 1231 {
@@ -1228,7 +1233,7 @@ if (m_shape != null) {
1228 Quaternion AXgrot = grot; 1233 Quaternion AXgrot = grot;
1229 Vector3 AXimpulsei = impulsei; 1234 Vector3 AXimpulsei = impulsei;
1230 Vector3 newimpulse = AXimpulsei * AXgrot; 1235 Vector3 newimpulse = AXimpulsei * AXgrot;
1231 impulse = new PhysicsVector(newimpulse.X, newimpulse.Y, newimpulse.Z); 1236 impulse = newimpulse;
1232 } 1237 }
1233 1238
1234 if (m_parentGroup != null) 1239 if (m_parentGroup != null)
@@ -1246,7 +1251,7 @@ if (m_shape != null) {
1246 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param> 1251 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param>
1247 public void ApplyAngularImpulse(Vector3 impulsei, bool localGlobalTF) 1252 public void ApplyAngularImpulse(Vector3 impulsei, bool localGlobalTF)
1248 { 1253 {
1249 PhysicsVector impulse = new PhysicsVector(impulsei.X, impulsei.Y, impulsei.Z); 1254 Vector3 impulse = impulsei;
1250 1255
1251 if (localGlobalTF) 1256 if (localGlobalTF)
1252 { 1257 {
@@ -1254,7 +1259,7 @@ if (m_shape != null) {
1254 Quaternion AXgrot = grot; 1259 Quaternion AXgrot = grot;
1255 Vector3 AXimpulsei = impulsei; 1260 Vector3 AXimpulsei = impulsei;
1256 Vector3 newimpulse = AXimpulsei * AXgrot; 1261 Vector3 newimpulse = AXimpulsei * AXgrot;
1257 impulse = new PhysicsVector(newimpulse.X, newimpulse.Y, newimpulse.Z); 1262 impulse = newimpulse;
1258 } 1263 }
1259 1264
1260 if (m_parentGroup != null) 1265 if (m_parentGroup != null)
@@ -1272,7 +1277,7 @@ if (m_shape != null) {
1272 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param> 1277 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param>
1273 public void SetAngularImpulse(Vector3 impulsei, bool localGlobalTF) 1278 public void SetAngularImpulse(Vector3 impulsei, bool localGlobalTF)
1274 { 1279 {
1275 PhysicsVector impulse = new PhysicsVector(impulsei.X, impulsei.Y, impulsei.Z); 1280 Vector3 impulse = impulsei;
1276 1281
1277 if (localGlobalTF) 1282 if (localGlobalTF)
1278 { 1283 {
@@ -1280,7 +1285,7 @@ if (m_shape != null) {
1280 Quaternion AXgrot = grot; 1285 Quaternion AXgrot = grot;
1281 Vector3 AXimpulsei = impulsei; 1286 Vector3 AXimpulsei = impulsei;
1282 Vector3 newimpulse = AXimpulsei * AXgrot; 1287 Vector3 newimpulse = AXimpulsei * AXgrot;
1283 impulse = new PhysicsVector(newimpulse.X, newimpulse.Y, newimpulse.Z); 1288 impulse = newimpulse;
1284 } 1289 }
1285 1290
1286 if (m_parentGroup != null) 1291 if (m_parentGroup != null)
@@ -1328,8 +1333,8 @@ if (m_shape != null) {
1328 PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( 1333 PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape(
1329 Name, 1334 Name,
1330 Shape, 1335 Shape,
1331 new PhysicsVector(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z), 1336 AbsolutePosition,
1332 new PhysicsVector(Scale.X, Scale.Y, Scale.Z), 1337 Scale,
1333 RotationOffset, 1338 RotationOffset,
1334 RigidBody); 1339 RigidBody);
1335 1340
@@ -1518,7 +1523,7 @@ if (m_shape != null) {
1518 PhysicsJoint joint; 1523 PhysicsJoint joint;
1519 1524
1520 joint = m_parentGroup.Scene.PhysicsScene.RequestJointCreation(Name, jointType, 1525 joint = m_parentGroup.Scene.PhysicsScene.RequestJointCreation(Name, jointType,
1521 new PhysicsVector(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z), 1526 AbsolutePosition,
1522 this.RotationOffset, 1527 this.RotationOffset,
1523 Description, 1528 Description,
1524 bodyNames, 1529 bodyNames,
@@ -1703,12 +1708,12 @@ if (m_shape != null) {
1703 } 1708 }
1704 } 1709 }
1705 1710
1706 public PhysicsVector GetForce() 1711 public Vector3 GetForce()
1707 { 1712 {
1708 if (PhysActor != null) 1713 if (PhysActor != null)
1709 return PhysActor.Force; 1714 return PhysActor.Force;
1710 else 1715 else
1711 return new PhysicsVector(); 1716 return Vector3.Zero;
1712 } 1717 }
1713 1718
1714 public void GetProperties(IClientAPI client) 1719 public void GetProperties(IClientAPI client)
@@ -1894,24 +1899,24 @@ if (m_shape != null) {
1894 } 1899 }
1895 else 1900 else
1896 { 1901 {
1897 List<ScenePresence> avlist = m_parentGroup.Scene.GetScenePresences(); 1902 ScenePresence[] avlist = m_parentGroup.Scene.GetScenePresences();
1898 if (avlist != null) 1903
1904 for (int i = 0; i < avlist.Length; i++)
1899 { 1905 {
1900 foreach (ScenePresence av in avlist) 1906 ScenePresence av = avlist[i];
1907
1908 if (av.LocalId == localId)
1901 { 1909 {
1902 if (av.LocalId == localId) 1910 DetectedObject detobj = new DetectedObject();
1903 { 1911 detobj.keyUUID = av.UUID;
1904 DetectedObject detobj = new DetectedObject(); 1912 detobj.nameStr = av.ControllingClient.Name;
1905 detobj.keyUUID = av.UUID; 1913 detobj.ownerUUID = av.UUID;
1906 detobj.nameStr = av.ControllingClient.Name; 1914 detobj.posVector = av.AbsolutePosition;
1907 detobj.ownerUUID = av.UUID; 1915 detobj.rotQuat = av.Rotation;
1908 detobj.posVector = av.AbsolutePosition; 1916 detobj.velVector = av.Velocity;
1909 detobj.rotQuat = av.Rotation; 1917 detobj.colliderType = 0;
1910 detobj.velVector = av.Velocity; 1918 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
1911 detobj.colliderType = 0; 1919 colliding.Add(detobj);
1912 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
1913 colliding.Add(detobj);
1914 }
1915 } 1920 }
1916 } 1921 }
1917 } 1922 }
@@ -1965,26 +1970,25 @@ if (m_shape != null) {
1965 } 1970 }
1966 else 1971 else
1967 { 1972 {
1968 List<ScenePresence> avlist = m_parentGroup.Scene.GetScenePresences(); 1973 ScenePresence[] avlist = m_parentGroup.Scene.GetScenePresences();
1969 if (avlist != null) 1974
1975 for (int i = 0; i < avlist.Length; i++)
1970 { 1976 {
1971 foreach (ScenePresence av in avlist) 1977 ScenePresence av = avlist[i];
1978
1979 if (av.LocalId == localId)
1972 { 1980 {
1973 if (av.LocalId == localId) 1981 DetectedObject detobj = new DetectedObject();
1974 { 1982 detobj.keyUUID = av.UUID;
1975 DetectedObject detobj = new DetectedObject(); 1983 detobj.nameStr = av.Name;
1976 detobj.keyUUID = av.UUID; 1984 detobj.ownerUUID = av.UUID;
1977 detobj.nameStr = av.Name; 1985 detobj.posVector = av.AbsolutePosition;
1978 detobj.ownerUUID = av.UUID; 1986 detobj.rotQuat = av.Rotation;
1979 detobj.posVector = av.AbsolutePosition; 1987 detobj.velVector = av.Velocity;
1980 detobj.rotQuat = av.Rotation; 1988 detobj.colliderType = 0;
1981 detobj.velVector = av.Velocity; 1989 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
1982 detobj.colliderType = 0; 1990 colliding.Add(detobj);
1983 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
1984 colliding.Add(detobj);
1985 }
1986 } 1991 }
1987
1988 } 1992 }
1989 } 1993 }
1990 } 1994 }
@@ -2035,24 +2039,24 @@ if (m_shape != null) {
2035 } 2039 }
2036 else 2040 else
2037 { 2041 {
2038 List<ScenePresence> avlist = m_parentGroup.Scene.GetScenePresences(); 2042 ScenePresence[] avlist = m_parentGroup.Scene.GetScenePresences();
2039 if (avlist != null) 2043
2044 for (int i = 0; i < avlist.Length; i++)
2040 { 2045 {
2041 foreach (ScenePresence av in avlist) 2046 ScenePresence av = avlist[i];
2047
2048 if (av.LocalId == localId)
2042 { 2049 {
2043 if (av.LocalId == localId) 2050 DetectedObject detobj = new DetectedObject();
2044 { 2051 detobj.keyUUID = av.UUID;
2045 DetectedObject detobj = new DetectedObject(); 2052 detobj.nameStr = av.Name;
2046 detobj.keyUUID = av.UUID; 2053 detobj.ownerUUID = av.UUID;
2047 detobj.nameStr = av.Name; 2054 detobj.posVector = av.AbsolutePosition;
2048 detobj.ownerUUID = av.UUID; 2055 detobj.rotQuat = av.Rotation;
2049 detobj.posVector = av.AbsolutePosition; 2056 detobj.velVector = av.Velocity;
2050 detobj.rotQuat = av.Rotation; 2057 detobj.colliderType = 0;
2051 detobj.velVector = av.Velocity; 2058 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2052 detobj.colliderType = 0; 2059 colliding.Add(detobj);
2053 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
2054 colliding.Add(detobj);
2055 }
2056 } 2060 }
2057 } 2061 }
2058 } 2062 }
@@ -2074,7 +2078,7 @@ if (m_shape != null) {
2074 } 2078 }
2075 } 2079 }
2076 2080
2077 public void PhysicsOutOfBounds(PhysicsVector pos) 2081 public void PhysicsOutOfBounds(Vector3 pos)
2078 { 2082 {
2079 m_log.Error("[PHYSICS]: Physical Object went out of bounds."); 2083 m_log.Error("[PHYSICS]: Physical Object went out of bounds.");
2080 2084
@@ -2317,8 +2321,8 @@ if (m_shape != null) {
2317 /// </summary> 2321 /// </summary>
2318 public void SendFullUpdateToAllClients() 2322 public void SendFullUpdateToAllClients()
2319 { 2323 {
2320 List<ScenePresence> avatars = m_parentGroup.Scene.GetScenePresences(); 2324 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
2321 for (int i = 0; i < avatars.Count; i++) 2325 for (int i = 0; i < avatars.Length; i++)
2322 { 2326 {
2323 // Ugly reference :( 2327 // Ugly reference :(
2324 m_parentGroup.SendPartFullUpdate(avatars[i].ControllingClient, this, 2328 m_parentGroup.SendPartFullUpdate(avatars[i].ControllingClient, this,
@@ -2328,8 +2332,8 @@ if (m_shape != null) {
2328 2332
2329 public void SendFullUpdateToAllClientsExcept(UUID agentID) 2333 public void SendFullUpdateToAllClientsExcept(UUID agentID)
2330 { 2334 {
2331 List<ScenePresence> avatars = m_parentGroup.Scene.GetScenePresences(); 2335 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
2332 for (int i = 0; i < avatars.Count; i++) 2336 for (int i = 0; i < avatars.Length; i++)
2333 { 2337 {
2334 // Ugly reference :( 2338 // Ugly reference :(
2335 if (avatars[i].UUID != agentID) 2339 if (avatars[i].UUID != agentID)
@@ -2394,18 +2398,36 @@ if (m_shape != null) {
2394 /// </summary> 2398 /// </summary>
2395 public void SendScheduledUpdates() 2399 public void SendScheduledUpdates()
2396 { 2400 {
2397 if (m_updateFlag == 1) //some change has been made so update the clients 2401 const float VELOCITY_TOLERANCE = 0.01f;
2402 const float POSITION_TOLERANCE = 0.1f;
2403
2404 if (m_updateFlag == 1)
2398 { 2405 {
2399 AddTerseUpdateToAllAvatars(); 2406 // Throw away duplicate or insignificant updates
2400 ClearUpdateSchedule(); 2407 if (RotationOffset != m_lastRotation ||
2408 Acceleration != m_lastAcceleration ||
2409 (Velocity - m_lastVelocity).Length() > VELOCITY_TOLERANCE ||
2410 (RotationalVelocity - m_lastAngularVelocity).Length() > VELOCITY_TOLERANCE ||
2411 (OffsetPosition - m_lastPosition).Length() > POSITION_TOLERANCE)
2412 {
2413 AddTerseUpdateToAllAvatars();
2414 ClearUpdateSchedule();
2401 2415
2402 // This causes the Scene to 'poll' physical objects every couple of frames 2416 // This causes the Scene to 'poll' physical objects every couple of frames
2403 // bad, so it's been replaced by an event driven method. 2417 // bad, so it's been replaced by an event driven method.
2404 //if ((ObjectFlags & (uint)PrimFlags.Physics) != 0) 2418 //if ((ObjectFlags & (uint)PrimFlags.Physics) != 0)
2405 //{ 2419 //{
2406 // Only send the constant terse updates on physical objects! 2420 // Only send the constant terse updates on physical objects!
2407 //ScheduleTerseUpdate(); 2421 //ScheduleTerseUpdate();
2408 //} 2422 //}
2423
2424 // Update the "last" values
2425 m_lastPosition = OffsetPosition;
2426 m_lastRotation = RotationOffset;
2427 m_lastVelocity = Velocity;
2428 m_lastAcceleration = Acceleration;
2429 m_lastAngularVelocity = RotationalVelocity;
2430 }
2409 } 2431 }
2410 else 2432 else
2411 { 2433 {
@@ -2472,8 +2494,8 @@ if (m_shape != null) {
2472 /// </summary> 2494 /// </summary>
2473 public void SendTerseUpdateToAllClients() 2495 public void SendTerseUpdateToAllClients()
2474 { 2496 {
2475 List<ScenePresence> avatars = m_parentGroup.Scene.GetScenePresences(); 2497 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
2476 for (int i = 0; i < avatars.Count; i++) 2498 for (int i = 0; i < avatars.Length; i++)
2477 { 2499 {
2478 SendTerseUpdateToClient(avatars[i].ControllingClient); 2500 SendTerseUpdateToClient(avatars[i].ControllingClient);
2479 } 2501 }
@@ -2547,7 +2569,7 @@ if (m_shape != null) {
2547 } 2569 }
2548 } 2570 }
2549 2571
2550 public void SetForce(PhysicsVector force) 2572 public void SetForce(Vector3 force)
2551 { 2573 {
2552 if (PhysActor != null) 2574 if (PhysActor != null)
2553 { 2575 {
@@ -2571,7 +2593,7 @@ if (m_shape != null) {
2571 } 2593 }
2572 } 2594 }
2573 2595
2574 public void SetVehicleVectorParam(int param, PhysicsVector value) 2596 public void SetVehicleVectorParam(int param, Vector3 value)
2575 { 2597 {
2576 if (PhysActor != null) 2598 if (PhysActor != null)
2577 { 2599 {
@@ -3420,8 +3442,8 @@ if (m_shape != null) {
3420 PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( 3442 PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape(
3421 Name, 3443 Name,
3422 Shape, 3444 Shape,
3423 new PhysicsVector(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z), 3445 AbsolutePosition,
3424 new PhysicsVector(Scale.X, Scale.Y, Scale.Z), 3446 Scale,
3425 RotationOffset, 3447 RotationOffset,
3426 UsePhysics); 3448 UsePhysics);
3427 3449
@@ -3561,7 +3583,7 @@ if (m_shape != null) {
3561 // in SL. 3583 // in SL.
3562 // 3584 //
3563 if (ParentGroup.RootPart != this) 3585 if (ParentGroup.RootPart != this)
3564 ParentGroup.RootPart.Rezzed = DateTime.Now; 3586 ParentGroup.RootPart.Rezzed = DateTime.UtcNow;
3565 3587
3566 ParentGroup.HasGroupChanged = true; 3588 ParentGroup.HasGroupChanged = true;
3567 ScheduleFullUpdate(); 3589 ScheduleFullUpdate();
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index d7113bf..87fac0c 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -93,12 +93,13 @@ namespace OpenSim.Region.Framework.Scenes
93 public Vector3 lastKnownAllowedPosition; 93 public Vector3 lastKnownAllowedPosition;
94 public bool sentMessageAboutRestrictedParcelFlyingDown; 94 public bool sentMessageAboutRestrictedParcelFlyingDown;
95 95
96 96 private Vector3 m_lastPosition;
97 private Quaternion m_lastRotation;
98 private Vector3 m_lastVelocity;
97 99
98 private bool m_updateflag; 100 private bool m_updateflag;
99 private byte m_movementflag; 101 private byte m_movementflag;
100 private readonly List<NewForce> m_forcesList = new List<NewForce>(); 102 private readonly List<NewForce> m_forcesList = new List<NewForce>();
101 private short m_updateCount;
102 private uint m_requestedSitTargetID; 103 private uint m_requestedSitTargetID;
103 private UUID m_requestedSitTargetUUID = UUID.Zero; 104 private UUID m_requestedSitTargetUUID = UUID.Zero;
104 private SendCourseLocationsMethod m_sendCourseLocationsMethod; 105 private SendCourseLocationsMethod m_sendCourseLocationsMethod;
@@ -145,12 +146,9 @@ namespace OpenSim.Region.Framework.Scenes
145 public string JID = string.Empty; 146 public string JID = string.Empty;
146 147
147 // Agent moves with a PID controller causing a force to be exerted. 148 // Agent moves with a PID controller causing a force to be exerted.
148 private bool m_newForce;
149 private bool m_newCoarseLocations = true; 149 private bool m_newCoarseLocations = true;
150 private float m_health = 100f; 150 private float m_health = 100f;
151 151
152 private Vector3 m_lastVelocity = Vector3.Zero;
153
154 // Default AV Height 152 // Default AV Height
155 private float m_avHeight = 127.0f; 153 private float m_avHeight = 127.0f;
156 154
@@ -158,16 +156,6 @@ namespace OpenSim.Region.Framework.Scenes
158 protected ulong crossingFromRegion; 156 protected ulong crossingFromRegion;
159 157
160 private readonly Vector3[] Dir_Vectors = new Vector3[6]; 158 private readonly Vector3[] Dir_Vectors = new Vector3[6];
161
162 /// <value>
163 /// The avatar position last sent to clients
164 /// </value>
165 private Vector3 lastPhysPos = Vector3.Zero;
166
167 /// <value>
168 /// The avatar body rotation last sent to clients
169 /// </value>
170 private Quaternion lastPhysRot = Quaternion.Identity;
171 159
172 // Position of agent's camera in world (region cordinates) 160 // Position of agent's camera in world (region cordinates)
173 protected Vector3 m_CameraCenter = Vector3.Zero; 161 protected Vector3 m_CameraCenter = Vector3.Zero;
@@ -297,6 +285,21 @@ namespace OpenSim.Region.Framework.Scenes
297 get { return Util.Axes2Rot(m_CameraAtAxis, m_CameraLeftAxis, m_CameraUpAxis); } 285 get { return Util.Axes2Rot(m_CameraAtAxis, m_CameraLeftAxis, m_CameraUpAxis); }
298 } 286 }
299 287
288 public Vector3 CameraAtAxis
289 {
290 get { return m_CameraAtAxis; }
291 }
292
293 public Vector3 CameraLeftAxis
294 {
295 get { return m_CameraLeftAxis; }
296 }
297
298 public Vector3 CameraUpAxis
299 {
300 get { return m_CameraUpAxis; }
301 }
302
300 public Vector3 Lookat 303 public Vector3 Lookat
301 { 304 {
302 get 305 get
@@ -431,7 +434,7 @@ namespace OpenSim.Region.Framework.Scenes
431 { 434 {
432 lock (m_scene.SyncRoot) 435 lock (m_scene.SyncRoot)
433 { 436 {
434 m_physicsActor.Position = new PhysicsVector(value.X, value.Y, value.Z); 437 m_physicsActor.Position = value;
435 } 438 }
436 } 439 }
437 catch (Exception e) 440 catch (Exception e)
@@ -471,7 +474,7 @@ namespace OpenSim.Region.Framework.Scenes
471 { 474 {
472 lock (m_scene.SyncRoot) 475 lock (m_scene.SyncRoot)
473 { 476 {
474 m_physicsActor.Velocity = new PhysicsVector(value.X, value.Y, value.Z); 477 m_physicsActor.Velocity = value;
475 } 478 }
476 } 479 }
477 catch (Exception e) 480 catch (Exception e)
@@ -869,14 +872,16 @@ namespace OpenSim.Region.Framework.Scenes
869 872
870 m_isChildAgent = false; 873 m_isChildAgent = false;
871 874
872 List<ScenePresence> AnimAgents = m_scene.GetScenePresences(); 875 ScenePresence[] animAgents = m_scene.GetScenePresences();
873 foreach (ScenePresence p in AnimAgents) 876 for (int i = 0; i < animAgents.Length; i++)
874 { 877 {
875 if (p != this) 878 ScenePresence presence = animAgents[i];
876 p.SendAnimPackToClient(ControllingClient); 879
880 if (presence != this)
881 presence.SendAnimPackToClient(ControllingClient);
877 } 882 }
878 m_scene.EventManager.TriggerOnMakeRootAgent(this);
879 883
884 m_scene.EventManager.TriggerOnMakeRootAgent(this);
880 } 885 }
881 886
882 /// <summary> 887 /// <summary>
@@ -1041,7 +1046,7 @@ namespace OpenSim.Region.Framework.Scenes
1041 m_avHeight = height; 1046 m_avHeight = height;
1042 if (PhysicsActor != null && !IsChildAgent) 1047 if (PhysicsActor != null && !IsChildAgent)
1043 { 1048 {
1044 PhysicsVector SetSize = new PhysicsVector(0.45f, 0.6f, m_avHeight); 1049 Vector3 SetSize = new Vector3(0.45f, 0.6f, m_avHeight);
1045 PhysicsActor.Size = SetSize; 1050 PhysicsActor.Size = SetSize;
1046 } 1051 }
1047 } 1052 }
@@ -1106,18 +1111,18 @@ namespace OpenSim.Region.Framework.Scenes
1106 CameraConstraintActive = true; 1111 CameraConstraintActive = true;
1107 //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance); 1112 //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance);
1108 1113
1109 Vector3 normal = Vector3.Normalize(new Vector3(0,0,collisionPoint.Z) - collisionPoint); 1114 Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint);
1110 ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint))); 1115 ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint)));
1111 } 1116 }
1112 else 1117 else
1113 { 1118 {
1114 if (((Util.GetDistanceTo(lastPhysPos, AbsolutePosition) > 0.02) 1119 if ((m_pos - m_lastPosition).Length() > 0.02f ||
1115 || (Util.GetDistanceTo(m_lastVelocity, m_velocity) > 0.02) 1120 (m_velocity - m_lastVelocity).Length() > 0.02f ||
1116 || lastPhysRot != m_bodyRot)) 1121 m_bodyRot != m_lastRotation)
1117 { 1122 {
1118 if (CameraConstraintActive) 1123 if (CameraConstraintActive)
1119 { 1124 {
1120 ControllingClient.SendCameraConstraint(new Vector4(0, 0.5f, 0.9f, -3000f)); 1125 ControllingClient.SendCameraConstraint(new Vector4(0f, 0.5f, 0.9f, -3000f));
1121 CameraConstraintActive = false; 1126 CameraConstraintActive = false;
1122 } 1127 }
1123 } 1128 }
@@ -2356,6 +2361,9 @@ namespace OpenSim.Region.Framework.Scenes
2356 2361
2357 public override void Update() 2362 public override void Update()
2358 { 2363 {
2364 const float VELOCITY_TOLERANCE = 0.01f;
2365 const float POSITION_TOLERANCE = 10.0f;
2366
2359 SendPrimUpdates(); 2367 SendPrimUpdates();
2360 2368
2361 if (m_newCoarseLocations) 2369 if (m_newCoarseLocations)
@@ -2366,28 +2374,17 @@ namespace OpenSim.Region.Framework.Scenes
2366 2374
2367 if (m_isChildAgent == false) 2375 if (m_isChildAgent == false)
2368 { 2376 {
2369 if (m_newForce) // user movement 'forces' (ie commands to move) 2377 // Throw away duplicate or insignificant updates
2370 { 2378 if (m_bodyRot != m_lastRotation ||
2371 SendTerseUpdateToAllClients(); 2379 (m_velocity - m_lastVelocity).Length() > VELOCITY_TOLERANCE ||
2372 m_updateCount = 0; 2380 (m_pos - m_lastPosition).Length() > POSITION_TOLERANCE)
2373 }
2374 else if (m_movementflag != 0) // scripted movement (?)
2375 {
2376 m_updateCount++;
2377 if (m_updateCount > 3)
2378 {
2379 SendTerseUpdateToAllClients();
2380 m_updateCount = 0;
2381 }
2382 }
2383 else if ((Util.GetDistanceTo(lastPhysPos, AbsolutePosition) > 0.02)
2384 || (Util.GetDistanceTo(m_lastVelocity, m_velocity) > 0.02)
2385 || lastPhysRot != m_bodyRot)
2386 { 2381 {
2387 // Send Terse Update to all clients updates lastPhysPos and m_lastVelocity
2388 // doing the above assures us that we know what we sent the clients last
2389 SendTerseUpdateToAllClients(); 2382 SendTerseUpdateToAllClients();
2390 m_updateCount = 0; 2383
2384 // Update the "last" values
2385 m_lastPosition = m_pos;
2386 m_lastRotation = m_bodyRot;
2387 m_lastVelocity = m_velocity;
2391 } 2388 }
2392 2389
2393 // followed suggestion from mic bowman. reversed the two lines below. 2390 // followed suggestion from mic bowman. reversed the two lines below.
@@ -2417,7 +2414,7 @@ namespace OpenSim.Region.Framework.Scenes
2417 pos.Z -= m_appearance.HipOffset; 2414 pos.Z -= m_appearance.HipOffset;
2418 2415
2419 remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_regionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 2416 remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_regionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
2420 pos, m_velocity, Vector3.Zero, m_rotation, Vector4.Zero, m_uuid, null, GetUpdatePriority(remoteClient))); 2417 pos, m_velocity, Vector3.Zero, m_bodyRot, Vector4.UnitW, m_uuid, null, GetUpdatePriority(remoteClient)));
2421 2418
2422 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); 2419 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS);
2423 m_scene.StatsReporter.AddAgentUpdates(1); 2420 m_scene.StatsReporter.AddAgentUpdates(1);
@@ -2430,15 +2427,10 @@ namespace OpenSim.Region.Framework.Scenes
2430 public void SendTerseUpdateToAllClients() 2427 public void SendTerseUpdateToAllClients()
2431 { 2428 {
2432 m_perfMonMS = Environment.TickCount; 2429 m_perfMonMS = Environment.TickCount;
2433 2430
2434 m_scene.ForEachClient(SendTerseUpdateToClient); 2431 m_scene.ForEachClient(SendTerseUpdateToClient);
2435 2432
2436 m_lastVelocity = m_velocity;
2437 lastPhysPos = AbsolutePosition;
2438 lastPhysRot = m_bodyRot;
2439
2440 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); 2433 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS);
2441
2442 } 2434 }
2443 2435
2444 public void SendCoarseLocations() 2436 public void SendCoarseLocations()
@@ -2517,15 +2509,12 @@ namespace OpenSim.Region.Framework.Scenes
2517 if (m_appearance.Texture == null) 2509 if (m_appearance.Texture == null)
2518 return; 2510 return;
2519 2511
2520 // Note: because Quaternion is a struct, it can't be null
2521 Quaternion rot = m_bodyRot;
2522
2523 Vector3 pos = m_pos; 2512 Vector3 pos = m_pos;
2524 pos.Z -= m_appearance.HipOffset; 2513 pos.Z -= m_appearance.HipOffset;
2525 2514
2526 remoteAvatar.m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, 2515 remoteAvatar.m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid,
2527 LocalId, m_pos, m_appearance.Texture.GetBytes(), 2516 LocalId, pos, m_appearance.Texture.GetBytes(),
2528 m_parentID, rot)); 2517 m_parentID, m_bodyRot));
2529 m_scene.StatsReporter.AddAgentUpdates(1); 2518 m_scene.StatsReporter.AddAgentUpdates(1);
2530 } 2519 }
2531 2520
@@ -2536,9 +2525,12 @@ namespace OpenSim.Region.Framework.Scenes
2536 { 2525 {
2537 m_perfMonMS = Environment.TickCount; 2526 m_perfMonMS = Environment.TickCount;
2538 2527
2539 List<ScenePresence> avatars = m_scene.GetScenePresences(); 2528 ScenePresence[] avatars = m_scene.GetScenePresences();
2540 foreach (ScenePresence avatar in avatars) 2529
2530 for (int i = 0; i < avatars.Length; i++)
2541 { 2531 {
2532 ScenePresence avatar = avatars[i];
2533
2542 // only send if this is the root (children are only "listening posts" in a foreign region) 2534 // only send if this is the root (children are only "listening posts" in a foreign region)
2543 if (!IsChildAgent) 2535 if (!IsChildAgent)
2544 { 2536 {
@@ -2556,7 +2548,7 @@ namespace OpenSim.Region.Framework.Scenes
2556 } 2548 }
2557 } 2549 }
2558 2550
2559 m_scene.StatsReporter.AddAgentUpdates(avatars.Count); 2551 m_scene.StatsReporter.AddAgentUpdates(avatars.Length);
2560 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); 2552 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS);
2561 2553
2562 //SendAnimPack(); 2554 //SendAnimPack();
@@ -2588,14 +2580,11 @@ namespace OpenSim.Region.Framework.Scenes
2588 // the inventory arrives 2580 // the inventory arrives
2589 // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); 2581 // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance);
2590 2582
2591 // Note: because Quaternion is a struct, it can't be null
2592 Quaternion rot = m_bodyRot;
2593
2594 Vector3 pos = m_pos; 2583 Vector3 pos = m_pos;
2595 pos.Z -= m_appearance.HipOffset; 2584 pos.Z -= m_appearance.HipOffset;
2596 2585
2597 m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, 2586 m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId,
2598 m_pos, m_appearance.Texture.GetBytes(), m_parentID, rot)); 2587 pos, m_appearance.Texture.GetBytes(), m_parentID, m_bodyRot));
2599 2588
2600 if (!m_isChildAgent) 2589 if (!m_isChildAgent)
2601 { 2590 {
@@ -2679,7 +2668,7 @@ namespace OpenSim.Region.Framework.Scenes
2679 { 2668 {
2680 if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) 2669 if (m_scene.AssetService.Get(face.TextureID.ToString()) == null)
2681 { 2670 {
2682 m_log.Warn("[APPEARANCE]: Missing baked texture " + face.TextureID + " (" + (AppearanceManager.TextureIndex)j + ") for avatar " + this.Name); 2671 m_log.Warn("[APPEARANCE]: Missing baked texture " + face.TextureID + " (" + j + ") for avatar " + this.Name);
2683 this.ControllingClient.SendRebakeAvatarTextures(face.TextureID); 2672 this.ControllingClient.SendRebakeAvatarTextures(face.TextureID);
2684 } 2673 }
2685 } 2674 }
@@ -2700,9 +2689,11 @@ namespace OpenSim.Region.Framework.Scenes
2700 m_startAnimationSet = true; 2689 m_startAnimationSet = true;
2701 } 2690 }
2702 2691
2703 Quaternion rot = m_bodyRot; 2692 Vector3 pos = m_pos;
2693 pos.Z -= m_appearance.HipOffset;
2694
2704 m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, 2695 m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId,
2705 m_pos, m_appearance.Texture.GetBytes(), m_parentID, rot)); 2696 pos, m_appearance.Texture.GetBytes(), m_parentID, m_bodyRot));
2706 2697
2707 } 2698 }
2708 2699
@@ -3300,7 +3291,6 @@ namespace OpenSim.Region.Framework.Scenes
3300 /// </summary> 3291 /// </summary>
3301 public override void UpdateMovement() 3292 public override void UpdateMovement()
3302 { 3293 {
3303 m_newForce = false;
3304 lock (m_forcesList) 3294 lock (m_forcesList)
3305 { 3295 {
3306 if (m_forcesList.Count > 0) 3296 if (m_forcesList.Count > 0)
@@ -3322,7 +3312,6 @@ namespace OpenSim.Region.Framework.Scenes
3322 // Ignoring this causes no movement to be sent to the physics engine... 3312 // Ignoring this causes no movement to be sent to the physics engine...
3323 // which when the scene is moving at 1 frame every 10 seconds, it doesn't really matter! 3313 // which when the scene is moving at 1 frame every 10 seconds, it doesn't really matter!
3324 } 3314 }
3325 m_newForce = true;
3326 3315
3327 m_forcesList.Clear(); 3316 m_forcesList.Clear();
3328 } 3317 }
@@ -3356,20 +3345,18 @@ namespace OpenSim.Region.Framework.Scenes
3356 3345
3357 PhysicsScene scene = m_scene.PhysicsScene; 3346 PhysicsScene scene = m_scene.PhysicsScene;
3358 3347
3359 PhysicsVector pVec = 3348 Vector3 pVec = AbsolutePosition;
3360 new PhysicsVector(AbsolutePosition.X, AbsolutePosition.Y,
3361 AbsolutePosition.Z);
3362 3349
3363 // Old bug where the height was in centimeters instead of meters 3350 // Old bug where the height was in centimeters instead of meters
3364 if (m_avHeight == 127.0f) 3351 if (m_avHeight == 127.0f)
3365 { 3352 {
3366 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, new PhysicsVector(0, 0, 1.56f), 3353 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, new Vector3(0f, 0f, 1.56f),
3367 isFlying); 3354 isFlying);
3368 } 3355 }
3369 else 3356 else
3370 { 3357 {
3371 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, 3358 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec,
3372 new PhysicsVector(0, 0, m_avHeight), isFlying); 3359 new Vector3(0f, 0f, m_avHeight), isFlying);
3373 } 3360 }
3374 scene.AddPhysicsActorTaint(m_physicsActor); 3361 scene.AddPhysicsActorTaint(m_physicsActor);
3375 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3362 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
@@ -3380,7 +3367,7 @@ namespace OpenSim.Region.Framework.Scenes
3380 3367
3381 } 3368 }
3382 3369
3383 private void OutOfBoundsCall(PhysicsVector pos) 3370 private void OutOfBoundsCall(Vector3 pos)
3384 { 3371 {
3385 //bool flying = m_physicsActor.Flying; 3372 //bool flying = m_physicsActor.Flying;
3386 //RemoveFromPhysicalScene(); 3373 //RemoveFromPhysicalScene();
@@ -3603,7 +3590,7 @@ namespace OpenSim.Region.Framework.Scenes
3603 */ 3590 */
3604 } 3591 }
3605 3592
3606 internal void PushForce(PhysicsVector impulse) 3593 internal void PushForce(Vector3 impulse)
3607 { 3594 {
3608 if (PhysicsActor != null) 3595 if (PhysicsActor != null)
3609 { 3596 {
@@ -3866,6 +3853,8 @@ namespace OpenSim.Region.Framework.Scenes
3866 return GetPriorityByDistance(client); 3853 return GetPriorityByDistance(client);
3867 case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance: 3854 case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance:
3868 return GetPriorityByDistance(client); 3855 return GetPriorityByDistance(client);
3856 case Scenes.Scene.UpdatePrioritizationSchemes.FrontBack:
3857 return GetPriorityByFrontBack(client);
3869 default: 3858 default:
3870 throw new InvalidOperationException("UpdatePrioritizationScheme not defined."); 3859 throw new InvalidOperationException("UpdatePrioritizationScheme not defined.");
3871 } 3860 }
@@ -3887,11 +3876,34 @@ namespace OpenSim.Region.Framework.Scenes
3887 return double.NaN; 3876 return double.NaN;
3888 } 3877 }
3889 3878
3879 private double GetPriorityByFrontBack(IClientAPI client)
3880 {
3881 ScenePresence presence = Scene.GetScenePresence(client.AgentId);
3882 if (presence != null)
3883 {
3884 return GetPriorityByFrontBack(presence.CameraPosition, presence.CameraAtAxis);
3885 }
3886 return double.NaN;
3887 }
3888
3890 private double GetPriorityByDistance(Vector3 position) 3889 private double GetPriorityByDistance(Vector3 position)
3891 { 3890 {
3892 return Vector3.Distance(AbsolutePosition, position); 3891 return Vector3.Distance(AbsolutePosition, position);
3893 } 3892 }
3894 3893
3894 private double GetPriorityByFrontBack(Vector3 camPosition, Vector3 camAtAxis)
3895 {
3896 // Distance
3897 double priority = Vector3.Distance(camPosition, AbsolutePosition);
3898
3899 // Plane equation
3900 float d = -Vector3.Dot(camPosition, camAtAxis);
3901 float p = Vector3.Dot(camAtAxis, AbsolutePosition) + d;
3902 if (p < 0.0f) priority *= 2.0f;
3903
3904 return priority;
3905 }
3906
3895 private double GetSOGUpdatePriority(SceneObjectGroup sog) 3907 private double GetSOGUpdatePriority(SceneObjectGroup sog)
3896 { 3908 {
3897 switch (Scene.UpdatePrioritizationScheme) 3909 switch (Scene.UpdatePrioritizationScheme)
@@ -3902,6 +3914,8 @@ namespace OpenSim.Region.Framework.Scenes
3902 return sog.GetPriorityByDistance((IsChildAgent) ? AbsolutePosition : CameraPosition); 3914 return sog.GetPriorityByDistance((IsChildAgent) ? AbsolutePosition : CameraPosition);
3903 case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance: 3915 case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance:
3904 return sog.GetPriorityBySimpleAngularDistance((IsChildAgent) ? AbsolutePosition : CameraPosition); 3916 return sog.GetPriorityBySimpleAngularDistance((IsChildAgent) ? AbsolutePosition : CameraPosition);
3917 case Scenes.Scene.UpdatePrioritizationSchemes.FrontBack:
3918 return sog.GetPriorityByFrontBack(CameraPosition, CameraAtAxis);
3905 default: 3919 default:
3906 throw new InvalidOperationException("UpdatePrioritizationScheme not defined"); 3920 throw new InvalidOperationException("UpdatePrioritizationScheme not defined");
3907 } 3921 }
@@ -3928,6 +3942,8 @@ namespace OpenSim.Region.Framework.Scenes
3928 case Scene.UpdatePrioritizationSchemes.Distance: 3942 case Scene.UpdatePrioritizationSchemes.Distance:
3929 case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance: 3943 case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance:
3930 return GetPriorityByDistance((IsChildAgent) ? AbsolutePosition : CameraPosition); 3944 return GetPriorityByDistance((IsChildAgent) ? AbsolutePosition : CameraPosition);
3945 case Scenes.Scene.UpdatePrioritizationSchemes.FrontBack:
3946 return GetPriorityByFrontBack(CameraPosition, CameraAtAxis);
3931 default: 3947 default:
3932 throw new InvalidOperationException("UpdatePrioritizationScheme not defined"); 3948 throw new InvalidOperationException("UpdatePrioritizationScheme not defined");
3933 } 3949 }