aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2009-11-03 19:11:09 +0000
committerJustin Clark-Casey (justincc)2009-11-03 19:11:09 +0000
commitaf0e5d097480de264e7501e7d5d35328be5640bb (patch)
tree4ca5cd796ed9618dc9134a6e5eee1f7e7912bee4 /OpenSim/Region
parentminor: remove some mono compiler warnings (diff)
parentFixed a couple of NREs in corner cases. (diff)
downloadopensim-SC_OLD-af0e5d097480de264e7501e7d5d35328be5640bb.zip
opensim-SC_OLD-af0e5d097480de264e7501e7d5d35328be5640bb.tar.gz
opensim-SC_OLD-af0e5d097480de264e7501e7d5d35328be5640bb.tar.bz2
opensim-SC_OLD-af0e5d097480de264e7501e7d5d35328be5640bb.tar.xz
Merge branch 'master' of ssh://justincc@opensimulator.org/var/git/opensim
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/Application/OpenSim.cs56
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs198
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs19
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs54
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs21
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/Alerts/DeadlockAlert.cs37
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/IAlert.cs13
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/IMonitor.cs9
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs93
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/AgentCountMonitor.cs33
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/ChildAgentCountMonitor.cs33
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/EventFrameMonitor.cs33
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/GCMemoryMonitor.cs26
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/LandFrameMonitor.cs33
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/LastFrameTimeMonitor.cs34
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/ObjectCountMonitor.cs33
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/PWSMemoryMonitor.cs26
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/PhysicsFrameMonitor.cs33
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/PhysicsUpdateFrameMonitor.cs33
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/ThreadCountMonitor.cs25
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/TotalFrameMonitor.cs33
-rw-r--r--OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs6
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs16
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Permissions.cs36
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs139
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneBase.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs14
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs39
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs153
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs925
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs4
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs11
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs2
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsActor.cs29
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsScene.cs5
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs14
-rw-r--r--OpenSim/Region/Physics/Meshing/PrimMesher.cs843
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODECharacter.cs4
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs4
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdePlugin.cs158
-rw-r--r--OpenSim/Region/ScriptEngine/Interfaces/ICompiler.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs5
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs191
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs54
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs118
47 files changed, 1687 insertions, 1970 deletions
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index b448182..60c34df 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -343,6 +343,10 @@ namespace OpenSim
343 "Add-InventoryHost <host>", 343 "Add-InventoryHost <host>",
344 String.Empty, RunCommand); 344 String.Empty, RunCommand);
345 345
346 m_console.Commands.AddCommand("region", false, "kill uuid",
347 "kill uuid <UUID>",
348 "Kill an object by UUID", KillUUID);
349
346 if (ConfigurationSettings.Standalone) 350 if (ConfigurationSettings.Standalone)
347 { 351 {
348 m_console.Commands.AddCommand("region", false, "create user", 352 m_console.Commands.AddCommand("region", false, "create user",
@@ -1332,6 +1336,58 @@ namespace OpenSim
1332 return result; 1336 return result;
1333 } 1337 }
1334 1338
1339 /// <summary>
1340 /// Kill an object given its UUID.
1341 /// </summary>
1342 /// <param name="cmdparams"></param>
1343 protected void KillUUID(string module, string[] cmdparams)
1344 {
1345 if (cmdparams.Length > 2)
1346 {
1347 UUID id = UUID.Zero;
1348 SceneObjectGroup grp = null;
1349 Scene sc = null;
1350
1351 if (!UUID.TryParse(cmdparams[2], out id))
1352 {
1353 MainConsole.Instance.Output("[KillUUID]: Error bad UUID format!");
1354 return;
1355 }
1356
1357 m_sceneManager.ForEachScene(
1358 delegate(Scene scene)
1359 {
1360 SceneObjectPart part = scene.GetSceneObjectPart(id);
1361 if (part == null)
1362 return;
1363
1364 grp = part.ParentGroup;
1365 sc = scene;
1366 });
1367
1368 if (grp == null)
1369 {
1370 MainConsole.Instance.Output(String.Format("[KillUUID]: Given UUID {0} not found!", id));
1371 }
1372 else
1373 {
1374 MainConsole.Instance.Output(String.Format("[KillUUID]: Found UUID {0} in scene {1}", id, sc.RegionInfo.RegionName));
1375 try
1376 {
1377 sc.DeleteSceneObject(grp, false);
1378 }
1379 catch (Exception e)
1380 {
1381 m_log.ErrorFormat("[KillUUID]: Error while removing objects from scene: " + e);
1382 }
1383 }
1384 }
1385 else
1386 {
1387 MainConsole.Instance.Output("[KillUUID]: Usage: kill uuid <UUID>");
1388 }
1389 }
1390
1335 #endregion 1391 #endregion
1336 } 1392 }
1337} 1393}
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index f6a7a0c..db0c3b8 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -37,6 +37,7 @@ using System.Xml;
37using log4net; 37using log4net;
38using OpenMetaverse; 38using OpenMetaverse;
39using OpenMetaverse.Packets; 39using OpenMetaverse.Packets;
40using OpenMetaverse.StructuredData;
40using OpenSim.Framework; 41using OpenSim.Framework;
41using OpenSim.Framework.Client; 42using OpenSim.Framework.Client;
42using OpenSim.Framework.Communications.Cache; 43using OpenSim.Framework.Communications.Cache;
@@ -314,14 +315,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
314 private readonly LLUDPClient m_udpClient; 315 private readonly LLUDPClient m_udpClient;
315 private readonly UUID m_sessionId; 316 private readonly UUID m_sessionId;
316 private readonly UUID m_secureSessionId; 317 private readonly UUID m_secureSessionId;
317 private readonly UUID m_agentId; 318 protected readonly UUID m_agentId;
318 private readonly uint m_circuitCode; 319 private readonly uint m_circuitCode;
319 private readonly byte[] m_channelVersion = Utils.EmptyBytes; 320 private readonly byte[] m_channelVersion = Utils.EmptyBytes;
320 private readonly Dictionary<string, UUID> m_defaultAnimations = new Dictionary<string, UUID>(); 321 private readonly Dictionary<string, UUID> m_defaultAnimations = new Dictionary<string, UUID>();
321 private readonly IGroupsModule m_GroupsModule; 322 private readonly IGroupsModule m_GroupsModule;
322 323
323 private int m_cachedTextureSerial; 324 private int m_cachedTextureSerial;
324 private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates; 325 protected PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates;
325 private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates; 326 private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates;
326 private PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates; 327 private PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates;
327 private int m_moneyBalance; 328 private int m_moneyBalance;
@@ -1856,7 +1857,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1856 economyData.Info.TeleportMinPrice = TeleportMinPrice; 1857 economyData.Info.TeleportMinPrice = TeleportMinPrice;
1857 economyData.Info.TeleportPriceExponent = TeleportPriceExponent; 1858 economyData.Info.TeleportPriceExponent = TeleportPriceExponent;
1858 economyData.Header.Reliable = true; 1859 economyData.Header.Reliable = true;
1859 OutPacket(economyData, ThrottleOutPacketType.Unknown); 1860 OutPacket(economyData, ThrottleOutPacketType.Task);
1860 } 1861 }
1861 1862
1862 public void SendAvatarPickerReply(AvatarPickerReplyAgentDataArgs AgentData, List<AvatarPickerReplyDataArgs> Data) 1863 public void SendAvatarPickerReply(AvatarPickerReplyAgentDataArgs AgentData, List<AvatarPickerReplyDataArgs> Data)
@@ -2786,30 +2787,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2786 2787
2787 public void SendAvatarGroupsReply(UUID avatarID, GroupMembershipData[] data) 2788 public void SendAvatarGroupsReply(UUID avatarID, GroupMembershipData[] data)
2788 { 2789 {
2789 AvatarGroupsReplyPacket p = (AvatarGroupsReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarGroupsReply); 2790 OSDMap llsd = new OSDMap(3);
2790 2791 OSDArray AgentData = new OSDArray(1);
2791 p.AgentData = new AvatarGroupsReplyPacket.AgentDataBlock(); 2792 OSDMap AgentDataMap = new OSDMap(1);
2792 p.AgentData.AgentID = AgentId; 2793 AgentDataMap.Add("AgentID", OSD.FromUUID(this.AgentId));
2793 p.AgentData.AvatarID = avatarID; 2794 AgentDataMap.Add("AvatarID", OSD.FromUUID(avatarID));
2794 2795 AgentData.Add(AgentDataMap);
2795 p.GroupData = new AvatarGroupsReplyPacket.GroupDataBlock[data.Length]; 2796 llsd.Add("AgentData", AgentData);
2796 int i = 0; 2797 OSDArray GroupData = new OSDArray(data.Length);
2797 foreach (GroupMembershipData m in data) 2798 OSDArray NewGroupData = new OSDArray(data.Length);
2798 { 2799 foreach (GroupMembershipData m in data)
2799 p.GroupData[i] = new AvatarGroupsReplyPacket.GroupDataBlock(); 2800 {
2800 p.GroupData[i].GroupPowers = m.GroupPowers; 2801 OSDMap GroupDataMap = new OSDMap(6);
2801 p.GroupData[i].AcceptNotices = m.AcceptNotices; 2802 OSDMap NewGroupDataMap = new OSDMap(1);
2802 p.GroupData[i].GroupTitle = Utils.StringToBytes(m.GroupTitle); 2803 GroupDataMap.Add("GroupPowers", OSD.FromBinary(m.GroupPowers));
2803 p.GroupData[i].GroupID = m.GroupID; 2804 GroupDataMap.Add("AcceptNotices", OSD.FromBoolean(m.AcceptNotices));
2804 p.GroupData[i].GroupName = Utils.StringToBytes(m.GroupName); 2805 GroupDataMap.Add("GroupTitle", OSD.FromString(m.GroupTitle));
2805 p.GroupData[i].GroupInsigniaID = m.GroupPicture; 2806 GroupDataMap.Add("GroupID", OSD.FromUUID(m.GroupID));
2806 i++; 2807 GroupDataMap.Add("GroupName", OSD.FromString(m.GroupName));
2807 } 2808 GroupDataMap.Add("GroupInsigniaID", OSD.FromUUID(m.GroupPicture));
2808 2809 NewGroupDataMap.Add("ListInProfile", OSD.FromBoolean(m.ListInProfile));
2809 p.NewGroupData = new AvatarGroupsReplyPacket.NewGroupDataBlock(); 2810 GroupData.Add(GroupDataMap);
2810 p.NewGroupData.ListInProfile = true; 2811 NewGroupData.Add(NewGroupDataMap);
2811 2812 }
2812 OutPacket(p, ThrottleOutPacketType.Task); 2813 llsd.Add("GroupData", GroupData);
2814 llsd.Add("NewGroupData", NewGroupData);
2815
2816 IEventQueue eq = this.Scene.RequestModuleInterface<IEventQueue>();
2817 if (eq != null)
2818 {
2819 eq.Enqueue(BuildEvent("AvatarGroupsReply", llsd), this.AgentId);
2820 }
2813 } 2821 }
2814 2822
2815 public void SendJoinGroupReply(UUID groupID, bool success) 2823 public void SendJoinGroupReply(UUID groupID, bool success)
@@ -3168,107 +3176,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3168 3176
3169 #endregion 3177 #endregion
3170 3178
3171 #region Prim/Avatar Updates
3172
3173 /*void SendObjectUpdate(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags)
3174 {
3175 bool canUseCompressed, canUseImproved;
3176 UpdateFlagsToPacketType(creatorFlags, updateFlags, out canUseCompressed, out canUseImproved);
3177
3178 if (!canUseImproved && !canUseCompressed)
3179 SendFullObjectUpdate(obj, creatorFlags, updateFlags);
3180 else if (!canUseImproved)
3181 SendObjectUpdateCompressed(obj, creatorFlags, updateFlags);
3182 else
3183 SendImprovedTerseObjectUpdate(obj, creatorFlags, updateFlags);
3184 }
3185
3186 void SendFullObjectUpdate(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags)
3187 {
3188 IClientAPI owner;
3189 if (m_scene.ClientManager.TryGetValue(obj.OwnerID, out owner) && owner is LLClientView)
3190 {
3191 LLClientView llOwner = (LLClientView)owner;
3192
3193 // Send an update out to the owner
3194 ObjectUpdatePacket updateToOwner = new ObjectUpdatePacket();
3195 updateToOwner.RegionData.RegionHandle = obj.RegionHandle;
3196 //updateToOwner.RegionData.TimeDilation = (ushort)(timeDilation * (float)UInt16.MaxValue);
3197 updateToOwner.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
3198 updateToOwner.ObjectData[0] = BuildUpdateBlock(obj, obj.Flags | creatorFlags | PrimFlags.ObjectYouOwner, 0);
3199
3200 m_udpServer.SendPacket(llOwner.UDPClient, updateToOwner, ThrottleOutPacketType.State, true);
3201 }
3202
3203 // Send an update out to everyone else
3204 ObjectUpdatePacket updateToOthers = new ObjectUpdatePacket();
3205 updateToOthers.RegionData.RegionHandle = obj.RegionHandle;
3206 //updateToOthers.RegionData.TimeDilation = (ushort)(timeDilation * (float)UInt16.MaxValue);
3207 updateToOthers.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
3208 updateToOthers.ObjectData[0] = BuildUpdateBlock(obj, obj.Flags, 0);
3209
3210 m_scene.ClientManager.ForEach(
3211 delegate(IClientAPI client)
3212 {
3213 if (client.AgentId != obj.OwnerID && client is LLClientView)
3214 {
3215 LLClientView llClient = (LLClientView)client;
3216 m_udpServer.SendPacket(llClient.UDPClient, updateToOthers, ThrottleOutPacketType.State, true);
3217 }
3218 }
3219 );
3220 }
3221
3222 void SendObjectUpdateCompressed(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags)
3223 {
3224 }
3225
3226 void SendImprovedTerseObjectUpdate(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags)
3227 {
3228 }
3229
3230 void UpdateFlagsToPacketType(PrimFlags creatorFlags, PrimUpdateFlags updateFlags, out bool canUseCompressed, out bool canUseImproved)
3231 {
3232 canUseCompressed = true;
3233 canUseImproved = true;
3234
3235 if ((updateFlags & PrimUpdateFlags.FullUpdate) == PrimUpdateFlags.FullUpdate || creatorFlags != PrimFlags.None)
3236 {
3237 canUseCompressed = false;
3238 canUseImproved = false;
3239 }
3240 else
3241 {
3242 if ((updateFlags & PrimUpdateFlags.Velocity) != 0 ||
3243 (updateFlags & PrimUpdateFlags.Acceleration) != 0 ||
3244 (updateFlags & PrimUpdateFlags.CollisionPlane) != 0 ||
3245 (updateFlags & PrimUpdateFlags.Joint) != 0)
3246 {
3247 canUseCompressed = false;
3248 }
3249
3250 if ((updateFlags & PrimUpdateFlags.PrimFlags) != 0 ||
3251 (updateFlags & PrimUpdateFlags.ParentID) != 0 ||
3252 (updateFlags & PrimUpdateFlags.Scale) != 0 ||
3253 (updateFlags & PrimUpdateFlags.PrimData) != 0 ||
3254 (updateFlags & PrimUpdateFlags.Text) != 0 ||
3255 (updateFlags & PrimUpdateFlags.NameValue) != 0 ||
3256 (updateFlags & PrimUpdateFlags.ExtraData) != 0 ||
3257 (updateFlags & PrimUpdateFlags.TextureAnim) != 0 ||
3258 (updateFlags & PrimUpdateFlags.Sound) != 0 ||
3259 (updateFlags & PrimUpdateFlags.Particles) != 0 ||
3260 (updateFlags & PrimUpdateFlags.Material) != 0 ||
3261 (updateFlags & PrimUpdateFlags.ClickAction) != 0 ||
3262 (updateFlags & PrimUpdateFlags.MediaURL) != 0 ||
3263 (updateFlags & PrimUpdateFlags.Joint) != 0)
3264 {
3265 canUseImproved = false;
3266 }
3267 }
3268 }*/
3269
3270 #endregion Prim/Avatar Updates
3271
3272 #region Avatar Packet/Data Sending Methods 3179 #region Avatar Packet/Data Sending Methods
3273 3180
3274 /// <summary> 3181 /// <summary>
@@ -3314,7 +3221,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3314 ProcessAvatarTerseUpdates(); 3221 ProcessAvatarTerseUpdates();
3315 } 3222 }
3316 3223
3317 private void ProcessAvatarTerseUpdates() 3224 protected void ProcessAvatarTerseUpdates()
3318 { 3225 {
3319 ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 3226 ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
3320 terse.Header.Reliable = false; 3227 terse.Header.Reliable = false;
@@ -3335,6 +3242,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3335 terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue(); 3242 terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue();
3336 } 3243 }
3337 3244
3245 // HACK: Using the task category until the tiered reprioritization code is in
3338 OutPacket(terse, ThrottleOutPacketType.Task); 3246 OutPacket(terse, ThrottleOutPacketType.Task);
3339 } 3247 }
3340 3248
@@ -4430,11 +4338,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4430 /// </summary> 4338 /// </summary>
4431 protected virtual void RegisterLocalPacketHandlers() 4339 protected virtual void RegisterLocalPacketHandlers()
4432 { 4340 {
4433 AddLocalPacketHandler(PacketType.LogoutRequest, Logout); 4341 AddLocalPacketHandler(PacketType.LogoutRequest, HandleLogout);
4434 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate); 4342 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate);
4435 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect); 4343 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect);
4436 AddLocalPacketHandler(PacketType.AgentCachedTexture, AgentTextureCached); 4344 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached);
4437 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, MultipleObjUpdate); 4345 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate);
4438 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest); 4346 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest);
4439 AddLocalPacketHandler(PacketType.ParcelBuy, HandleParcelBuyRequest); 4347 AddLocalPacketHandler(PacketType.ParcelBuy, HandleParcelBuyRequest);
4440 AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest); 4348 AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest);
@@ -4703,7 +4611,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4703 /// <param name="client"></param> 4611 /// <param name="client"></param>
4704 /// <param name="packet"></param> 4612 /// <param name="packet"></param>
4705 /// <returns></returns> 4613 /// <returns></returns>
4706 protected virtual bool Logout(IClientAPI client, Packet packet) 4614 protected virtual bool HandleLogout(IClientAPI client, Packet packet)
4707 { 4615 {
4708 if (packet.Type == PacketType.LogoutRequest) 4616 if (packet.Type == PacketType.LogoutRequest)
4709 { 4617 {
@@ -4741,7 +4649,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4741 /// <param name="simclient"></param> 4649 /// <param name="simclient"></param>
4742 /// <param name="packet"></param> 4650 /// <param name="packet"></param>
4743 /// <returns></returns> 4651 /// <returns></returns>
4744 protected bool AgentTextureCached(IClientAPI simclient, Packet packet) 4652 protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet)
4745 { 4653 {
4746 //m_log.Debug("texture cached: " + packet.ToString()); 4654 //m_log.Debug("texture cached: " + packet.ToString());
4747 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet; 4655 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet;
@@ -4771,7 +4679,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4771 return true; 4679 return true;
4772 } 4680 }
4773 4681
4774 protected bool MultipleObjUpdate(IClientAPI simClient, Packet packet) 4682 protected bool HandleMultipleObjUpdate(IClientAPI simClient, Packet packet)
4775 { 4683 {
4776 MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket)packet; 4684 MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket)packet;
4777 if (multipleupdate.AgentData.SessionID != SessionId) return false; 4685 if (multipleupdate.AgentData.SessionID != SessionId) return false;
@@ -5050,7 +4958,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5050 /// </summary> 4958 /// </summary>
5051 /// <param name="packet">Packet to send</param> 4959 /// <param name="packet">Packet to send</param>
5052 /// <param name="throttlePacketType">Throttling category for the packet</param> 4960 /// <param name="throttlePacketType">Throttling category for the packet</param>
5053 private void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType) 4961 protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType)
5054 { 4962 {
5055 m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, true); 4963 m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, true);
5056 } 4964 }
@@ -9944,7 +9852,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9944 commandMessagePacket.CommandBlock.Command = (uint)command; 9852 commandMessagePacket.CommandBlock.Command = (uint)command;
9945 commandMessagePacket.CommandBlock.Time = time; 9853 commandMessagePacket.CommandBlock.Time = time;
9946 9854
9947 OutPacket(commandMessagePacket, ThrottleOutPacketType.Unknown); 9855 OutPacket(commandMessagePacket, ThrottleOutPacketType.Task);
9948 } 9856 }
9949 9857
9950 public void SendParcelMediaUpdate(string mediaUrl, UUID mediaTextureID, 9858 public void SendParcelMediaUpdate(string mediaUrl, UUID mediaTextureID,
@@ -9962,7 +9870,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9962 updatePacket.DataBlockExtended.MediaHeight = mediaHeight; 9870 updatePacket.DataBlockExtended.MediaHeight = mediaHeight;
9963 updatePacket.DataBlockExtended.MediaLoop = mediaLoop; 9871 updatePacket.DataBlockExtended.MediaLoop = mediaLoop;
9964 9872
9965 OutPacket(updatePacket, ThrottleOutPacketType.Unknown); 9873 OutPacket(updatePacket, ThrottleOutPacketType.Task);
9966 } 9874 }
9967 9875
9968 #endregion 9876 #endregion
@@ -10236,7 +10144,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10236 } 10144 }
10237 10145
10238 #region PriorityQueue 10146 #region PriorityQueue
10239 private class PriorityQueue<TPriority, TValue> 10147 public class PriorityQueue<TPriority, TValue>
10240 { 10148 {
10241 internal delegate bool UpdatePriorityHandler(ref TPriority priority, uint local_id); 10149 internal delegate bool UpdatePriorityHandler(ref TPriority priority, uint local_id);
10242 10150
@@ -10264,7 +10172,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10264 this.m_comparison = comparison; 10172 this.m_comparison = comparison;
10265 } 10173 }
10266 10174
10267 internal object SyncRoot { get { return this.m_syncRoot; } } 10175 public object SyncRoot { get { return this.m_syncRoot; } }
10268 internal int Count 10176 internal int Count
10269 { 10177 {
10270 get 10178 get
@@ -10276,7 +10184,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10276 } 10184 }
10277 } 10185 }
10278 10186
10279 internal bool Enqueue(TPriority priority, TValue value, uint local_id) 10187 public bool Enqueue(TPriority priority, TValue value, uint local_id)
10280 { 10188 {
10281 LookupItem item; 10189 LookupItem item;
10282 10190
@@ -10396,5 +10304,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10396 } 10304 }
10397 #endregion 10305 #endregion
10398 10306
10307 public static OSD BuildEvent(string eventName, OSD eventBody)
10308 {
10309 OSDMap osdEvent = new OSDMap(2);
10310 osdEvent.Add("message", new OSDString(eventName));
10311 osdEvent.Add("body", eventBody);
10312
10313 return osdEvent;
10314 }
10399 } 10315 }
10400} 10316}
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
index 84a4959..9856a1c 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
@@ -135,8 +135,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
135 private readonly TokenBucket m_throttle; 135 private readonly TokenBucket m_throttle;
136 /// <summary>Throttle buckets for each packet category</summary> 136 /// <summary>Throttle buckets for each packet category</summary>
137 private readonly TokenBucket[] m_throttleCategories; 137 private readonly TokenBucket[] m_throttleCategories;
138 /// <summary>Throttle rate defaults and limits</summary>
139 private readonly ThrottleRates m_defaultThrottleRates;
140 /// <summary>Outgoing queues for throttled packets</summary> 138 /// <summary>Outgoing queues for throttled packets</summary>
141 private readonly OpenSim.Framework.LocklessQueue<OutgoingPacket>[] m_packetOutboxes = new OpenSim.Framework.LocklessQueue<OutgoingPacket>[THROTTLE_CATEGORY_COUNT]; 139 private readonly OpenSim.Framework.LocklessQueue<OutgoingPacket>[] m_packetOutboxes = new OpenSim.Framework.LocklessQueue<OutgoingPacket>[THROTTLE_CATEGORY_COUNT];
142 /// <summary>A container that can hold one packet for each outbox, used to store 140 /// <summary>A container that can hold one packet for each outbox, used to store
@@ -145,6 +143,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
145 /// <summary>A reference to the LLUDPServer that is managing this client</summary> 143 /// <summary>A reference to the LLUDPServer that is managing this client</summary>
146 private readonly LLUDPServer m_udpServer; 144 private readonly LLUDPServer m_udpServer;
147 145
146 private int m_defaultRTO = 3000;
147 private int m_maxRTO = 60000;
148
148 /// <summary> 149 /// <summary>
149 /// Default constructor 150 /// Default constructor
150 /// </summary> 151 /// </summary>
@@ -155,13 +156,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
155 /// <param name="circuitCode">Circuit code for this connection</param> 156 /// <param name="circuitCode">Circuit code for this connection</param>
156 /// <param name="agentID">AgentID for the connected agent</param> 157 /// <param name="agentID">AgentID for the connected agent</param>
157 /// <param name="remoteEndPoint">Remote endpoint for this connection</param> 158 /// <param name="remoteEndPoint">Remote endpoint for this connection</param>
158 public LLUDPClient(LLUDPServer server, ThrottleRates rates, TokenBucket parentThrottle, uint circuitCode, UUID agentID, IPEndPoint remoteEndPoint) 159 public LLUDPClient(LLUDPServer server, ThrottleRates rates, TokenBucket parentThrottle, uint circuitCode, UUID agentID, IPEndPoint remoteEndPoint, int defaultRTO, int maxRTO)
159 { 160 {
160 AgentID = agentID; 161 AgentID = agentID;
161 RemoteEndPoint = remoteEndPoint; 162 RemoteEndPoint = remoteEndPoint;
162 CircuitCode = circuitCode; 163 CircuitCode = circuitCode;
163 m_udpServer = server; 164 m_udpServer = server;
164 m_defaultThrottleRates = rates; 165 if (defaultRTO != 0)
166 m_defaultRTO = defaultRTO;
167 if (maxRTO != 0)
168 m_maxRTO = maxRTO;
169
165 // Create a token bucket throttle for this client that has the scene token bucket as a parent 170 // Create a token bucket throttle for this client that has the scene token bucket as a parent
166 m_throttle = new TokenBucket(parentThrottle, rates.TotalLimit, rates.Total); 171 m_throttle = new TokenBucket(parentThrottle, rates.TotalLimit, rates.Total);
167 // Create an array of token buckets for this clients different throttle categories 172 // Create an array of token buckets for this clients different throttle categories
@@ -178,7 +183,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
178 } 183 }
179 184
180 // Default the retransmission timeout to three seconds 185 // Default the retransmission timeout to three seconds
181 RTO = 3000; 186 RTO = m_defaultRTO;
182 187
183 // Initialize this to a sane value to prevent early disconnects 188 // Initialize this to a sane value to prevent early disconnects
184 TickLastPacketReceived = Environment.TickCount & Int32.MaxValue; 189 TickLastPacketReceived = Environment.TickCount & Int32.MaxValue;
@@ -500,7 +505,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
500 int rto = (int)(SRTT + Math.Max(m_udpServer.TickCountResolution, K * RTTVAR)); 505 int rto = (int)(SRTT + Math.Max(m_udpServer.TickCountResolution, K * RTTVAR));
501 506
502 // Clamp the retransmission timeout to manageable values 507 // Clamp the retransmission timeout to manageable values
503 rto = Utils.Clamp(RTO, 3000, 60000); 508 rto = Utils.Clamp(RTO, m_defaultRTO, m_maxRTO);
504 509
505 RTO = rto; 510 RTO = rto;
506 511
@@ -520,7 +525,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
520 RTTVAR = 0.0f; 525 RTTVAR = 0.0f;
521 526
522 // Double the retransmission timeout 527 // Double the retransmission timeout
523 RTO = Math.Min(RTO * 2, 60000); 528 RTO = Math.Min(RTO * 2, m_maxRTO);
524 } 529 }
525 530
526 /// <summary> 531 /// <summary>
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index e3233da..93946ae 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -118,13 +118,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
118 /// <summary></summary> 118 /// <summary></summary>
119 //private UDPClientCollection m_clients = new UDPClientCollection(); 119 //private UDPClientCollection m_clients = new UDPClientCollection();
120 /// <summary>Bandwidth throttle for this UDP server</summary> 120 /// <summary>Bandwidth throttle for this UDP server</summary>
121 private TokenBucket m_throttle; 121 protected TokenBucket m_throttle;
122 /// <summary>Bandwidth throttle rates for this UDP server</summary> 122 /// <summary>Bandwidth throttle rates for this UDP server</summary>
123 private ThrottleRates m_throttleRates; 123 protected ThrottleRates m_throttleRates;
124 /// <summary>Manages authentication for agent circuits</summary> 124 /// <summary>Manages authentication for agent circuits</summary>
125 private AgentCircuitManager m_circuitManager; 125 private AgentCircuitManager m_circuitManager;
126 /// <summary>Reference to the scene this UDP server is attached to</summary> 126 /// <summary>Reference to the scene this UDP server is attached to</summary>
127 private Scene m_scene; 127 protected Scene m_scene;
128 /// <summary>The X/Y coordinates of the scene this UDP server is attached to</summary> 128 /// <summary>The X/Y coordinates of the scene this UDP server is attached to</summary>
129 private Location m_location; 129 private Location m_location;
130 /// <summary>The size of the receive buffer for the UDP socket. This value 130 /// <summary>The size of the receive buffer for the UDP socket. This value
@@ -153,6 +153,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
153 /// <summary>Flag to signal when clients should send pings</summary> 153 /// <summary>Flag to signal when clients should send pings</summary>
154 private bool m_sendPing; 154 private bool m_sendPing;
155 155
156 private int m_defaultRTO = 0;
157 private int m_maxRTO = 0;
158
156 public Socket Server { get { return null; } } 159 public Socket Server { get { return null; } }
157 160
158 public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager) 161 public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager)
@@ -189,6 +192,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
189 AvatarTerseUpdatesPerPacket = config.GetInt("AvatarTerseUpdatesPerPacket", 10); 192 AvatarTerseUpdatesPerPacket = config.GetInt("AvatarTerseUpdatesPerPacket", 10);
190 PrimFullUpdatesPerPacket = config.GetInt("PrimFullUpdatesPerPacket", 100); 193 PrimFullUpdatesPerPacket = config.GetInt("PrimFullUpdatesPerPacket", 100);
191 TextureSendLimit = config.GetInt("TextureSendLimit", 20); 194 TextureSendLimit = config.GetInt("TextureSendLimit", 20);
195
196 m_defaultRTO = config.GetInt("DefaultRTO", 0);
197 m_maxRTO = config.GetInt("MaxRTO", 0);
192 } 198 }
193 else 199 else
194 { 200 {
@@ -247,8 +253,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
247 253
248 public void BroadcastPacket(Packet packet, ThrottleOutPacketType category, bool sendToPausedAgents, bool allowSplitting) 254 public void BroadcastPacket(Packet packet, ThrottleOutPacketType category, bool sendToPausedAgents, bool allowSplitting)
249 { 255 {
250 // CoarseLocationUpdate packets cannot be split in an automated way 256 // CoarseLocationUpdate and AvatarGroupsReply packets cannot be split in an automated way
251 if (packet.Type == PacketType.CoarseLocationUpdate && allowSplitting) 257 if ((packet.Type == PacketType.CoarseLocationUpdate || packet.Type == PacketType.AvatarGroupsReply) && allowSplitting)
252 allowSplitting = false; 258 allowSplitting = false;
253 259
254 if (allowSplitting && packet.HasVariableBlocks) 260 if (allowSplitting && packet.HasVariableBlocks)
@@ -256,8 +262,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
256 byte[][] datas = packet.ToBytesMultiple(); 262 byte[][] datas = packet.ToBytesMultiple();
257 int packetCount = datas.Length; 263 int packetCount = datas.Length;
258 264
259 //if (packetCount > 1) 265 if (packetCount < 1)
260 // m_log.Debug("[LLUDPSERVER]: Split " + packet.Type + " packet into " + packetCount + " packets"); 266 m_log.Error("[LLUDPSERVER]: Failed to split " + packet.Type + " with estimated length " + packet.Length);
261 267
262 for (int i = 0; i < packetCount; i++) 268 for (int i = 0; i < packetCount; i++)
263 { 269 {
@@ -295,8 +301,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
295 byte[][] datas = packet.ToBytesMultiple(); 301 byte[][] datas = packet.ToBytesMultiple();
296 int packetCount = datas.Length; 302 int packetCount = datas.Length;
297 303
298 //if (packetCount > 1) 304 if (packetCount < 1)
299 // m_log.Debug("[LLUDPSERVER]: Split " + packet.Type + " packet into " + packetCount + " packets"); 305 m_log.Error("[LLUDPSERVER]: Failed to split " + packet.Type + " with estimated length " + packet.Length);
300 306
301 for (int i = 0; i < packetCount; i++) 307 for (int i = 0; i < packetCount; i++)
302 { 308 {
@@ -409,6 +415,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
409 SendPacket(udpClient, pc, ThrottleOutPacketType.Unknown, false); 415 SendPacket(udpClient, pc, ThrottleOutPacketType.Unknown, false);
410 } 416 }
411 417
418 public void CompletePing(LLUDPClient udpClient, byte pingID)
419 {
420 CompletePingCheckPacket completePing = new CompletePingCheckPacket();
421 completePing.PingID.PingID = pingID;
422 SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false);
423 }
424
412 public void ResendUnacked(LLUDPClient udpClient) 425 public void ResendUnacked(LLUDPClient udpClient)
413 { 426 {
414 if (!udpClient.IsConnected) 427 if (!udpClient.IsConnected)
@@ -429,7 +442,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
429 442
430 if (expiredPackets != null) 443 if (expiredPackets != null)
431 { 444 {
432 m_log.Debug("[LLUDPSERVER]: Resending " + expiredPackets.Count + " packets to " + udpClient.AgentID + ", RTO=" + udpClient.RTO); 445 //m_log.Debug("[LLUDPSERVER]: Resending " + expiredPackets.Count + " packets to " + udpClient.AgentID + ", RTO=" + udpClient.RTO);
433 446
434 // Exponential backoff of the retransmission timeout 447 // Exponential backoff of the retransmission timeout
435 udpClient.BackoffRTO(); 448 udpClient.BackoffRTO();
@@ -585,7 +598,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
585 IClientAPI client; 598 IClientAPI client;
586 if (!m_scene.TryGetClient(address, out client) || !(client is LLClientView)) 599 if (!m_scene.TryGetClient(address, out client) || !(client is LLClientView))
587 { 600 {
588 m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); 601 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
589 return; 602 return;
590 } 603 }
591 604
@@ -669,10 +682,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
669 { 682 {
670 // We don't need to do anything else with ping checks 683 // We don't need to do anything else with ping checks
671 StartPingCheckPacket startPing = (StartPingCheckPacket)packet; 684 StartPingCheckPacket startPing = (StartPingCheckPacket)packet;
672 685 CompletePing(udpClient, startPing.PingID.PingID);
673 CompletePingCheckPacket completePing = new CompletePingCheckPacket();
674 completePing.PingID.PingID = startPing.PingID.PingID;
675 SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false);
676 return; 686 return;
677 } 687 }
678 else if (packet.Type == PacketType.CompletePingCheck) 688 else if (packet.Type == PacketType.CompletePingCheck)
@@ -759,10 +769,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
759 } 769 }
760 } 770 }
761 771
762 private void AddClient(uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo) 772 protected virtual void AddClient(uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo)
763 { 773 {
764 // Create the LLUDPClient 774 // Create the LLUDPClient
765 LLUDPClient udpClient = new LLUDPClient(this, m_throttleRates, m_throttle, circuitCode, agentID, remoteEndPoint); 775 LLUDPClient udpClient = new LLUDPClient(this, m_throttleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
766 IClientAPI existingClient; 776 IClientAPI existingClient;
767 777
768 if (!m_scene.TryGetClient(agentID, out existingClient)) 778 if (!m_scene.TryGetClient(agentID, out existingClient))
@@ -801,6 +811,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
801 { 811 {
802 IncomingPacket incomingPacket = null; 812 IncomingPacket incomingPacket = null;
803 813
814 // HACK: This is a test to try and rate limit packet handling on Mono.
815 // If it works, a more elegant solution can be devised
816 if (Util.FireAndForgetCount() < 2)
817 {
818 //m_log.Debug("[LLUDPSERVER]: Incoming packet handler is sleeping");
819 Thread.Sleep(30);
820 }
821
804 if (packetInbox.Dequeue(100, ref incomingPacket)) 822 if (packetInbox.Dequeue(100, ref incomingPacket))
805 Util.FireAndForget(ProcessInPacket, incomingPacket); 823 Util.FireAndForget(ProcessInPacket, incomingPacket);
806 } 824 }
@@ -968,7 +986,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
968 } 986 }
969 } 987 }
970 988
971 private void LogoutHandler(IClientAPI client) 989 protected void LogoutHandler(IClientAPI client)
972 { 990 {
973 client.SendLogoutPacket(); 991 client.SendLogoutPacket();
974 if (client.IsActive) 992 if (client.IsActive)
diff --git a/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs b/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs
index 008d827..aaf6e26 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs
@@ -87,15 +87,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
87 IConfig throttleConfig = config.Configs["ClientStack.LindenUDP"]; 87 IConfig throttleConfig = config.Configs["ClientStack.LindenUDP"];
88 88
89 Resend = throttleConfig.GetInt("resend_default", 12500); 89 Resend = throttleConfig.GetInt("resend_default", 12500);
90 Land = throttleConfig.GetInt("land_default", 500); 90 Land = throttleConfig.GetInt("land_default", 1000);
91 Wind = throttleConfig.GetInt("wind_default", 500); 91 Wind = throttleConfig.GetInt("wind_default", 1000);
92 Cloud = throttleConfig.GetInt("cloud_default", 500); 92 Cloud = throttleConfig.GetInt("cloud_default", 1000);
93 Task = throttleConfig.GetInt("task_default", 500); 93 Task = throttleConfig.GetInt("task_default", 1000);
94 Texture = throttleConfig.GetInt("texture_default", 500); 94 Texture = throttleConfig.GetInt("texture_default", 1000);
95 Asset = throttleConfig.GetInt("asset_default", 500); 95 Asset = throttleConfig.GetInt("asset_default", 1000);
96 State = throttleConfig.GetInt("state_default", 500); 96 State = throttleConfig.GetInt("state_default", 1000);
97
98 Total = throttleConfig.GetInt("client_throttle_max_bps", 0);
99 97
100 ResendLimit = throttleConfig.GetInt("resend_limit", 18750); 98 ResendLimit = throttleConfig.GetInt("resend_limit", 18750);
101 LandLimit = throttleConfig.GetInt("land_limit", 29750); 99 LandLimit = throttleConfig.GetInt("land_limit", 29750);
@@ -104,9 +102,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
104 TaskLimit = throttleConfig.GetInt("task_limit", 18750); 102 TaskLimit = throttleConfig.GetInt("task_limit", 18750);
105 TextureLimit = throttleConfig.GetInt("texture_limit", 55750); 103 TextureLimit = throttleConfig.GetInt("texture_limit", 55750);
106 AssetLimit = throttleConfig.GetInt("asset_limit", 27500); 104 AssetLimit = throttleConfig.GetInt("asset_limit", 27500);
107 State = throttleConfig.GetInt("state_limit", 37000); 105 StateLimit = throttleConfig.GetInt("state_limit", 37000);
108 106
109 TotalLimit = throttleConfig.GetInt("client_throttle_max_bps", 0); 107 Total = throttleConfig.GetInt("client_throttle_max_bps", 0);
108 TotalLimit = Total;
110 } 109 }
111 catch (Exception) { } 110 catch (Exception) { }
112 } 111 }
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/Alerts/DeadlockAlert.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/Alerts/DeadlockAlert.cs
new file mode 100644
index 0000000..b546ccb
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/Alerts/DeadlockAlert.cs
@@ -0,0 +1,37 @@
1using OpenSim.Region.CoreModules.Framework.Monitoring.Monitors;
2
3namespace OpenSim.Region.CoreModules.Framework.Monitoring.Alerts
4{
5 class DeadlockAlert : IAlert
6 {
7 private LastFrameTimeMonitor m_monitor;
8
9 public DeadlockAlert(LastFrameTimeMonitor m_monitor)
10 {
11 this.m_monitor = m_monitor;
12 }
13
14 #region Implementation of IAlert
15
16 public string GetName()
17 {
18 return "Potential Deadlock Alert";
19 }
20
21 public void Test()
22 {
23 if (m_monitor.GetValue() > 60 * 1000)
24 {
25 if(OnTriggerAlert != null)
26 {
27 OnTriggerAlert(typeof (DeadlockAlert),
28 (int) (m_monitor.GetValue()/1000) + " second(s) since last frame processed.", true);
29 }
30 }
31 }
32
33 public event Alert OnTriggerAlert;
34
35 #endregion
36 }
37}
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/IAlert.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/IAlert.cs
new file mode 100644
index 0000000..b533df9
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/IAlert.cs
@@ -0,0 +1,13 @@
1using System;
2
3namespace OpenSim.Region.CoreModules.Framework.Monitoring
4{
5 internal delegate void Alert(Type reporter, string reason, bool fatal);
6
7 interface IAlert
8 {
9 string GetName();
10 void Test();
11 event Alert OnTriggerAlert;
12 }
13}
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/IMonitor.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/IMonitor.cs
new file mode 100644
index 0000000..a51dccd
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/IMonitor.cs
@@ -0,0 +1,9 @@
1namespace OpenSim.Region.CoreModules.Framework.Monitoring
2{
3 interface IMonitor
4 {
5 double GetValue();
6 string GetName();
7 string GetFriendlyValue(); // Convert to readable numbers
8 }
9}
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
new file mode 100644
index 0000000..769af8d
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
@@ -0,0 +1,93 @@
1using System.Collections.Generic;
2using System.Reflection;
3using log4net;
4using Nini.Config;
5using OpenSim.Region.CoreModules.Framework.Monitoring.Alerts;
6using OpenSim.Region.CoreModules.Framework.Monitoring.Monitors;
7using OpenSim.Region.Framework.Interfaces;
8using OpenSim.Region.Framework.Scenes;
9
10namespace OpenSim.Region.CoreModules.Framework.Monitoring
11{
12 public class MonitorModule : IRegionModule
13 {
14 private Scene m_scene;
15 private readonly List<IMonitor> m_monitors = new List<IMonitor>();
16 private readonly List<IAlert> m_alerts = new List<IAlert>();
17 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
18
19 public void DebugMonitors(string module, string[] args)
20 {
21 foreach (IMonitor monitor in m_monitors)
22 {
23 m_log.Info("[MonitorModule] " + m_scene.RegionInfo.RegionName + " reports " + monitor.GetName() + " = " + monitor.GetFriendlyValue());
24 }
25 }
26
27 public void TestAlerts()
28 {
29 foreach (IAlert alert in m_alerts)
30 {
31 alert.Test();
32 }
33 }
34
35 #region Implementation of IRegionModule
36
37 public void Initialise(Scene scene, IConfigSource source)
38 {
39 m_scene = scene;
40
41
42 m_scene.AddCommand(this, "monitor report",
43 "monitor report",
44 "Returns a variety of statistics about the current region and/or simulator",
45 DebugMonitors);
46 }
47
48 public void PostInitialise()
49 {
50 m_monitors.Add(new AgentCountMonitor(m_scene));
51 m_monitors.Add(new ChildAgentCountMonitor(m_scene));
52 m_monitors.Add(new GCMemoryMonitor());
53 m_monitors.Add(new ObjectCountMonitor(m_scene));
54 m_monitors.Add(new PhysicsFrameMonitor(m_scene));
55 m_monitors.Add(new PhysicsUpdateFrameMonitor(m_scene));
56 m_monitors.Add(new PWSMemoryMonitor());
57 m_monitors.Add(new ThreadCountMonitor());
58 m_monitors.Add(new TotalFrameMonitor(m_scene));
59 m_monitors.Add(new EventFrameMonitor(m_scene));
60 m_monitors.Add(new LandFrameMonitor(m_scene));
61 m_monitors.Add(new LastFrameTimeMonitor(m_scene));
62
63 m_alerts.Add(new DeadlockAlert(m_monitors.Find(x => x is LastFrameTimeMonitor) as LastFrameTimeMonitor));
64
65 foreach (IAlert alert in m_alerts)
66 {
67 alert.OnTriggerAlert += OnTriggerAlert;
68 }
69 }
70
71 void OnTriggerAlert(System.Type reporter, string reason, bool fatal)
72 {
73 m_log.Error("[Monitor] " + reporter.Name + " for " + m_scene.RegionInfo.RegionName + " reports " + reason + " (Fatal: " + fatal + ")");
74 }
75
76 public void Close()
77 {
78
79 }
80
81 public string Name
82 {
83 get { return "Region Health Monitoring Module"; }
84 }
85
86 public bool IsSharedModule
87 {
88 get { return false; }
89 }
90
91 #endregion
92 }
93}
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/AgentCountMonitor.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/AgentCountMonitor.cs
new file mode 100644
index 0000000..edc6e6b
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/AgentCountMonitor.cs
@@ -0,0 +1,33 @@
1using OpenSim.Region.Framework.Scenes;
2
3namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors
4{
5 class AgentCountMonitor : IMonitor
6 {
7 private readonly Scene m_scene;
8
9 public AgentCountMonitor(Scene scene)
10 {
11 m_scene = scene;
12 }
13
14 #region Implementation of IMonitor
15
16 public double GetValue()
17 {
18 return m_scene.SceneGraph.GetRootAgentCount();
19 }
20
21 public string GetName()
22 {
23 return "Root Agent Count";
24 }
25
26 public string GetFriendlyValue()
27 {
28 return (int)GetValue() + " agent(s)";
29 }
30
31 #endregion
32 }
33}
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/ChildAgentCountMonitor.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/ChildAgentCountMonitor.cs
new file mode 100644
index 0000000..afe6b79
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/ChildAgentCountMonitor.cs
@@ -0,0 +1,33 @@
1using OpenSim.Region.Framework.Scenes;
2
3namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors
4{
5 class ChildAgentCountMonitor : IMonitor
6 {
7 private readonly Scene m_scene;
8
9 public ChildAgentCountMonitor(Scene scene)
10 {
11 m_scene = scene;
12 }
13
14 #region Implementation of IMonitor
15
16 public double GetValue()
17 {
18 return m_scene.SceneGraph.GetChildAgentCount();
19 }
20
21 public string GetName()
22 {
23 return "Child Agent Count";
24 }
25
26 public string GetFriendlyValue()
27 {
28 return (int)GetValue() + " child agent(s)";
29 }
30
31 #endregion
32 }
33}
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/EventFrameMonitor.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/EventFrameMonitor.cs
new file mode 100644
index 0000000..dec5a9e
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/EventFrameMonitor.cs
@@ -0,0 +1,33 @@
1using OpenSim.Region.Framework.Scenes;
2
3namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors
4{
5 class EventFrameMonitor : IMonitor
6 {
7 private readonly Scene m_scene;
8
9 public EventFrameMonitor(Scene scene)
10 {
11 m_scene = scene;
12 }
13
14 #region Implementation of IMonitor
15
16 public double GetValue()
17 {
18 return m_scene.MonitorEventTime;
19 }
20
21 public string GetName()
22 {
23 return "Total Event Frame Time";
24 }
25
26 public string GetFriendlyValue()
27 {
28 return (int)GetValue() + "ms";
29 }
30
31 #endregion
32 }
33}
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/GCMemoryMonitor.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/GCMemoryMonitor.cs
new file mode 100644
index 0000000..cd67fea
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/GCMemoryMonitor.cs
@@ -0,0 +1,26 @@
1using System;
2
3namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors
4{
5 class GCMemoryMonitor : IMonitor
6 {
7 #region Implementation of IMonitor
8
9 public double GetValue()
10 {
11 return GC.GetTotalMemory(false);
12 }
13
14 public string GetName()
15 {
16 return "GC Reported Memory";
17 }
18
19 public string GetFriendlyValue()
20 {
21 return (int)(GetValue() / (1024*1024)) + "MB (Global)";
22 }
23
24 #endregion
25 }
26}
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/LandFrameMonitor.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/LandFrameMonitor.cs
new file mode 100644
index 0000000..d883fc7
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/LandFrameMonitor.cs
@@ -0,0 +1,33 @@
1using OpenSim.Region.Framework.Scenes;
2
3namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors
4{
5 class LandFrameMonitor : IMonitor
6 {
7 private readonly Scene m_scene;
8
9 public LandFrameMonitor(Scene scene)
10 {
11 m_scene = scene;
12 }
13
14 #region Implementation of IMonitor
15
16 public double GetValue()
17 {
18 return m_scene.MonitorLandTime;
19 }
20
21 public string GetName()
22 {
23 return "Land Frame Time";
24 }
25
26 public string GetFriendlyValue()
27 {
28 return (int)GetValue() + "ms";
29 }
30
31 #endregion
32 }
33}
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/LastFrameTimeMonitor.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/LastFrameTimeMonitor.cs
new file mode 100644
index 0000000..36363f8
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/LastFrameTimeMonitor.cs
@@ -0,0 +1,34 @@
1using System;
2using OpenSim.Region.Framework.Scenes;
3
4namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors
5{
6 class LastFrameTimeMonitor : IMonitor
7 {
8 private readonly Scene m_scene;
9
10 public LastFrameTimeMonitor(Scene scene)
11 {
12 m_scene = scene;
13 }
14
15 #region Implementation of IMonitor
16
17 public double GetValue()
18 {
19 return Environment.TickCount - m_scene.MonitorLastFrameTick;
20 }
21
22 public string GetName()
23 {
24 return "Last Completed Frame At";
25 }
26
27 public string GetFriendlyValue()
28 {
29 return (int)GetValue() + "ms ago";
30 }
31
32 #endregion
33 }
34}
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/ObjectCountMonitor.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/ObjectCountMonitor.cs
new file mode 100644
index 0000000..dd9b19d
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/ObjectCountMonitor.cs
@@ -0,0 +1,33 @@
1using OpenSim.Region.Framework.Scenes;
2
3namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors
4{
5 class ObjectCountMonitor : IMonitor
6 {
7 private readonly Scene m_scene;
8
9 public ObjectCountMonitor(Scene scene)
10 {
11 m_scene = scene;
12 }
13
14 #region Implementation of IMonitor
15
16 public double GetValue()
17 {
18 return m_scene.SceneGraph.GetTotalObjectsCount();
19 }
20
21 public string GetName()
22 {
23 return "Total Objects Count";
24 }
25
26 public string GetFriendlyValue()
27 {
28 return (int)GetValue() + " Object(s)";
29 }
30
31 #endregion
32 }
33}
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/PWSMemoryMonitor.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/PWSMemoryMonitor.cs
new file mode 100644
index 0000000..88f2938
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/PWSMemoryMonitor.cs
@@ -0,0 +1,26 @@
1using System;
2
3namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors
4{
5 class PWSMemoryMonitor : IMonitor
6 {
7 #region Implementation of IMonitor
8
9 public double GetValue()
10 {
11 return System.Diagnostics.Process.GetCurrentProcess().PrivateMemorySize64;
12 }
13
14 public string GetName()
15 {
16 return "Private Working Set Memory";
17 }
18
19 public string GetFriendlyValue()
20 {
21 return (int)(GetValue() / (1024 * 1024)) + "MB (Global)";
22 }
23
24 #endregion
25 }
26}
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/PhysicsFrameMonitor.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/PhysicsFrameMonitor.cs
new file mode 100644
index 0000000..4d62e4f
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/PhysicsFrameMonitor.cs
@@ -0,0 +1,33 @@
1using OpenSim.Region.Framework.Scenes;
2
3namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors
4{
5 class PhysicsFrameMonitor : IMonitor
6 {
7 private readonly Scene m_scene;
8
9 public PhysicsFrameMonitor(Scene scene)
10 {
11 m_scene = scene;
12 }
13
14 #region Implementation of IMonitor
15
16 public double GetValue()
17 {
18 return m_scene.MonitorPhysicsSyncTime + m_scene.MonitorPhysicsUpdateTime;
19 }
20
21 public string GetName()
22 {
23 return "Total Physics Frame Time";
24 }
25
26 public string GetFriendlyValue()
27 {
28 return (int)GetValue() + "ms";
29 }
30
31 #endregion
32 }
33}
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/PhysicsUpdateFrameMonitor.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/PhysicsUpdateFrameMonitor.cs
new file mode 100644
index 0000000..91ac282
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/PhysicsUpdateFrameMonitor.cs
@@ -0,0 +1,33 @@
1using OpenSim.Region.Framework.Scenes;
2
3namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors
4{
5 class PhysicsUpdateFrameMonitor : IMonitor
6 {
7 private readonly Scene m_scene;
8
9 public PhysicsUpdateFrameMonitor(Scene scene)
10 {
11 m_scene = scene;
12 }
13
14 #region Implementation of IMonitor
15
16 public double GetValue()
17 {
18 return m_scene.MonitorPhysicsUpdateTime;
19 }
20
21 public string GetName()
22 {
23 return "Physics Update Frame Time";
24 }
25
26 public string GetFriendlyValue()
27 {
28 return (int)GetValue() + "ms";
29 }
30
31 #endregion
32 }
33}
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/ThreadCountMonitor.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/ThreadCountMonitor.cs
new file mode 100644
index 0000000..9300a93
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/ThreadCountMonitor.cs
@@ -0,0 +1,25 @@
1
2namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors
3{
4 class ThreadCountMonitor : IMonitor
5 {
6 #region Implementation of IMonitor
7
8 public double GetValue()
9 {
10 return System.Diagnostics.Process.GetCurrentProcess().Threads.Count;
11 }
12
13 public string GetName()
14 {
15 return "Total Threads";
16 }
17
18 public string GetFriendlyValue()
19 {
20 return (int)GetValue() + " Thread(s) (Global)";
21 }
22
23 #endregion
24 }
25}
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/TotalFrameMonitor.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/TotalFrameMonitor.cs
new file mode 100644
index 0000000..dea1f94
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/TotalFrameMonitor.cs
@@ -0,0 +1,33 @@
1using OpenSim.Region.Framework.Scenes;
2
3namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors
4{
5 class TotalFrameMonitor : IMonitor
6 {
7 private readonly Scene m_scene;
8
9 public TotalFrameMonitor(Scene scene)
10 {
11 m_scene = scene;
12 }
13
14 #region Implementation of IMonitor
15
16 public double GetValue()
17 {
18 return m_scene.MonitorFrameTime;
19 }
20
21 public string GetName()
22 {
23 return "Total Frame Time";
24 }
25
26 public string GetFriendlyValue()
27 {
28 return (int)GetValue() + "ms";
29 }
30
31 #endregion
32 }
33}
diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs
index 4199c98..46ee3c0 100644
--- a/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs
+++ b/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs
@@ -193,6 +193,10 @@ namespace OpenSim.Region.CoreModules.Hypergrid
193 { 193 {
194 return scene.RegionInfo; 194 return scene.RegionInfo;
195 } 195 }
196 else if (m_scenes.Count > 0)
197 {
198 return m_scenes[0].RegionInfo;
199 }
196 return null; 200 return null;
197 } 201 }
198 202
@@ -248,7 +252,7 @@ namespace OpenSim.Region.CoreModules.Hypergrid
248 { 252 {
249 foreach (Scene nextScene in m_scenes) 253 foreach (Scene nextScene in m_scenes)
250 { 254 {
251 if (nextScene.RegionInfo.RegionName == regionName) 255 if (nextScene.RegionInfo.RegionName.Equals(regionName, StringComparison.InvariantCultureIgnoreCase))
252 { 256 {
253 scene = nextScene; 257 scene = nextScene;
254 return true; 258 return true;
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs
index 046bee5..9c04755 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs
@@ -322,10 +322,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
322 { 322 {
323 List<GridRegion> rinfos = new List<GridRegion>(); 323 List<GridRegion> rinfos = new List<GridRegion>();
324 324
325 // Commenting until regionname exists 325 if (name == string.Empty)
326 //foreach (SimpleRegionInfo r in m_HyperlinkRegions.Values) 326 return rinfos;
327 // if ((r.RegionName != null) && r.RegionName.StartsWith(name)) 327
328 // rinfos.Add(r); 328 foreach (GridRegion r in m_HyperlinkRegions.Values)
329 if ((r.RegionName != null) && r.RegionName.ToLower().StartsWith(name.ToLower()))
330 rinfos.Add(r);
329 331
330 rinfos.AddRange(m_GridServiceConnector.GetRegionsByName(scopeID, name, maxNumber)); 332 rinfos.AddRange(m_GridServiceConnector.GetRegionsByName(scopeID, name, maxNumber));
331 return rinfos; 333 return rinfos;
@@ -602,6 +604,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
602 { 604 {
603 CachedUserInfo uinfo = m_aScene.CommsManager.UserProfileCacheService.GetUserDetails(agentData.AgentID); 605 CachedUserInfo uinfo = m_aScene.CommsManager.UserProfileCacheService.GetUserDetails(agentData.AgentID);
604 606
607 if (uinfo == null)
608 return false;
609
605 if ((IsLocalUser(uinfo) && (GetHyperlinkRegion(regInfo.RegionHandle) != null)) || 610 if ((IsLocalUser(uinfo) && (GetHyperlinkRegion(regInfo.RegionHandle) != null)) ||
606 (!IsLocalUser(uinfo) && !IsGoingHome(uinfo, regInfo))) 611 (!IsLocalUser(uinfo) && !IsGoingHome(uinfo, regInfo)))
607 { 612 {
@@ -735,6 +740,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
735 // Is the user going back to the home region or the home grid? 740 // Is the user going back to the home region or the home grid?
736 protected bool IsGoingHome(CachedUserInfo uinfo, GridRegion rinfo) 741 protected bool IsGoingHome(CachedUserInfo uinfo, GridRegion rinfo)
737 { 742 {
743 if (uinfo == null)
744 return false;
745
738 if (uinfo.UserProfile == null) 746 if (uinfo.UserProfile == null)
739 return false; 747 return false;
740 748
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index 54acbc4..c261943 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -129,6 +129,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
129 successfulAssetRestores++; 129 successfulAssetRestores++;
130 else 130 else
131 failedAssetRestores++; 131 failedAssetRestores++;
132
133 if ((successfulAssetRestores + failedAssetRestores) % 250 == 0)
134 m_log.Debug("[ARCHIVER]: Loaded " + successfulAssetRestores + " assets and failed to load " + failedAssetRestores + " assets...");
132 } 135 }
133 else if (!m_merge && filePath.StartsWith(ArchiveConstants.TERRAINS_PATH)) 136 else if (!m_merge && filePath.StartsWith(ArchiveConstants.TERRAINS_PATH))
134 { 137 {
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
index d01cef7..d1d6b6a 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
@@ -35,7 +35,7 @@ using OpenSim.Region.Framework.Interfaces;
35namespace OpenSim.Region.Framework.Scenes 35namespace OpenSim.Region.Framework.Scenes
36{ 36{
37 #region Delegates 37 #region Delegates
38 public delegate uint GenerateClientFlagsHandler(UUID userID, UUID objectIDID); 38 public delegate uint GenerateClientFlagsHandler(UUID userID, UUID objectID);
39 public delegate void SetBypassPermissionsHandler(bool value); 39 public delegate void SetBypassPermissionsHandler(bool value);
40 public delegate bool BypassPermissionsHandler(); 40 public delegate bool BypassPermissionsHandler();
41 public delegate bool PropagatePermissionsHandler(); 41 public delegate bool PropagatePermissionsHandler();
@@ -147,28 +147,28 @@ namespace OpenSim.Region.Framework.Scenes
147 147
148 public uint GenerateClientFlags(UUID userID, UUID objectID) 148 public uint GenerateClientFlags(UUID userID, UUID objectID)
149 { 149 {
150 SceneObjectPart part=m_scene.GetSceneObjectPart(objectID); 150 // libomv will moan about PrimFlags.ObjectYouOfficer being
151 // obsolete...
152#pragma warning disable 0612
153 const PrimFlags DEFAULT_FLAGS =
154 PrimFlags.ObjectModify |
155 PrimFlags.ObjectCopy |
156 PrimFlags.ObjectMove |
157 PrimFlags.ObjectTransfer |
158 PrimFlags.ObjectYouOwner |
159 PrimFlags.ObjectAnyOwner |
160 PrimFlags.ObjectOwnerModify |
161 PrimFlags.ObjectYouOfficer;
162#pragma warning restore 0612
163
164 SceneObjectPart part = m_scene.GetSceneObjectPart(objectID);
151 165
152 if (part == null) 166 if (part == null)
153 return 0; 167 return 0;
154 168
155 // libomv will moan about PrimFlags.ObjectYouOfficer being 169 uint perms = part.GetEffectiveObjectFlags() | (uint)DEFAULT_FLAGS;
156 // obsolete...
157 #pragma warning disable 0612
158 uint perms=part.GetEffectiveObjectFlags() |
159 (uint)PrimFlags.ObjectModify |
160 (uint)PrimFlags.ObjectCopy |
161 (uint)PrimFlags.ObjectMove |
162 (uint)PrimFlags.ObjectTransfer |
163 (uint)PrimFlags.ObjectYouOwner |
164 (uint)PrimFlags.ObjectAnyOwner |
165 (uint)PrimFlags.ObjectOwnerModify |
166 (uint)PrimFlags.ObjectYouOfficer;
167 #pragma warning restore 0612
168
169 GenerateClientFlagsHandler handlerGenerateClientFlags =
170 OnGenerateClientFlags;
171 170
171 GenerateClientFlagsHandler handlerGenerateClientFlags = OnGenerateClientFlags;
172 if (handlerGenerateClientFlags != null) 172 if (handlerGenerateClientFlags != null)
173 { 173 {
174 Delegate[] list = handlerGenerateClientFlags.GetInvocationList(); 174 Delegate[] list = handlerGenerateClientFlags.GetInvocationList();
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 7c3875d..a6ee40a 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -135,6 +135,11 @@ namespace OpenSim.Region.Framework.Scenes
135 protected SceneCommunicationService m_sceneGridService; 135 protected SceneCommunicationService m_sceneGridService;
136 public bool loginsdisabled = true; 136 public bool loginsdisabled = true;
137 137
138 public new float TimeDilation
139 {
140 get { return m_sceneGraph.PhysicsScene.TimeDilation; }
141 }
142
138 public SceneCommunicationService SceneGridService 143 public SceneCommunicationService SceneGridService
139 { 144 {
140 get { return m_sceneGridService; } 145 get { return m_sceneGridService; }
@@ -252,7 +257,7 @@ namespace OpenSim.Region.Framework.Scenes
252 // Central Update Loop 257 // Central Update Loop
253 258
254 protected int m_fps = 10; 259 protected int m_fps = 10;
255 protected int m_frame; 260 protected uint m_frame;
256 protected float m_timespan = 0.089f; 261 protected float m_timespan = 0.089f;
257 protected DateTime m_lastupdate = DateTime.UtcNow; 262 protected DateTime m_lastupdate = DateTime.UtcNow;
258 263
@@ -269,6 +274,23 @@ namespace OpenSim.Region.Framework.Scenes
269 private int physicsMS2; 274 private int physicsMS2;
270 private int physicsMS; 275 private int physicsMS;
271 private int otherMS; 276 private int otherMS;
277 private int tempOnRezMS;
278 private int eventMS;
279 private int backupMS;
280 private int terrainMS;
281 private int landMS;
282 private int lastCompletedFrame;
283
284 public int MonitorFrameTime { get { return frameMS; } }
285 public int MonitorPhysicsUpdateTime { get { return physicsMS; } }
286 public int MonitorPhysicsSyncTime { get { return physicsMS2; } }
287 public int MonitorOtherTime { get { return otherMS; } }
288 public int MonitorTempOnRezTime { get { return tempOnRezMS; } }
289 public int MonitorEventTime { get { return eventMS; } } // This may need to be divided into each event?
290 public int MonitorBackupTime { get { return backupMS; } }
291 public int MonitorTerrainTime { get { return terrainMS; } }
292 public int MonitorLandTime { get { return landMS; } }
293 public int MonitorLastFrameTick { get { return lastCompletedFrame; } }
272 294
273 private bool m_physics_enabled = true; 295 private bool m_physics_enabled = true;
274 private bool m_scripts_enabled = true; 296 private bool m_scripts_enabled = true;
@@ -1013,36 +1035,25 @@ namespace OpenSim.Region.Framework.Scenes
1013 /// </summary> 1035 /// </summary>
1014 public override void Update() 1036 public override void Update()
1015 { 1037 {
1016 int maintc = 0; 1038 float physicsFPS;
1039 int maintc;
1040
1017 while (!shuttingdown) 1041 while (!shuttingdown)
1018 { 1042 {
1019//#if DEBUG
1020// int w = 0, io = 0;
1021// ThreadPool.GetAvailableThreads(out w, out io);
1022// if ((w < 10) || (io < 10))
1023// m_log.DebugFormat("[WARNING]: ThreadPool reaching exhaustion. workers = {0}; io = {1}", w, io);
1024//#endif
1025 maintc = Environment.TickCount;
1026
1027 TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastupdate; 1043 TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastupdate;
1028 float physicsFPS = 0; 1044 physicsFPS = 0f;
1045
1046 maintc = maintc = otherMS = Environment.TickCount;
1047 int tmpFrameMS = maintc;
1029 1048
1030 frameMS = Environment.TickCount; 1049 // Increment the frame counter
1050 ++m_frame;
1031 1051
1032 try 1052 try
1033 { 1053 {
1034 // Increment the frame counter
1035 m_frame++;
1036
1037 // Loop it
1038 if (m_frame == Int32.MaxValue)
1039 m_frame = 0;
1040
1041 otherMS = Environment.TickCount;
1042
1043 // Check if any objects have reached their targets 1054 // Check if any objects have reached their targets
1044 CheckAtTargets(); 1055 CheckAtTargets();
1045 1056
1046 // Update SceneObjectGroups that have scheduled themselves for updates 1057 // Update SceneObjectGroups that have scheduled themselves for updates
1047 // Objects queue their updates onto all scene presences 1058 // Objects queue their updates onto all scene presences
1048 if (m_frame % m_update_objects == 0) 1059 if (m_frame % m_update_objects == 0)
@@ -1053,62 +1064,92 @@ namespace OpenSim.Region.Framework.Scenes
1053 if (m_frame % m_update_presences == 0) 1064 if (m_frame % m_update_presences == 0)
1054 m_sceneGraph.UpdatePresences(); 1065 m_sceneGraph.UpdatePresences();
1055 1066
1056 physicsMS2 = Environment.TickCount; 1067 int TempPhysicsMS2 = Environment.TickCount;
1057 if ((m_frame % m_update_physics == 0) && m_physics_enabled) 1068 if ((m_frame % m_update_physics == 0) && m_physics_enabled)
1058 m_sceneGraph.UpdatePreparePhysics(); 1069 m_sceneGraph.UpdatePreparePhysics();
1059 physicsMS2 = Environment.TickCount - physicsMS2; 1070 TempPhysicsMS2 = Environment.TickCount - TempPhysicsMS2;
1071 physicsMS2 = TempPhysicsMS2;
1060 1072
1061 if (m_frame % m_update_entitymovement == 0) 1073 if (m_frame % m_update_entitymovement == 0)
1062 m_sceneGraph.UpdateScenePresenceMovement(); 1074 m_sceneGraph.UpdateScenePresenceMovement();
1063 1075
1064 physicsMS = Environment.TickCount; 1076 int TempPhysicsMS = Environment.TickCount;
1065 if ((m_frame % m_update_physics == 0) && m_physics_enabled) 1077 if (m_frame % m_update_physics == 0)
1066 physicsFPS = m_sceneGraph.UpdatePhysics( 1078 {
1067 Math.Max(SinceLastFrame.TotalSeconds, m_timespan) 1079 if (m_physics_enabled)
1068 ); 1080 physicsFPS = m_sceneGraph.UpdatePhysics(Math.Max(SinceLastFrame.TotalSeconds, m_timespan));
1069 if (m_frame % m_update_physics == 0 && SynchronizeScene != null) 1081 if (SynchronizeScene != null)
1070 SynchronizeScene(this); 1082 SynchronizeScene(this);
1071 1083 }
1072 physicsMS = Environment.TickCount - physicsMS; 1084 TempPhysicsMS = Environment.TickCount - TempPhysicsMS;
1073 physicsMS += physicsMS2; 1085 physicsMS = TempPhysicsMS;
1074 1086
1075 // Delete temp-on-rez stuff 1087 // Delete temp-on-rez stuff
1076 if (m_frame % m_update_backup == 0) 1088 if (m_frame % m_update_backup == 0)
1089 {
1090 int tozMS = Environment.TickCount;
1077 CleanTempObjects(); 1091 CleanTempObjects();
1092 tozMS -= Environment.TickCount;
1093 tempOnRezMS = tozMS;
1094 }
1078 1095
1079 if (RegionStatus != RegionStatus.SlaveScene) 1096 if (RegionStatus != RegionStatus.SlaveScene)
1080 { 1097 {
1081 if (m_frame % m_update_events == 0) 1098 if (m_frame % m_update_events == 0)
1099 {
1100 int evMS = Environment.TickCount;
1082 UpdateEvents(); 1101 UpdateEvents();
1102 evMS -= Environment.TickCount;
1103 eventMS = evMS;
1104 }
1083 1105
1084 if (m_frame % m_update_backup == 0) 1106 if (m_frame % m_update_backup == 0)
1107 {
1108 int backMS = Environment.TickCount;
1085 UpdateStorageBackup(); 1109 UpdateStorageBackup();
1110 backMS -= Environment.TickCount;
1111 backupMS = backMS;
1112 }
1086 1113
1087 if (m_frame % m_update_terrain == 0) 1114 if (m_frame % m_update_terrain == 0)
1115 {
1116 int terMS = Environment.TickCount;
1088 UpdateTerrain(); 1117 UpdateTerrain();
1118 terMS -= Environment.TickCount;
1119 terrainMS = terMS;
1120 }
1089 1121
1090 if (m_frame % m_update_land == 0) 1122 if (m_frame % m_update_land == 0)
1123 {
1124 int ldMS = Environment.TickCount;
1091 UpdateLand(); 1125 UpdateLand();
1126 ldMS -= Environment.TickCount;
1127 landMS = ldMS;
1128 }
1129
1130 int tickCount = Environment.TickCount;
1131 otherMS = tickCount - otherMS;
1132 tmpFrameMS -= tickCount;
1133 frameMS = tmpFrameMS;
1134 lastCompletedFrame = tickCount;
1092 1135
1093 otherMS = Environment.TickCount - otherMS;
1094 // if (m_frame%m_update_avatars == 0) 1136 // if (m_frame%m_update_avatars == 0)
1095 // UpdateInWorldTime(); 1137 // UpdateInWorldTime();
1096 StatsReporter.AddPhysicsFPS(physicsFPS); 1138 StatsReporter.AddPhysicsFPS(physicsFPS);
1097 StatsReporter.AddTimeDilation(m_timedilation); 1139 StatsReporter.AddTimeDilation(TimeDilation);
1098 StatsReporter.AddFPS(1); 1140 StatsReporter.AddFPS(1);
1099 StatsReporter.AddInPackets(0);
1100 StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount()); 1141 StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
1101 StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount()); 1142 StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
1102 StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount()); 1143 StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
1103 StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount()); 1144 StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
1104 frameMS = Environment.TickCount - frameMS;
1105 StatsReporter.addFrameMS(frameMS); 1145 StatsReporter.addFrameMS(frameMS);
1106 StatsReporter.addPhysicsMS(physicsMS); 1146 StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
1107 StatsReporter.addOtherMS(otherMS); 1147 StatsReporter.addOtherMS(otherMS);
1108 StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount()); 1148 StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
1109 StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS()); 1149 StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
1110 } 1150 }
1111 if (loginsdisabled && (m_frame > 20)) 1151
1152 if (loginsdisabled && m_frame > 20)
1112 { 1153 {
1113 // In 99.9% of cases it is a bad idea to manually force garbage collection. However, 1154 // 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 1155 // this is a rare case where we know we have just went through a long cycle of heap
@@ -1141,18 +1182,6 @@ namespace OpenSim.Region.Framework.Scenes
1141 } 1182 }
1142 finally 1183 finally
1143 { 1184 {
1144 //updateLock.ReleaseMutex();
1145 // Get actual time dilation
1146 float tmpval = (m_timespan / (float)SinceLastFrame.TotalSeconds);
1147
1148 // If actual time dilation is greater then one, we're catching up, so subtract
1149 // the amount that's greater then 1 from the time dilation
1150 if (tmpval > 1.0)
1151 {
1152 tmpval = tmpval - (tmpval - 1.0f);
1153 }
1154 m_timedilation = tmpval;
1155
1156 m_lastupdate = DateTime.UtcNow; 1185 m_lastupdate = DateTime.UtcNow;
1157 } 1186 }
1158 maintc = Environment.TickCount - maintc; 1187 maintc = Environment.TickCount - maintc;
@@ -1183,9 +1212,9 @@ namespace OpenSim.Region.Framework.Scenes
1183 { 1212 {
1184 lock (m_groupsWithTargets) 1213 lock (m_groupsWithTargets)
1185 { 1214 {
1186 foreach (KeyValuePair<UUID, SceneObjectGroup> kvp in m_groupsWithTargets) 1215 foreach (SceneObjectGroup entry in m_groupsWithTargets.Values)
1187 { 1216 {
1188 kvp.Value.checkAtTargets(); 1217 entry.checkAtTargets();
1189 } 1218 }
1190 } 1219 }
1191 } 1220 }
@@ -4606,7 +4635,7 @@ namespace OpenSim.Region.Framework.Scenes
4606 SceneObjectPart trackedBody = GetSceneObjectPart(joint.TrackedBodyName); // FIXME: causes a sequential lookup 4635 SceneObjectPart trackedBody = GetSceneObjectPart(joint.TrackedBodyName); // FIXME: causes a sequential lookup
4607 if (trackedBody == null) return; // the actor may have been deleted but the joint still lingers around a few frames waiting for deletion. during this time, trackedBody is NULL to prevent further motion of the joint proxy. 4636 if (trackedBody == null) return; // the actor may have been deleted but the joint still lingers around a few frames waiting for deletion. during this time, trackedBody is NULL to prevent further motion of the joint proxy.
4608 jointProxyObject.Velocity = trackedBody.Velocity; 4637 jointProxyObject.Velocity = trackedBody.Velocity;
4609 jointProxyObject.RotationalVelocity = trackedBody.RotationalVelocity; 4638 jointProxyObject.AngularVelocity = trackedBody.AngularVelocity;
4610 switch (joint.Type) 4639 switch (joint.Type)
4611 { 4640 {
4612 case PhysicsJointType.Ball: 4641 case PhysicsJointType.Ball:
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs
index 82731d1..1547f9a 100644
--- a/OpenSim/Region/Framework/Scenes/SceneBase.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs
@@ -106,9 +106,8 @@ namespace OpenSim.Region.Framework.Scenes
106 106
107 public float TimeDilation 107 public float TimeDilation
108 { 108 {
109 get { return m_timedilation; } 109 get { return 1.0f; }
110 } 110 }
111 protected float m_timedilation = 1.0f;
112 111
113 protected ulong m_regionHandle; 112 protected ulong m_regionHandle;
114 protected string m_regionName; 113 protected string m_regionName;
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index db055f9..2fdb48d 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -369,26 +369,30 @@ namespace OpenSim.Region.Framework.Scenes
369 /// </summary> 369 /// </summary>
370 protected internal void UpdateObjectGroups() 370 protected internal void UpdateObjectGroups()
371 { 371 {
372 Dictionary<UUID, SceneObjectGroup> updates; 372 List<SceneObjectGroup> updates;
373
373 // Some updates add more updates to the updateList. 374 // Some updates add more updates to the updateList.
374 // Get the current list of updates and clear the list before iterating 375 // Get the current list of updates and clear the list before iterating
375 lock (m_updateList) 376 lock (m_updateList)
376 { 377 {
377 updates = new Dictionary<UUID, SceneObjectGroup>(m_updateList); 378 updates = new List<SceneObjectGroup>(m_updateList.Values);
378 m_updateList.Clear(); 379 m_updateList.Clear();
379 } 380 }
381
380 // Go through all updates 382 // Go through all updates
381 foreach (KeyValuePair<UUID, SceneObjectGroup> kvp in updates) 383 for (int i = 0; i < updates.Count; i++)
382 { 384 {
385 SceneObjectGroup sog = updates[i];
386
383 // Don't abort the whole update if one entity happens to give us an exception. 387 // Don't abort the whole update if one entity happens to give us an exception.
384 try 388 try
385 { 389 {
386 kvp.Value.Update(); 390 sog.Update();
387 } 391 }
388 catch (Exception e) 392 catch (Exception e)
389 { 393 {
390 m_log.ErrorFormat( 394 m_log.ErrorFormat(
391 "[INNER SCENE]: Failed to update {0}, {1} - {2}", kvp.Value.Name, kvp.Value.UUID, e); 395 "[INNER SCENE]: Failed to update {0}, {1} - {2}", sog.Name, sog.UUID, e);
392 } 396 }
393 } 397 }
394 } 398 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 38a0cff..c65a665 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -1015,9 +1015,9 @@ namespace OpenSim.Region.Framework.Scenes
1015 } 1015 }
1016 } 1016 }
1017 1017
1018 public float GetTimeDilation() 1018 public ushort GetTimeDilation()
1019 { 1019 {
1020 return m_scene.TimeDilation; 1020 return Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f);
1021 } 1021 }
1022 1022
1023 /// <summary> 1023 /// <summary>
@@ -1857,28 +1857,15 @@ namespace OpenSim.Region.Framework.Scenes
1857 { 1857 {
1858 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 1858 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
1859 1859
1860 //if (IsAttachment) 1860 if (UsePhysics && !AbsolutePosition.ApproxEquals(lastPhysGroupPos, 0.02f))
1861 //{
1862 //foreach (SceneObjectPart part in m_parts.Values)
1863 //{
1864 //part.SendScheduledUpdates();
1865 //}
1866 //return;
1867 //}
1868
1869 if (UsePhysics && Util.DistanceLessThan(lastPhysGroupPos, AbsolutePosition, 0.02))
1870 { 1861 {
1871 m_rootPart.UpdateFlag = 1; 1862 m_rootPart.UpdateFlag = 1;
1872 lastPhysGroupPos = AbsolutePosition; 1863 lastPhysGroupPos = AbsolutePosition;
1873 } 1864 }
1874 1865
1875 if (UsePhysics && ((Math.Abs(lastPhysGroupRot.W - GroupRotation.W) > 0.1) 1866 if (UsePhysics && !GroupRotation.ApproxEquals(lastPhysGroupRot, 0.1f))
1876 || (Math.Abs(lastPhysGroupRot.X - GroupRotation.X) > 0.1)
1877 || (Math.Abs(lastPhysGroupRot.Y - GroupRotation.Y) > 0.1)
1878 || (Math.Abs(lastPhysGroupRot.Z - GroupRotation.Z) > 0.1)))
1879 { 1867 {
1880 m_rootPart.UpdateFlag = 1; 1868 m_rootPart.UpdateFlag = 1;
1881
1882 lastPhysGroupRot = GroupRotation; 1869 lastPhysGroupRot = GroupRotation;
1883 } 1870 }
1884 1871
@@ -2959,12 +2946,13 @@ namespace OpenSim.Region.Framework.Scenes
2959 /// <param name="rot"></param> 2946 /// <param name="rot"></param>
2960 public void UpdateGroupRotationR(Quaternion rot) 2947 public void UpdateGroupRotationR(Quaternion rot)
2961 { 2948 {
2962
2963 m_rootPart.UpdateRotation(rot); 2949 m_rootPart.UpdateRotation(rot);
2964 if (m_rootPart.PhysActor != null) 2950
2951 PhysicsActor actor = m_rootPart.PhysActor;
2952 if (actor != null)
2965 { 2953 {
2966 m_rootPart.PhysActor.Orientation = m_rootPart.RotationOffset; 2954 actor.Orientation = m_rootPart.RotationOffset;
2967 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 2955 m_scene.PhysicsScene.AddPhysicsActorTaint(actor);
2968 } 2956 }
2969 2957
2970 HasGroupChanged = true; 2958 HasGroupChanged = true;
@@ -2979,11 +2967,14 @@ namespace OpenSim.Region.Framework.Scenes
2979 public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot) 2967 public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot)
2980 { 2968 {
2981 m_rootPart.UpdateRotation(rot); 2969 m_rootPart.UpdateRotation(rot);
2982 if (m_rootPart.PhysActor != null) 2970
2971 PhysicsActor actor = m_rootPart.PhysActor;
2972 if (actor != null)
2983 { 2973 {
2984 m_rootPart.PhysActor.Orientation = m_rootPart.RotationOffset; 2974 actor.Orientation = m_rootPart.RotationOffset;
2985 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 2975 m_scene.PhysicsScene.AddPhysicsActorTaint(actor);
2986 } 2976 }
2977
2987 AbsolutePosition = pos; 2978 AbsolutePosition = pos;
2988 2979
2989 HasGroupChanged = true; 2980 HasGroupChanged = true;
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 9b11582..2bc7f66 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -253,6 +253,7 @@ namespace OpenSim.Region.Framework.Scenes
253 protected Vector3 m_lastVelocity; 253 protected Vector3 m_lastVelocity;
254 protected Vector3 m_lastAcceleration; 254 protected Vector3 m_lastAcceleration;
255 protected Vector3 m_lastAngularVelocity; 255 protected Vector3 m_lastAngularVelocity;
256 protected int m_lastTerseSent;
256 257
257 // TODO: Those have to be changed into persistent properties at some later point, 258 // TODO: Those have to be changed into persistent properties at some later point,
258 // or sit-camera on vehicles will break on sim-crossing. 259 // or sit-camera on vehicles will break on sim-crossing.
@@ -506,20 +507,17 @@ namespace OpenSim.Region.Framework.Scenes
506 get 507 get
507 { 508 {
508 // If this is a linkset, we don't want the physics engine mucking up our group position here. 509 // If this is a linkset, we don't want the physics engine mucking up our group position here.
509 if (PhysActor != null && _parentID == 0) 510 PhysicsActor actor = PhysActor;
511 if (actor != null && _parentID == 0)
510 { 512 {
511 m_groupPosition.X = PhysActor.Position.X; 513 m_groupPosition = actor.Position;
512 m_groupPosition.Y = PhysActor.Position.Y;
513 m_groupPosition.Z = PhysActor.Position.Z;
514 } 514 }
515 515
516 if (IsAttachment) 516 if (IsAttachment)
517 { 517 {
518 ScenePresence sp = m_parentGroup.Scene.GetScenePresence(AttachedAvatar); 518 ScenePresence sp = m_parentGroup.Scene.GetScenePresence(AttachedAvatar);
519 if (sp != null) 519 if (sp != null)
520 {
521 return sp.AbsolutePosition; 520 return sp.AbsolutePosition;
522 }
523 } 521 }
524 522
525 return m_groupPosition; 523 return m_groupPosition;
@@ -530,26 +528,25 @@ namespace OpenSim.Region.Framework.Scenes
530 528
531 m_groupPosition = value; 529 m_groupPosition = value;
532 530
533 if (PhysActor != null) 531 PhysicsActor actor = PhysActor;
532 if (actor != null)
534 { 533 {
535 try 534 try
536 { 535 {
537 // Root prim actually goes at Position 536 // Root prim actually goes at Position
538 if (_parentID == 0) 537 if (_parentID == 0)
539 { 538 {
540 PhysActor.Position = value; 539 actor.Position = value;
541 } 540 }
542 else 541 else
543 { 542 {
544 // To move the child prim in respect to the group position and rotation we have to calculate 543 // To move the child prim in respect to the group position and rotation we have to calculate
545 Vector3 resultingposition = GetWorldPosition(); 544 actor.Position = GetWorldPosition();
546 PhysActor.Position = resultingposition; 545 actor.Orientation = GetWorldRotation();
547 Quaternion resultingrot = GetWorldRotation();
548 PhysActor.Orientation = resultingrot;
549 } 546 }
550 547
551 // Tell the physics engines that this prim changed. 548 // Tell the physics engines that this prim changed.
552 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); 549 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
553 } 550 }
554 catch (Exception e) 551 catch (Exception e)
555 { 552 {
@@ -582,15 +579,14 @@ namespace OpenSim.Region.Framework.Scenes
582 579
583 if (ParentGroup != null && !ParentGroup.IsDeleted) 580 if (ParentGroup != null && !ParentGroup.IsDeleted)
584 { 581 {
585 if (_parentID != 0 && PhysActor != null) 582 PhysicsActor actor = PhysActor;
583 if (_parentID != 0 && actor != null)
586 { 584 {
587 Vector3 resultingposition = GetWorldPosition(); 585 actor.Position = GetWorldPosition();
588 PhysActor.Position = resultingposition; 586 actor.Orientation = GetWorldRotation();
589 Quaternion resultingrot = GetWorldRotation();
590 PhysActor.Orientation = resultingrot;
591 587
592 // Tell the physics engines that this prim changed. 588 // Tell the physics engines that this prim changed.
593 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); 589 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
594 } 590 }
595 } 591 }
596 } 592 }
@@ -601,12 +597,13 @@ namespace OpenSim.Region.Framework.Scenes
601 get 597 get
602 { 598 {
603 // We don't want the physics engine mucking up the rotations in a linkset 599 // We don't want the physics engine mucking up the rotations in a linkset
604 if ((_parentID == 0) && (Shape.PCode != 9 || Shape.State == 0) && (PhysActor != null)) 600 PhysicsActor actor = PhysActor;
601 if (_parentID == 0 && (Shape.PCode != 9 || Shape.State == 0) && actor != null)
605 { 602 {
606 if (PhysActor.Orientation.X != 0 || PhysActor.Orientation.Y != 0 603 if (actor.Orientation.X != 0f || actor.Orientation.Y != 0f
607 || PhysActor.Orientation.Z != 0 || PhysActor.Orientation.W != 0) 604 || actor.Orientation.Z != 0f || actor.Orientation.W != 0f)
608 { 605 {
609 m_rotationOffset = PhysActor.Orientation; 606 m_rotationOffset = actor.Orientation;
610 } 607 }
611 } 608 }
612 609
@@ -618,24 +615,25 @@ namespace OpenSim.Region.Framework.Scenes
618 StoreUndoState(); 615 StoreUndoState();
619 m_rotationOffset = value; 616 m_rotationOffset = value;
620 617
621 if (PhysActor != null) 618 PhysicsActor actor = PhysActor;
619 if (actor != null)
622 { 620 {
623 try 621 try
624 { 622 {
625 // Root prim gets value directly 623 // Root prim gets value directly
626 if (_parentID == 0) 624 if (_parentID == 0)
627 { 625 {
628 PhysActor.Orientation = value; 626 actor.Orientation = value;
629 //m_log.Info("[PART]: RO1:" + PhysActor.Orientation.ToString()); 627 //m_log.Info("[PART]: RO1:" + actor.Orientation.ToString());
630 } 628 }
631 else 629 else
632 { 630 {
633 // Child prim we have to calculate it's world rotationwel 631 // Child prim we have to calculate it's world rotationwel
634 Quaternion resultingrotation = GetWorldRotation(); 632 Quaternion resultingrotation = GetWorldRotation();
635 PhysActor.Orientation = resultingrotation; 633 actor.Orientation = resultingrotation;
636 //m_log.Info("[PART]: RO2:" + PhysActor.Orientation.ToString()); 634 //m_log.Info("[PART]: RO2:" + actor.Orientation.ToString());
637 } 635 }
638 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); 636 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
639 //} 637 //}
640 } 638 }
641 catch (Exception ex) 639 catch (Exception ex)
@@ -652,16 +650,12 @@ namespace OpenSim.Region.Framework.Scenes
652 { 650 {
653 get 651 get
654 { 652 {
655 //if (PhysActor.Velocity.X != 0 || PhysActor.Velocity.Y != 0 653 PhysicsActor actor = PhysActor;
656 //|| PhysActor.Velocity.Z != 0) 654 if (actor != null)
657 //{
658 if (PhysActor != null)
659 { 655 {
660 if (PhysActor.IsPhysical) 656 if (actor.IsPhysical)
661 { 657 {
662 m_velocity.X = PhysActor.Velocity.X; 658 m_velocity = actor.Velocity;
663 m_velocity.Y = PhysActor.Velocity.Y;
664 m_velocity.Z = PhysActor.Velocity.Z;
665 } 659 }
666 } 660 }
667 661
@@ -671,31 +665,28 @@ namespace OpenSim.Region.Framework.Scenes
671 set 665 set
672 { 666 {
673 m_velocity = value; 667 m_velocity = value;
674 if (PhysActor != null) 668
669 PhysicsActor actor = PhysActor;
670 if (actor != null)
675 { 671 {
676 if (PhysActor.IsPhysical) 672 if (actor.IsPhysical)
677 { 673 {
678 PhysActor.Velocity = value; 674 actor.Velocity = value;
679 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); 675 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
680 } 676 }
681 } 677 }
682 } 678 }
683 } 679 }
684 680
685 public Vector3 RotationalVelocity
686 {
687 get { return AngularVelocity; }
688 set { AngularVelocity = value; }
689 }
690
691 /// <summary></summary> 681 /// <summary></summary>
692 public Vector3 AngularVelocity 682 public Vector3 AngularVelocity
693 { 683 {
694 get 684 get
695 { 685 {
696 if ((PhysActor != null) && PhysActor.IsPhysical) 686 PhysicsActor actor = PhysActor;
687 if ((actor != null) && actor.IsPhysical)
697 { 688 {
698 m_angularVelocity.FromBytes(PhysActor.RotationalVelocity.GetBytes(), 0); 689 m_angularVelocity = actor.RotationalVelocity;
699 } 690 }
700 return m_angularVelocity; 691 return m_angularVelocity;
701 } 692 }
@@ -715,9 +706,10 @@ namespace OpenSim.Region.Framework.Scenes
715 set 706 set
716 { 707 {
717 m_description = value; 708 m_description = value;
718 if (PhysActor != null) 709 PhysicsActor actor = PhysActor;
710 if (actor != null)
719 { 711 {
720 PhysActor.SOPDescription = value; 712 actor.SOPDescription = value;
721 } 713 }
722 } 714 }
723 } 715 }
@@ -808,21 +800,23 @@ namespace OpenSim.Region.Framework.Scenes
808 set 800 set
809 { 801 {
810 StoreUndoState(); 802 StoreUndoState();
811if (m_shape != null) { 803 if (m_shape != null)
812 m_shape.Scale = value;
813
814 if (PhysActor != null && m_parentGroup != null)
815 { 804 {
816 if (m_parentGroup.Scene != null) 805 m_shape.Scale = value;
806
807 PhysicsActor actor = PhysActor;
808 if (actor != null && m_parentGroup != null)
817 { 809 {
818 if (m_parentGroup.Scene.PhysicsScene != null) 810 if (m_parentGroup.Scene != null)
819 { 811 {
820 PhysActor.Size = m_shape.Scale; 812 if (m_parentGroup.Scene.PhysicsScene != null)
821 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); 813 {
814 actor.Size = m_shape.Scale;
815 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
816 }
822 } 817 }
823 } 818 }
824 } 819 }
825}
826 TriggerScriptChangedEvent(Changed.SCALE); 820 TriggerScriptChangedEvent(Changed.SCALE);
827 } 821 }
828 } 822 }
@@ -1056,8 +1050,6 @@ if (m_shape != null) {
1056 1050
1057 #endregion Public Properties with only Get 1051 #endregion Public Properties with only Get
1058 1052
1059
1060
1061 #region Private Methods 1053 #region Private Methods
1062 1054
1063 private uint ApplyMask(uint val, bool set, uint mask) 1055 private uint ApplyMask(uint val, bool set, uint mask)
@@ -1551,9 +1543,9 @@ if (m_shape != null) {
1551 m_parentGroup.Scene.PhysicsScene.RequestJointDeletion(Name); // FIXME: what if the name changed? 1543 m_parentGroup.Scene.PhysicsScene.RequestJointDeletion(Name); // FIXME: what if the name changed?
1552 1544
1553 // make sure client isn't interpolating the joint proxy object 1545 // make sure client isn't interpolating the joint proxy object
1554 Velocity = new Vector3(0, 0, 0); 1546 Velocity = Vector3.Zero;
1555 RotationalVelocity = new Vector3(0, 0, 0); 1547 AngularVelocity = Vector3.Zero;
1556 Acceleration = new Vector3(0, 0, 0); 1548 Acceleration = Vector3.Zero;
1557 } 1549 }
1558 } 1550 }
1559 } 1551 }
@@ -1816,7 +1808,7 @@ if (m_shape != null) {
1816 } 1808 }
1817 1809
1818 CollisionEventUpdate a = (CollisionEventUpdate)e; 1810 CollisionEventUpdate a = (CollisionEventUpdate)e;
1819 Dictionary<uint, float> collissionswith = a.m_objCollisionList; 1811 Dictionary<uint, ContactPoint> collissionswith = a.m_objCollisionList;
1820 List<uint> thisHitColliders = new List<uint>(); 1812 List<uint> thisHitColliders = new List<uint>();
1821 List<uint> endedColliders = new List<uint>(); 1813 List<uint> endedColliders = new List<uint>();
1822 List<uint> startedColliders = new List<uint>(); 1814 List<uint> startedColliders = new List<uint>();
@@ -2382,8 +2374,8 @@ if (m_shape != null) {
2382 //isattachment = ParentGroup.RootPart.IsAttachment; 2374 //isattachment = ParentGroup.RootPart.IsAttachment;
2383 2375
2384 byte[] color = new byte[] {m_color.R, m_color.G, m_color.B, m_color.A}; 2376 byte[] color = new byte[] {m_color.R, m_color.G, m_color.B, m_color.A};
2385 remoteClient.SendPrimitiveToClient(new SendPrimitiveData(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, m_shape, 2377 remoteClient.SendPrimitiveToClient(new SendPrimitiveData(m_regionHandle, m_parentGroup.GetTimeDilation(), LocalId, m_shape,
2386 lPos, Velocity, Acceleration, RotationOffset, RotationalVelocity, clientFlags, m_uuid, _ownerID, 2378 lPos, Velocity, Acceleration, RotationOffset, AngularVelocity, clientFlags, m_uuid, _ownerID,
2387 m_text, color, _parentID, m_particleSystem, m_clickAction, (byte)m_material, m_TextureAnimation, IsAttachment, 2379 m_text, color, _parentID, m_particleSystem, m_clickAction, (byte)m_material, m_TextureAnimation, IsAttachment,
2388 AttachmentPoint,FromItemID, Sound, SoundGain, SoundFlags, SoundRadius, ParentGroup.GetUpdatePriority(remoteClient))); 2380 AttachmentPoint,FromItemID, Sound, SoundGain, SoundFlags, SoundRadius, ParentGroup.GetUpdatePriority(remoteClient)));
2389 } 2381 }
@@ -2393,17 +2385,20 @@ if (m_shape != null) {
2393 /// </summary> 2385 /// </summary>
2394 public void SendScheduledUpdates() 2386 public void SendScheduledUpdates()
2395 { 2387 {
2396 const float VELOCITY_TOLERANCE = 0.01f; 2388 const float ROTATION_TOLERANCE = 0.01f;
2397 const float POSITION_TOLERANCE = 0.1f; 2389 const float VELOCITY_TOLERANCE = 0.001f;
2390 const float POSITION_TOLERANCE = 0.05f;
2391 const int TIME_MS_TOLERANCE = 3000;
2398 2392
2399 if (m_updateFlag == 1) 2393 if (m_updateFlag == 1)
2400 { 2394 {
2401 // Throw away duplicate or insignificant updates 2395 // Throw away duplicate or insignificant updates
2402 if (RotationOffset != m_lastRotation || 2396 if (!RotationOffset.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) ||
2403 Acceleration != m_lastAcceleration || 2397 !Acceleration.Equals(m_lastAcceleration) ||
2404 (Velocity - m_lastVelocity).Length() > VELOCITY_TOLERANCE || 2398 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
2405 (RotationalVelocity - m_lastAngularVelocity).Length() > VELOCITY_TOLERANCE || 2399 !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) ||
2406 (OffsetPosition - m_lastPosition).Length() > POSITION_TOLERANCE) 2400 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
2401 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE)
2407 { 2402 {
2408 AddTerseUpdateToAllAvatars(); 2403 AddTerseUpdateToAllAvatars();
2409 ClearUpdateSchedule(); 2404 ClearUpdateSchedule();
@@ -2421,7 +2416,8 @@ if (m_shape != null) {
2421 m_lastRotation = RotationOffset; 2416 m_lastRotation = RotationOffset;
2422 m_lastVelocity = Velocity; 2417 m_lastVelocity = Velocity;
2423 m_lastAcceleration = Acceleration; 2418 m_lastAcceleration = Acceleration;
2424 m_lastAngularVelocity = RotationalVelocity; 2419 m_lastAngularVelocity = AngularVelocity;
2420 m_lastTerseSent = Environment.TickCount;
2425 } 2421 }
2426 } 2422 }
2427 else 2423 else
@@ -3780,10 +3776,9 @@ if (m_shape != null) {
3780 // Causes this thread to dig into the Client Thread Data. 3776 // Causes this thread to dig into the Client Thread Data.
3781 // Remember your locking here! 3777 // Remember your locking here!
3782 remoteClient.SendPrimTerseUpdate(new SendPrimitiveTerseData(m_regionHandle, 3778 remoteClient.SendPrimTerseUpdate(new SendPrimitiveTerseData(m_regionHandle,
3783 (ushort)(m_parentGroup.GetTimeDilation() * 3779 m_parentGroup.GetTimeDilation(), LocalId, lPos,
3784 (float)ushort.MaxValue), LocalId, lPos,
3785 RotationOffset, Velocity, Acceleration, 3780 RotationOffset, Velocity, Acceleration,
3786 RotationalVelocity, state, FromItemID, 3781 AngularVelocity, state, FromItemID,
3787 OwnerID, (int)AttachmentPoint, null, ParentGroup.GetUpdatePriority(remoteClient))); 3782 OwnerID, (int)AttachmentPoint, null, ParentGroup.GetUpdatePriority(remoteClient)));
3788 } 3783 }
3789 3784
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 87fac0c..6c0d9f2 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -76,8 +76,18 @@ namespace OpenSim.Region.Framework.Scenes
76 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 76 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
77 77
78 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; 78 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
79 79 private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes();
80 public static byte[] DefaultTexture; 80 private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags));
81 private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f);
82 /// <summary>
83 /// Experimentally determined "fudge factor" to make sit-target positions
84 /// the same as in SecondLife. Fudge factor was tested for 36 different
85 /// test cases including prims of type box, sphere, cylinder, and torus,
86 /// with varying parameters for sit target location, prim size, prim
87 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
88 /// issue #1716
89 /// </summary>
90 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f);
81 91
82 public UUID currentParcelUUID = UUID.Zero; 92 public UUID currentParcelUUID = UUID.Zero;
83 93
@@ -92,16 +102,18 @@ namespace OpenSim.Region.Framework.Scenes
92 //private SceneObjectPart proxyObjectPart = null; 102 //private SceneObjectPart proxyObjectPart = null;
93 public Vector3 lastKnownAllowedPosition; 103 public Vector3 lastKnownAllowedPosition;
94 public bool sentMessageAboutRestrictedParcelFlyingDown; 104 public bool sentMessageAboutRestrictedParcelFlyingDown;
105 public Vector4 CollisionPlane = Vector4.UnitW;
95 106
96 private Vector3 m_lastPosition; 107 private Vector3 m_lastPosition;
97 private Quaternion m_lastRotation; 108 private Quaternion m_lastRotation;
98 private Vector3 m_lastVelocity; 109 private Vector3 m_lastVelocity;
110 //private int m_lastTerseSent;
99 111
100 private bool m_updateflag; 112 private bool m_updateflag;
101 private byte m_movementflag; 113 private byte m_movementflag;
102 private readonly List<NewForce> m_forcesList = new List<NewForce>(); 114 private Vector3? m_forceToApply;
103 private uint m_requestedSitTargetID; 115 private uint m_requestedSitTargetID;
104 private UUID m_requestedSitTargetUUID = UUID.Zero; 116 private UUID m_requestedSitTargetUUID;
105 private SendCourseLocationsMethod m_sendCourseLocationsMethod; 117 private SendCourseLocationsMethod m_sendCourseLocationsMethod;
106 118
107 private bool m_startAnimationSet; 119 private bool m_startAnimationSet;
@@ -112,30 +124,24 @@ namespace OpenSim.Region.Framework.Scenes
112 124
113 private float m_sitAvatarHeight = 2.0f; 125 private float m_sitAvatarHeight = 2.0f;
114 126
115 // experimentally determined "fudge factor" to make sit-target positions
116 // the same as in SecondLife. Fudge factor was tested for 36 different
117 // test cases including prims of type box, sphere, cylinder, and torus,
118 // with varying parameters for sit target location, prim size, prim
119 // rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
120 // issue #1716
121 private static readonly Vector3 m_sitTargetCorrectionOffset = new Vector3(0.1f, 0.0f, 0.3f);
122 private float m_godlevel; 127 private float m_godlevel;
123 128
124 private bool m_invulnerable = true; 129 private bool m_invulnerable = true;
125 130
126 private Vector3 m_LastChildAgentUpdatePosition; 131 private Vector3 m_lastChildAgentUpdatePosition;
132 private Vector3 m_lastChildAgentUpdateCamPosition;
127 133
128 private int m_perfMonMS; 134 private int m_perfMonMS;
129 135
130 private bool m_setAlwaysRun; 136 private bool m_setAlwaysRun;
131 137
132 private string m_movementAnimation = "DEFAULT"; 138 private string m_movementAnimation = "DEFAULT";
133 private long m_animPersistUntil = 0; 139 private int m_animTickFall;
134 private bool m_allowFalling = false; 140 private int m_animTickJump;
135 private bool m_useFlySlow = false; 141 private bool m_useFlySlow;
136 private bool m_usePreJump = false; 142 private bool m_usePreJump;
137 private bool m_forceFly = false; 143 private bool m_forceFly;
138 private bool m_flyDisabled = false; 144 private bool m_flyDisabled;
139 145
140 private float m_speedModifier = 1.0f; 146 private float m_speedModifier = 1.0f;
141 147
@@ -143,7 +149,7 @@ namespace OpenSim.Region.Framework.Scenes
143 149
144 public bool IsRestrictedToRegion; 150 public bool IsRestrictedToRegion;
145 151
146 public string JID = string.Empty; 152 public string JID = String.Empty;
147 153
148 // Agent moves with a PID controller causing a force to be exerted. 154 // Agent moves with a PID controller causing a force to be exerted.
149 private bool m_newCoarseLocations = true; 155 private bool m_newCoarseLocations = true;
@@ -158,43 +164,43 @@ namespace OpenSim.Region.Framework.Scenes
158 private readonly Vector3[] Dir_Vectors = new Vector3[6]; 164 private readonly Vector3[] Dir_Vectors = new Vector3[6];
159 165
160 // Position of agent's camera in world (region cordinates) 166 // Position of agent's camera in world (region cordinates)
161 protected Vector3 m_CameraCenter = Vector3.Zero; 167 protected Vector3 m_CameraCenter;
162 protected Vector3 m_lastCameraCenter = Vector3.Zero; 168 protected Vector3 m_lastCameraCenter;
163 169
164 protected Timer m_reprioritization_timer; 170 protected Timer m_reprioritization_timer;
165 protected bool m_reprioritizing = false; 171 protected bool m_reprioritizing;
166 protected bool m_reprioritization_called = false; 172 protected bool m_reprioritization_called;
167 173
168 // Use these three vectors to figure out what the agent is looking at 174 // Use these three vectors to figure out what the agent is looking at
169 // Convert it to a Matrix and/or Quaternion 175 // Convert it to a Matrix and/or Quaternion
170 protected Vector3 m_CameraAtAxis = Vector3.Zero; 176 protected Vector3 m_CameraAtAxis;
171 protected Vector3 m_CameraLeftAxis = Vector3.Zero; 177 protected Vector3 m_CameraLeftAxis;
172 protected Vector3 m_CameraUpAxis = Vector3.Zero; 178 protected Vector3 m_CameraUpAxis;
173 private uint m_AgentControlFlags; 179 private AgentManager.ControlFlags m_AgentControlFlags;
174 private Quaternion m_headrotation = Quaternion.Identity; 180 private Quaternion m_headrotation = Quaternion.Identity;
175 private byte m_state; 181 private byte m_state;
176 182
177 //Reuse the Vector3 instead of creating a new one on the UpdateMovement method 183 //Reuse the Vector3 instead of creating a new one on the UpdateMovement method
178 private Vector3 movementvector = Vector3.Zero; 184 private Vector3 movementvector;
179 185
180 private bool m_autopilotMoving; 186 private bool m_autopilotMoving;
181 private Vector3 m_autoPilotTarget = Vector3.Zero; 187 private Vector3 m_autoPilotTarget;
182 private bool m_sitAtAutoTarget; 188 private bool m_sitAtAutoTarget;
183 189
184 private string m_nextSitAnimation = String.Empty; 190 private string m_nextSitAnimation = String.Empty;
185 191
186 //PauPaw:Proper PID Controler for autopilot************ 192 //PauPaw:Proper PID Controler for autopilot************
187 private bool m_moveToPositionInProgress; 193 private bool m_moveToPositionInProgress;
188 private Vector3 m_moveToPositionTarget = Vector3.Zero; 194 private Vector3 m_moveToPositionTarget;
189 195
190 private bool m_followCamAuto = false; 196 private bool m_followCamAuto;
191 197
192 private int m_movementUpdateCount = 0; 198 private int m_movementUpdateCount;
193 199
194 private const int NumMovementsBetweenRayCast = 5; 200 private const int NumMovementsBetweenRayCast = 5;
195 201
196 private bool CameraConstraintActive = false; 202 private bool CameraConstraintActive;
197 //private int m_moveToPositionStateStatus = 0; 203 //private int m_moveToPositionStateStatus;
198 //***************************************************** 204 //*****************************************************
199 205
200 // Agent's Draw distance. 206 // Agent's Draw distance.
@@ -268,11 +274,9 @@ namespace OpenSim.Region.Framework.Scenes
268 get { return m_godlevel; } 274 get { return m_godlevel; }
269 } 275 }
270 276
271 private readonly ulong m_regionHandle;
272
273 public ulong RegionHandle 277 public ulong RegionHandle
274 { 278 {
275 get { return m_regionHandle; } 279 get { return m_rootRegionHandle; }
276 } 280 }
277 281
278 public Vector3 CameraPosition 282 public Vector3 CameraPosition
@@ -379,8 +383,8 @@ namespace OpenSim.Region.Framework.Scenes
379 383
380 public uint AgentControlFlags 384 public uint AgentControlFlags
381 { 385 {
382 get { return m_AgentControlFlags; } 386 get { return (uint)m_AgentControlFlags; }
383 set { m_AgentControlFlags = value; } 387 set { m_AgentControlFlags = (AgentManager.ControlFlags)value; }
384 } 388 }
385 389
386 /// <summary> 390 /// <summary>
@@ -411,31 +415,27 @@ namespace OpenSim.Region.Framework.Scenes
411 } 415 }
412 416
413 /// <summary> 417 /// <summary>
414 /// Absolute position of this avatar in 'region cordinates' 418 /// Position of this avatar relative to the region the avatar is in
415 /// </summary> 419 /// </summary>
416 public override Vector3 AbsolutePosition 420 public override Vector3 AbsolutePosition
417 { 421 {
418 get 422 get
419 { 423 {
420 if (m_physicsActor != null) 424 PhysicsActor actor = m_physicsActor;
421 { 425 if (actor != null)
422 m_pos.X = m_physicsActor.Position.X; 426 m_pos = actor.Position;
423 m_pos.Y = m_physicsActor.Position.Y;
424 m_pos.Z = m_physicsActor.Position.Z;
425 }
426 427
427 return m_parentPosition + m_pos; 428 return m_parentPosition + m_pos;
428 } 429 }
429 set 430 set
430 { 431 {
431 if (m_physicsActor != null) 432 PhysicsActor actor = m_physicsActor;
433 if (actor != null)
432 { 434 {
433 try 435 try
434 { 436 {
435 lock (m_scene.SyncRoot) 437 lock (m_scene.SyncRoot)
436 {
437 m_physicsActor.Position = value; 438 m_physicsActor.Position = value;
438 }
439 } 439 }
440 catch (Exception e) 440 catch (Exception e)
441 { 441 {
@@ -444,7 +444,7 @@ namespace OpenSim.Region.Framework.Scenes
444 } 444 }
445 445
446 m_pos = value; 446 m_pos = value;
447 m_parentPosition = new Vector3(0, 0, 0); 447 m_parentPosition = Vector3.Zero;
448 } 448 }
449 } 449 }
450 450
@@ -455,27 +455,21 @@ namespace OpenSim.Region.Framework.Scenes
455 { 455 {
456 get 456 get
457 { 457 {
458 if (m_physicsActor != null) 458 PhysicsActor actor = m_physicsActor;
459 { 459 if (actor != null)
460 m_velocity.X = m_physicsActor.Velocity.X; 460 m_velocity = actor.Velocity;
461 m_velocity.Y = m_physicsActor.Velocity.Y;
462 m_velocity.Z = m_physicsActor.Velocity.Z;
463 }
464 461
465 return m_velocity; 462 return m_velocity;
466 } 463 }
467 set 464 set
468 { 465 {
469 //m_log.DebugFormat("In {0} setting velocity of {1} to {2}", m_scene.RegionInfo.RegionName, Name, value); 466 PhysicsActor actor = m_physicsActor;
470 467 if (actor != null)
471 if (m_physicsActor != null)
472 { 468 {
473 try 469 try
474 { 470 {
475 lock (m_scene.SyncRoot) 471 lock (m_scene.SyncRoot)
476 { 472 actor.Velocity = value;
477 m_physicsActor.Velocity = value;
478 }
479 } 473 }
480 catch (Exception e) 474 catch (Exception e)
481 { 475 {
@@ -627,7 +621,7 @@ namespace OpenSim.Region.Framework.Scenes
627 { 621 {
628 m_sendCourseLocationsMethod = SendCoarseLocationsDefault; 622 m_sendCourseLocationsMethod = SendCoarseLocationsDefault;
629 CreateSceneViewer(); 623 CreateSceneViewer();
630 m_regionHandle = reginfo.RegionHandle; 624 m_rootRegionHandle = reginfo.RegionHandle;
631 m_controllingClient = client; 625 m_controllingClient = client;
632 m_firstname = m_controllingClient.FirstName; 626 m_firstname = m_controllingClient.FirstName;
633 m_lastname = m_controllingClient.LastName; 627 m_lastname = m_controllingClient.LastName;
@@ -710,25 +704,25 @@ namespace OpenSim.Region.Framework.Scenes
710 704
711 private void SetDirectionVectors() 705 private void SetDirectionVectors()
712 { 706 {
713 Dir_Vectors[0] = new Vector3(1, 0, 0); //FORWARD 707 Dir_Vectors[0] = Vector3.UnitX; //FORWARD
714 Dir_Vectors[1] = new Vector3(-1, 0, 0); //BACK 708 Dir_Vectors[1] = -Vector3.UnitX; //BACK
715 Dir_Vectors[2] = new Vector3(0, 1, 0); //LEFT 709 Dir_Vectors[2] = Vector3.UnitY; //LEFT
716 Dir_Vectors[3] = new Vector3(0, -1, 0); //RIGHT 710 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
717 Dir_Vectors[4] = new Vector3(0, 0, 1); //UP 711 Dir_Vectors[4] = Vector3.UnitZ; //UP
718 Dir_Vectors[5] = new Vector3(0, 0, -1); //DOWN 712 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
719 Dir_Vectors[5] = new Vector3(0, 0, -0.5f); //DOWN_Nudge 713 Dir_Vectors[5] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
720 } 714 }
721 715
722 private Vector3[] GetWalkDirectionVectors() 716 private Vector3[] GetWalkDirectionVectors()
723 { 717 {
724 Vector3[] vector = new Vector3[6]; 718 Vector3[] vector = new Vector3[6];
725 vector[0] = new Vector3(m_CameraUpAxis.Z, 0, -m_CameraAtAxis.Z); //FORWARD 719 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
726 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0, m_CameraAtAxis.Z); //BACK 720 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
727 vector[2] = new Vector3(0, 1, 0); //LEFT 721 vector[2] = Vector3.UnitY; //LEFT
728 vector[3] = new Vector3(0, -1, 0); //RIGHT 722 vector[3] = -Vector3.UnitY; //RIGHT
729 vector[4] = new Vector3(m_CameraAtAxis.Z, 0, m_CameraUpAxis.Z); //UP 723 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
730 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0, -m_CameraUpAxis.Z); //DOWN 724 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
731 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0, -m_CameraUpAxis.Z); //DOWN_Nudge 725 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge
732 return vector; 726 return vector;
733 } 727 }
734 728
@@ -781,6 +775,8 @@ namespace OpenSim.Region.Framework.Scenes
781 if (gm != null) 775 if (gm != null)
782 m_grouptitle = gm.GetGroupTitle(m_uuid); 776 m_grouptitle = gm.GetGroupTitle(m_uuid);
783 777
778 m_rootRegionHandle = m_scene.RegionInfo.RegionHandle;
779
784 m_scene.SetRootAgentScene(m_uuid); 780 m_scene.SetRootAgentScene(m_uuid);
785 781
786 // Moved this from SendInitialData to ensure that m_appearance is initialized 782 // Moved this from SendInitialData to ensure that m_appearance is initialized
@@ -811,7 +807,6 @@ namespace OpenSim.Region.Framework.Scenes
811 pos = emergencyPos; 807 pos = emergencyPos;
812 } 808 }
813 809
814
815 float localAVHeight = 1.56f; 810 float localAVHeight = 1.56f;
816 if (m_avHeight != 127.0f) 811 if (m_avHeight != 127.0f)
817 { 812 {
@@ -906,6 +901,8 @@ namespace OpenSim.Region.Framework.Scenes
906 m_isChildAgent = true; 901 m_isChildAgent = true;
907 m_scene.SwapRootAgentCount(true); 902 m_scene.SwapRootAgentCount(true);
908 RemoveFromPhysicalScene(); 903 RemoveFromPhysicalScene();
904
905 // FIXME: Set m_rootRegionHandle to the region handle of the scene this agent is moving into
909 906
910 m_scene.EventManager.TriggerOnMakeChildAgent(this); 907 m_scene.EventManager.TriggerOnMakeChildAgent(this);
911 } 908 }
@@ -937,7 +934,7 @@ namespace OpenSim.Region.Framework.Scenes
937 isFlying = m_physicsActor.Flying; 934 isFlying = m_physicsActor.Flying;
938 935
939 RemoveFromPhysicalScene(); 936 RemoveFromPhysicalScene();
940 Velocity = new Vector3(0, 0, 0); 937 Velocity = Vector3.Zero;
941 AbsolutePosition = pos; 938 AbsolutePosition = pos;
942 AddToPhysicalScene(isFlying); 939 AddToPhysicalScene(isFlying);
943 if (m_appearance != null) 940 if (m_appearance != null)
@@ -985,12 +982,13 @@ namespace OpenSim.Region.Framework.Scenes
985 982
986 if (m_avHeight != 127.0f) 983 if (m_avHeight != 127.0f)
987 { 984 {
988 AbsolutePosition = AbsolutePosition + new Vector3(0, 0, (m_avHeight / 6f)); 985 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (m_avHeight / 6f));
989 } 986 }
990 else 987 else
991 { 988 {
992 AbsolutePosition = AbsolutePosition + new Vector3(0, 0, (1.56f / 6f)); 989 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
993 } 990 }
991
994 TrySetMovementAnimation("LAND"); 992 TrySetMovementAnimation("LAND");
995 SendFullUpdateToAllClients(); 993 SendFullUpdateToAllClients();
996 } 994 }
@@ -1076,7 +1074,7 @@ namespace OpenSim.Region.Framework.Scenes
1076 } 1074 }
1077 1075
1078 m_isChildAgent = false; 1076 m_isChildAgent = false;
1079 bool m_flying = ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 1077 bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1080 MakeRootAgent(AbsolutePosition, m_flying); 1078 MakeRootAgent(AbsolutePosition, m_flying);
1081 1079
1082 if ((m_callbackURI != null) && !m_callbackURI.Equals("")) 1080 if ((m_callbackURI != null) && !m_callbackURI.Equals(""))
@@ -1103,9 +1101,12 @@ namespace OpenSim.Region.Framework.Scenes
1103 /// <param name="distance"></param> 1101 /// <param name="distance"></param>
1104 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance) 1102 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance)
1105 { 1103 {
1104 const float POSITION_TOLERANCE = 0.02f;
1105 const float VELOCITY_TOLERANCE = 0.02f;
1106 const float ROTATION_TOLERANCE = 0.02f;
1107
1106 if (m_followCamAuto) 1108 if (m_followCamAuto)
1107 { 1109 {
1108
1109 if (hitYN) 1110 if (hitYN)
1110 { 1111 {
1111 CameraConstraintActive = true; 1112 CameraConstraintActive = true;
@@ -1114,11 +1115,11 @@ namespace OpenSim.Region.Framework.Scenes
1114 Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint); 1115 Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint);
1115 ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint))); 1116 ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint)));
1116 } 1117 }
1117 else 1118 else
1118 { 1119 {
1119 if ((m_pos - m_lastPosition).Length() > 0.02f || 1120 if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
1120 (m_velocity - m_lastVelocity).Length() > 0.02f || 1121 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
1121 m_bodyRot != m_lastRotation) 1122 !m_bodyRot.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE))
1122 { 1123 {
1123 if (CameraConstraintActive) 1124 if (CameraConstraintActive)
1124 { 1125 {
@@ -1127,13 +1128,11 @@ namespace OpenSim.Region.Framework.Scenes
1127 } 1128 }
1128 } 1129 }
1129 } 1130 }
1130 } 1131 }
1131 } 1132 }
1132 1133
1133 Array m_dirControlFlags = Enum.GetValues(typeof(Dir_ControlFlags));
1134
1135 /// <summary> 1134 /// <summary>
1136 /// This is the event handler for client movement. If a client is moving, this event is triggering. 1135 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1137 /// </summary> 1136 /// </summary>
1138 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 1137 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
1139 { 1138 {
@@ -1149,15 +1148,13 @@ namespace OpenSim.Region.Framework.Scenes
1149 if (m_movementUpdateCount < 1) 1148 if (m_movementUpdateCount < 1)
1150 m_movementUpdateCount = 1; 1149 m_movementUpdateCount = 1;
1151 1150
1152 // Must check for standing up even when PhysicsActor is null, 1151 #region Sanity Checking
1153 // since sitting currently removes avatar from physical scene
1154 //m_log.Debug("agentPos:" + AbsolutePosition.ToString());
1155 1152
1156 // This is irritating. Really. 1153 // This is irritating. Really.
1157 if (!AbsolutePosition.IsFinite()) 1154 if (!AbsolutePosition.IsFinite())
1158 { 1155 {
1159 RemoveFromPhysicalScene(); 1156 RemoveFromPhysicalScene();
1160 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error# 9999902"); 1157 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");
1161 1158
1162 m_pos = m_LastFinitePos; 1159 m_pos = m_LastFinitePos;
1163 if (!m_pos.IsFinite()) 1160 if (!m_pos.IsFinite())
@@ -1165,7 +1162,7 @@ namespace OpenSim.Region.Framework.Scenes
1165 m_pos.X = 127f; 1162 m_pos.X = 127f;
1166 m_pos.Y = 127f; 1163 m_pos.Y = 127f;
1167 m_pos.Z = 127f; 1164 m_pos.Z = 127f;
1168 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error# 9999903"); 1165 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999903");
1169 } 1166 }
1170 1167
1171 AddToPhysicalScene(false); 1168 AddToPhysicalScene(false);
@@ -1175,18 +1172,11 @@ namespace OpenSim.Region.Framework.Scenes
1175 m_LastFinitePos = m_pos; 1172 m_LastFinitePos = m_pos;
1176 } 1173 }
1177 1174
1178 //m_physicsActor.AddForce(new PhysicsVector(999999999, 99999999, 999999999999999), true); 1175 #endregion Sanity Checking
1179 1176
1180 //ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y); 1177 #region Inputs
1181 //if (land != null)
1182 //{
1183 //if (land.landData.landingType == (byte)1 && land.landData.userLocation != Vector3.Zero)
1184 //{
1185 // agent.startpos = land.landData.userLocation;
1186 //}
1187 //}
1188 1178
1189 uint flags = agentData.ControlFlags; 1179 AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags;
1190 Quaternion bodyRotation = agentData.BodyRotation; 1180 Quaternion bodyRotation = agentData.BodyRotation;
1191 1181
1192 // Camera location in world. We'll need to raytrace 1182 // Camera location in world. We'll need to raytrace
@@ -1207,87 +1197,85 @@ namespace OpenSim.Region.Framework.Scenes
1207 // The Agent's Draw distance setting 1197 // The Agent's Draw distance setting
1208 m_DrawDistance = agentData.Far; 1198 m_DrawDistance = agentData.Far;
1209 1199
1210 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0)
1211 {
1212 StandUp();
1213 }
1214
1215 // Check if Client has camera in 'follow cam' or 'build' mode. 1200 // Check if Client has camera in 'follow cam' or 'build' mode.
1216 Vector3 camdif = (Vector3.One * m_bodyRot - Vector3.One * CameraRotation); 1201 Vector3 camdif = (Vector3.One * m_bodyRot - Vector3.One * CameraRotation);
1217 1202
1218 m_followCamAuto = ((m_CameraUpAxis.Z > 0.959f && m_CameraUpAxis.Z < 0.98f) 1203 m_followCamAuto = ((m_CameraUpAxis.Z > 0.959f && m_CameraUpAxis.Z < 0.98f)
1219 && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false; 1204 && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false;
1220 1205
1206 m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0;
1207 m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0;
1208
1209 #endregion Inputs
1210
1211 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0)
1212 {
1213 StandUp();
1214 }
1215
1221 //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto); 1216 //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto);
1222 // Raycast from the avatar's head to the camera to see if there's anything blocking the view 1217 // Raycast from the avatar's head to the camera to see if there's anything blocking the view
1223 if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast()) 1218 if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast())
1224 { 1219 {
1225 if (m_followCamAuto) 1220 if (m_followCamAuto)
1226 { 1221 {
1227 Vector3 headadjustment = new Vector3(0, 0, 0.3f); 1222 Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT;
1228 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - (m_pos + headadjustment)), Vector3.Distance(m_CameraCenter, (m_pos + headadjustment)) + 0.3f, RayCastCameraCallback); 1223 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1229 } 1224 }
1230 } 1225 }
1231 1226
1232 m_mouseLook = (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0;
1233 m_leftButtonDown = (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0;
1234
1235 lock (scriptedcontrols) 1227 lock (scriptedcontrols)
1236 { 1228 {
1237 if (scriptedcontrols.Count > 0) 1229 if (scriptedcontrols.Count > 0)
1238 { 1230 {
1239 SendControlToScripts(flags); 1231 SendControlToScripts((uint)flags);
1240 flags = RemoveIgnoredControls(flags, IgnoredControls); 1232 flags = RemoveIgnoredControls(flags, IgnoredControls);
1241 } 1233 }
1242 } 1234 }
1243 1235
1244 if (PhysicsActor == null)
1245 {
1246 return;
1247 }
1248
1249 if (m_autopilotMoving) 1236 if (m_autopilotMoving)
1250 CheckAtSitTarget(); 1237 CheckAtSitTarget();
1251 1238
1252 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1239 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1253 { 1240 {
1254 // TODO: This doesn't prevent the user from walking yet. 1241 // TODO: This doesn't prevent the user from walking yet.
1255 // Setting parent ID would fix this, if we knew what value 1242 // Setting parent ID would fix this, if we knew what value
1256 // to use. Or we could add a m_isSitting variable. 1243 // to use. Or we could add a m_isSitting variable.
1257
1258 TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); 1244 TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1259 } 1245 }
1246
1260 // In the future, these values might need to go global. 1247 // In the future, these values might need to go global.
1261 // Here's where you get them. 1248 // Here's where you get them.
1262
1263 m_AgentControlFlags = flags; 1249 m_AgentControlFlags = flags;
1264 m_headrotation = agentData.HeadRotation; 1250 m_headrotation = agentData.HeadRotation;
1265 m_state = agentData.State; 1251 m_state = agentData.State;
1266 1252
1253 PhysicsActor actor = PhysicsActor;
1254 if (actor == null)
1255 {
1256 return;
1257 }
1258
1267 if (m_allowMovement) 1259 if (m_allowMovement)
1268 { 1260 {
1269 int i = 0; 1261 int i = 0;
1270 bool update_movementflag = false; 1262 bool update_movementflag = false;
1271 bool update_rotation = false; 1263 bool update_rotation = false;
1272 bool DCFlagKeyPressed = false; 1264 bool DCFlagKeyPressed = false;
1273 Vector3 agent_control_v3 = new Vector3(0, 0, 0); 1265 Vector3 agent_control_v3 = Vector3.Zero;
1274 Quaternion q = bodyRotation; 1266 Quaternion q = bodyRotation;
1275 if (PhysicsActor != null)
1276 {
1277 bool oldflying = PhysicsActor.Flying;
1278 1267
1279 if (m_forceFly) 1268 bool oldflying = PhysicsActor.Flying;
1280 PhysicsActor.Flying = true;
1281 else if (m_flyDisabled)
1282 PhysicsActor.Flying = false;
1283 else
1284 PhysicsActor.Flying = ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1285 1269
1286 if (PhysicsActor.Flying != oldflying) 1270 if (m_forceFly)
1287 { 1271 actor.Flying = true;
1288 update_movementflag = true; 1272 else if (m_flyDisabled)
1289 } 1273 actor.Flying = false;
1290 } 1274 else
1275 actor.Flying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1276
1277 if (actor.Flying != oldflying)
1278 update_movementflag = true;
1291 1279
1292 if (q != m_bodyRot) 1280 if (q != m_bodyRot)
1293 { 1281 {
@@ -1309,10 +1297,9 @@ namespace OpenSim.Region.Framework.Scenes
1309 else 1297 else
1310 dirVectors = Dir_Vectors; 1298 dirVectors = Dir_Vectors;
1311 1299
1312 1300 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1313 foreach (Dir_ControlFlags DCF in m_dirControlFlags)
1314 { 1301 {
1315 if ((flags & (uint)DCF) != 0) 1302 if (((uint)flags & (uint)DCF) != 0)
1316 { 1303 {
1317 bResetMoveToPosition = true; 1304 bResetMoveToPosition = true;
1318 DCFlagKeyPressed = true; 1305 DCFlagKeyPressed = true;
@@ -1358,7 +1345,7 @@ namespace OpenSim.Region.Framework.Scenes
1358 if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving)) 1345 if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving))
1359 { 1346 {
1360 //Check the error term of the current position in relation to the target position 1347 //Check the error term of the current position in relation to the target position
1361 if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 1.5) 1348 if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 1.5f)
1362 { 1349 {
1363 // we are close enough to the target 1350 // we are close enough to the target
1364 m_moveToPositionTarget = Vector3.Zero; 1351 m_moveToPositionTarget = Vector3.Zero;
@@ -1439,8 +1426,8 @@ namespace OpenSim.Region.Framework.Scenes
1439 if (m_physicsActor != null && m_physicsActor.Flying && !m_forceFly) 1426 if (m_physicsActor != null && m_physicsActor.Flying && !m_forceFly)
1440 { 1427 {
1441 // Are the landing controls requirements filled? 1428 // Are the landing controls requirements filled?
1442 bool controlland = (((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || 1429 bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) ||
1443 ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); 1430 ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
1444 1431
1445 // Are the collision requirements fulfilled? 1432 // Are the collision requirements fulfilled?
1446 bool colliding = (m_physicsActor.IsColliding == true); 1433 bool colliding = (m_physicsActor.IsColliding == true);
@@ -1537,7 +1524,7 @@ namespace OpenSim.Region.Framework.Scenes
1537 if (part != null) 1524 if (part != null)
1538 { 1525 {
1539 AbsolutePosition = part.AbsolutePosition; 1526 AbsolutePosition = part.AbsolutePosition;
1540 Velocity = new Vector3(0, 0, 0); 1527 Velocity = Vector3.Zero;
1541 SendFullUpdateToAllClients(); 1528 SendFullUpdateToAllClients();
1542 1529
1543 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1530 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID);
@@ -1607,7 +1594,7 @@ namespace OpenSim.Region.Framework.Scenes
1607 } 1594 }
1608 1595
1609 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1596 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight);
1610 m_parentPosition = new Vector3(); 1597 m_parentPosition = Vector3.Zero;
1611 1598
1612 m_parentID = 0; 1599 m_parentID = 0;
1613 SendFullUpdateToAllClients(); 1600 SendFullUpdateToAllClients();
@@ -1834,7 +1821,7 @@ namespace OpenSim.Region.Framework.Scenes
1834 //Quaternion result = (sitTargetOrient * vq) * nq; 1821 //Quaternion result = (sitTargetOrient * vq) * nq;
1835 1822
1836 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 1823 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
1837 m_pos += m_sitTargetCorrectionOffset; 1824 m_pos += SIT_TARGET_ADJUSTMENT;
1838 m_bodyRot = sitTargetOrient; 1825 m_bodyRot = sitTargetOrient;
1839 //Rotation = sitTargetOrient; 1826 //Rotation = sitTargetOrient;
1840 m_parentPosition = part.AbsolutePosition; 1827 m_parentPosition = part.AbsolutePosition;
@@ -1854,7 +1841,7 @@ namespace OpenSim.Region.Framework.Scenes
1854 } 1841 }
1855 m_parentID = m_requestedSitTargetID; 1842 m_parentID = m_requestedSitTargetID;
1856 1843
1857 Velocity = new Vector3(0, 0, 0); 1844 Velocity = Vector3.Zero;
1858 RemoveFromPhysicalScene(); 1845 RemoveFromPhysicalScene();
1859 1846
1860 TrySetMovementAnimation(sitAnimation); 1847 TrySetMovementAnimation(sitAnimation);
@@ -2011,7 +1998,7 @@ namespace OpenSim.Region.Framework.Scenes
2011 protected void TrySetMovementAnimation(string anim) 1998 protected void TrySetMovementAnimation(string anim)
2012 { 1999 {
2013 //m_log.DebugFormat("Updating movement animation to {0}", anim); 2000 //m_log.DebugFormat("Updating movement animation to {0}", anim);
2014 2001
2015 if (!m_isChildAgent) 2002 if (!m_isChildAgent)
2016 { 2003 {
2017 if (m_animations.TrySetDefaultAnimation(anim, m_controllingClient.NextAnimationSequenceNumber, UUID.Zero)) 2004 if (m_animations.TrySetDefaultAnimation(anim, m_controllingClient.NextAnimationSequenceNumber, UUID.Zero))
@@ -2046,200 +2033,169 @@ namespace OpenSim.Region.Framework.Scenes
2046 /// </summary> 2033 /// </summary>
2047 public string GetMovementAnimation() 2034 public string GetMovementAnimation()
2048 { 2035 {
2049 if ((m_animPersistUntil > 0) && (m_animPersistUntil > DateTime.Now.Ticks)) 2036 const float FALL_DELAY = 0.33f;
2050 { 2037 const float PREJUMP_DELAY = 0.25f;
2051 //We don't want our existing state to end yet.
2052 return m_movementAnimation;
2053 2038
2054 } 2039 #region Inputs
2055 else if (m_movementflag != 0) 2040
2041 AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_AgentControlFlags;
2042 PhysicsActor actor = m_physicsActor;
2043
2044 // Create forward and left vectors from the current avatar rotation
2045 Matrix4 rotMatrix = Matrix4.CreateFromQuaternion(m_bodyRot);
2046 Vector3 fwd = Vector3.Transform(Vector3.UnitX, rotMatrix);
2047 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix);
2048
2049 // Check control flags
2050 bool heldForward = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS;
2051 bool heldBack = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG;
2052 bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS;
2053 bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG;
2054 //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;
2055 //bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
2056 bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS;
2057 bool heldDown = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG;
2058 //bool flying = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY;
2059 //bool mouselook = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) == AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK;
2060
2061 // Direction in which the avatar is trying to move
2062 Vector3 move = Vector3.Zero;
2063 if (heldForward) { move.X += fwd.X; move.Y += fwd.Y; }
2064 if (heldBack) { move.X -= fwd.X; move.Y -= fwd.Y; }
2065 if (heldLeft) { move.X += left.X; move.Y += left.Y; }
2066 if (heldRight) { move.X -= left.X; move.Y -= left.Y; }
2067 if (heldUp) { move.Z += 1; }
2068 if (heldDown) { move.Z -= 1; }
2069
2070 // Is the avatar trying to move?
2071 bool moving = (move != Vector3.Zero);
2072 bool jumping = m_animTickJump != 0;
2073
2074 #endregion Inputs
2075
2076 #region Flying
2077
2078 if (actor != null && actor.Flying)
2056 { 2079 {
2057 //We're moving 2080 m_animTickFall = 0;
2058 m_allowFalling = true; 2081 m_animTickJump = 0;
2059 if (PhysicsActor != null && PhysicsActor.IsColliding) 2082
2083 if (move.X != 0f || move.Y != 0f)
2060 { 2084 {
2061 //And colliding. Can you guess what it is yet? 2085 return (m_useFlySlow ? "FLYSLOW" : "FLY");
2062 if ((m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) 2086 }
2063 { 2087 else if (move.Z > 0f)
2064 //Down key is being pressed. 2088 {
2065 if ((m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) + (m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0) 2089 return "HOVER_UP";
2066 { 2090 }
2067 return "CROUCHWALK"; 2091 else if (move.Z < 0f)
2068 } 2092 {
2069 else 2093 if (actor != null && actor.IsColliding)
2070 { 2094 return "LAND";
2071 return "CROUCH";
2072 }
2073 }
2074 else if (m_setAlwaysRun)
2075 {
2076 return "RUN";
2077 }
2078 else 2095 else
2079 { 2096 return "HOVER_DOWN";
2080 //If we're prejumping then inhibit this, it's a problem
2081 //caused by a false positive on IsColliding
2082 if (m_movementAnimation == "PREJUMP")
2083 {
2084 return "PREJUMP";
2085 }
2086 else
2087 {
2088 return "WALK";
2089 }
2090 }
2091
2092 } 2097 }
2093 else 2098 else
2094 { 2099 {
2095 //We're not colliding. Colliding isn't cool these days. 2100 return "HOVER";
2096 if (PhysicsActor != null && PhysicsActor.Flying) 2101 }
2097 { 2102 }
2098 //Are we moving forwards or backwards?
2099 if ((m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0)
2100 {
2101 //Then we really are flying
2102 if (m_setAlwaysRun)
2103 {
2104 return "FLY";
2105 }
2106 else
2107 {
2108 if (m_useFlySlow == false)
2109 {
2110 return "FLY";
2111 }
2112 else
2113 {
2114 return "FLYSLOW";
2115 }
2116 }
2117 }
2118 else
2119 {
2120 if ((m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0)
2121 {
2122 return "HOVER_UP";
2123 }
2124 else
2125 {
2126 return "HOVER_DOWN";
2127 }
2128 }
2129 2103
2130 } 2104 #endregion Flying
2131 else if (m_movementAnimation == "JUMP")
2132 {
2133 //If we were already jumping, continue to jump until we collide
2134 return "JUMP";
2135 2105
2136 } 2106 #region Falling/Floating/Landing
2137 else if (m_movementAnimation == "PREJUMP" && (m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == 0)
2138 {
2139 //If we were in a prejump, and the UP key is no longer being held down
2140 //then we're not going to fly, so we're jumping
2141 return "JUMP";
2142 2107
2143 } 2108 if (actor == null || !actor.IsColliding)
2144 else if ((m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0) 2109 {
2145 { 2110 float fallElapsed = (float)(Environment.TickCount - m_animTickFall) / 1000f;
2146 //They're pressing up, so we're either going to fly or jump 2111 float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f;
2147 return "PREJUMP"; 2112
2148 } 2113 if (m_animTickFall == 0 || (fallElapsed > FALL_DELAY && fallVelocity >= 0.0f))
2149 else 2114 {
2150 { 2115 // Just started falling
2151 //If we're moving and not flying and not jumping and not colliding.. 2116 m_animTickFall = Environment.TickCount;
2152
2153 if (m_movementAnimation == "WALK" || m_movementAnimation == "RUN")
2154 {
2155 //Let's not enter a FALLDOWN state here, since we're probably
2156 //not colliding because we're going down hill.
2157 return m_movementAnimation;
2158 }
2159 //Record the time we enter this state so we know whether to "land" or not
2160 m_animPersistUntil = DateTime.Now.Ticks;
2161 return "FALLDOWN";
2162
2163 }
2164 } 2117 }
2118 else if (!jumping && fallElapsed > FALL_DELAY)
2119 {
2120 // Falling long enough to trigger the animation
2121 return "FALLDOWN";
2122 }
2123
2124 return m_movementAnimation;
2165 } 2125 }
2166 else 2126
2127 #endregion Falling/Floating/Landing
2128
2129 #region Ground Movement
2130
2131 if (m_movementAnimation == "FALLDOWN")
2167 { 2132 {
2168 //We're not moving. 2133 m_animTickFall = Environment.TickCount;
2169 if (PhysicsActor != null && PhysicsActor.IsColliding)
2170 {
2171 //But we are colliding.
2172 if (m_movementAnimation == "FALLDOWN")
2173 {
2174 //We're re-using the m_animPersistUntil value here to see how long we've been falling
2175 if ((DateTime.Now.Ticks - m_animPersistUntil) > TimeSpan.TicksPerSecond)
2176 {
2177 //Make sure we don't change state for a bit
2178 m_animPersistUntil = DateTime.Now.Ticks + TimeSpan.TicksPerSecond;
2179 return "LAND";
2180 }
2181 else
2182 {
2183 //We haven't been falling very long, we were probably just walking down hill
2184 return "STAND";
2185 }
2186 }
2187 else if (m_movementAnimation == "JUMP" || m_movementAnimation == "HOVER_DOWN")
2188 {
2189 //Make sure we don't change state for a bit
2190 m_animPersistUntil = DateTime.Now.Ticks + (1 * TimeSpan.TicksPerSecond);
2191 return "SOFT_LAND";
2192 2134
2193 } 2135 // TODO: SOFT_LAND support
2194 else if ((m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0) 2136 return "LAND";
2195 { 2137 }
2196 return "PREJUMP"; 2138 else if (m_movementAnimation == "LAND")
2197 } 2139 {
2198 else if (PhysicsActor != null && PhysicsActor.Flying) 2140 float landElapsed = (float)(Environment.TickCount - m_animTickFall) / 1000f;
2199 {
2200 m_allowFalling = true;
2201 if ((m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0)
2202 {
2203 return "HOVER_UP";
2204 }
2205 else if ((m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0)
2206 {
2207 return "HOVER_DOWN";
2208 }
2209 else
2210 {
2211 return "HOVER";
2212 }
2213 }
2214 else
2215 {
2216 return "STAND";
2217 }
2218 2141
2142 if (landElapsed <= FALL_DELAY)
2143 return "LAND";
2144 }
2145
2146 m_animTickFall = 0;
2147
2148 if (move.Z > 0f)
2149 {
2150 // Jumping
2151 if (!jumping)
2152 {
2153 // Begin prejump
2154 m_animTickJump = Environment.TickCount;
2155 return "PREJUMP";
2219 } 2156 }
2220 else 2157 else if (Environment.TickCount - m_animTickJump > PREJUMP_DELAY * 1000.0f)
2221 { 2158 {
2222 //We're not colliding. 2159 // Start actual jump
2223 if (PhysicsActor != null && PhysicsActor.Flying) 2160 if (m_animTickJump == -1)
2224 { 2161 {
2225 2162 // Already jumping! End the current jump
2226 return "HOVER"; 2163 m_animTickJump = 0;
2227 2164 return "JUMP";
2228 } 2165 }
2229 else if ((m_movementAnimation == "JUMP" || m_movementAnimation == "PREJUMP") && (m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == 0)
2230 {
2231 2166
2232 return "JUMP"; 2167 m_animTickJump = -1;
2168 return "JUMP";
2169 }
2170 }
2171 else
2172 {
2173 // Not jumping
2174 m_animTickJump = 0;
2233 2175
2234 } 2176 if (move.X != 0f || move.Y != 0f)
2177 {
2178 // Walking / crouchwalking / running
2179 if (move.Z < 0f)
2180 return "CROUCHWALK";
2181 else if (m_setAlwaysRun)
2182 return "RUN";
2235 else 2183 else
2236 { 2184 return "WALK";
2237 //Record the time we enter this state so we know whether to "land" or not 2185 }
2238 m_animPersistUntil = DateTime.Now.Ticks; 2186 else
2239 return "FALLDOWN"; // this falling animation is invoked too frequently when capsule tilt correction is used - why? 2187 {
2240 } 2188 // Not walking
2189 if (move.Z < 0f)
2190 return "CROUCH";
2191 else
2192 return "STAND";
2241 } 2193 }
2242 } 2194 }
2195
2196 #endregion Ground Movement
2197
2198 return m_movementAnimation;
2243 } 2199 }
2244 2200
2245 /// <summary> 2201 /// <summary>
@@ -2247,24 +2203,16 @@ namespace OpenSim.Region.Framework.Scenes
2247 /// </summary> 2203 /// </summary>
2248 protected void UpdateMovementAnimations() 2204 protected void UpdateMovementAnimations()
2249 { 2205 {
2250 string movementAnimation = GetMovementAnimation(); 2206 m_movementAnimation = GetMovementAnimation();
2251 2207
2252 if (movementAnimation == "FALLDOWN" && m_allowFalling == false) 2208 if (m_movementAnimation == "PREJUMP" && !m_usePreJump)
2253 {
2254 movementAnimation = m_movementAnimation;
2255 }
2256 else
2257 {
2258 m_movementAnimation = movementAnimation;
2259 }
2260 if (movementAnimation == "PREJUMP" && m_usePreJump == false)
2261 { 2209 {
2262 //This was the previous behavior before PREJUMP 2210 // This was the previous behavior before PREJUMP
2263 TrySetMovementAnimation("JUMP"); 2211 TrySetMovementAnimation("JUMP");
2264 } 2212 }
2265 else 2213 else
2266 { 2214 {
2267 TrySetMovementAnimation(movementAnimation); 2215 TrySetMovementAnimation(m_movementAnimation);
2268 } 2216 }
2269 } 2217 }
2270 2218
@@ -2277,7 +2225,7 @@ namespace OpenSim.Region.Framework.Scenes
2277 { 2225 {
2278 if (m_isChildAgent) 2226 if (m_isChildAgent)
2279 { 2227 {
2280 m_log.Debug("DEBUG: AddNewMovement: child agent, Making root agent!"); 2228 m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent, making root agent!");
2281 2229
2282 // we have to reset the user's child agent connections. 2230 // we have to reset the user's child agent connections.
2283 // Likely, here they've lost the eventqueue for other regions so border 2231 // Likely, here they've lost the eventqueue for other regions so border
@@ -2286,7 +2234,7 @@ namespace OpenSim.Region.Framework.Scenes
2286 List<ulong> regions = new List<ulong>(KnownChildRegionHandles); 2234 List<ulong> regions = new List<ulong>(KnownChildRegionHandles);
2287 regions.Remove(m_scene.RegionInfo.RegionHandle); 2235 regions.Remove(m_scene.RegionInfo.RegionHandle);
2288 2236
2289 MakeRootAgent(new Vector3(127, 127, 127), true); 2237 MakeRootAgent(new Vector3(127f, 127f, 127f), true);
2290 2238
2291 // Async command 2239 // Async command
2292 if (m_scene.SceneGridService != null) 2240 if (m_scene.SceneGridService != null)
@@ -2298,47 +2246,45 @@ namespace OpenSim.Region.Framework.Scenes
2298 System.Threading.Thread.Sleep(500); 2246 System.Threading.Thread.Sleep(500);
2299 } 2247 }
2300 2248
2301
2302 if (m_scene.SceneGridService != null) 2249 if (m_scene.SceneGridService != null)
2303 { 2250 {
2304 m_scene.SceneGridService.EnableNeighbourChildAgents(this, new List<RegionInfo>()); 2251 m_scene.SceneGridService.EnableNeighbourChildAgents(this, new List<RegionInfo>());
2305 } 2252 }
2306 2253
2307
2308
2309 return; 2254 return;
2310 } 2255 }
2311 2256
2312 m_perfMonMS = Environment.TickCount; 2257 m_perfMonMS = Environment.TickCount;
2313 2258
2314 m_rotation = rotation; 2259 m_rotation = rotation;
2315 NewForce newVelocity = new NewForce();
2316 Vector3 direc = vec * rotation; 2260 Vector3 direc = vec * rotation;
2317 direc.Normalize(); 2261 direc.Normalize();
2318 2262
2319 direc *= 0.03f * 128f * m_speedModifier; 2263 direc *= 0.03f * 128f * m_speedModifier;
2320 if (m_physicsActor.Flying) 2264
2321 { 2265 PhysicsActor actor = m_physicsActor;
2322 direc *= 4; 2266 if (actor != null)
2323 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
2324 //bool colliding = (m_physicsActor.IsColliding==true);
2325 //if (controlland)
2326 // m_log.Info("[AGENT]: landCommand");
2327 //if (colliding)
2328 // m_log.Info("[AGENT]: colliding");
2329 //if (m_physicsActor.Flying && colliding && controlland)
2330 //{
2331 // StopFlying();
2332 // m_log.Info("[AGENT]: Stop FLying");
2333 //}
2334 }
2335 else
2336 { 2267 {
2337 if (!m_physicsActor.Flying && m_physicsActor.IsColliding) 2268 if (actor.Flying)
2269 {
2270 direc *= 4.0f;
2271 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
2272 //bool colliding = (m_physicsActor.IsColliding==true);
2273 //if (controlland)
2274 // m_log.Info("[AGENT]: landCommand");
2275 //if (colliding)
2276 // m_log.Info("[AGENT]: colliding");
2277 //if (m_physicsActor.Flying && colliding && controlland)
2278 //{
2279 // StopFlying();
2280 // m_log.Info("[AGENT]: Stop FLying");
2281 //}
2282 }
2283 else if (!actor.Flying && actor.IsColliding)
2338 { 2284 {
2339 if (direc.Z > 2.0f) 2285 if (direc.Z > 2.0f)
2340 { 2286 {
2341 direc.Z *= 3; 2287 direc.Z *= 3.0f;
2342 2288
2343 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2289 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
2344 TrySetMovementAnimation("PREJUMP"); 2290 TrySetMovementAnimation("PREJUMP");
@@ -2347,10 +2293,8 @@ namespace OpenSim.Region.Framework.Scenes
2347 } 2293 }
2348 } 2294 }
2349 2295
2350 newVelocity.X = direc.X; 2296 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2351 newVelocity.Y = direc.Y; 2297 m_forceToApply = direc;
2352 newVelocity.Z = direc.Z;
2353 m_forcesList.Add(newVelocity);
2354 2298
2355 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); 2299 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS);
2356 } 2300 }
@@ -2361,8 +2305,10 @@ namespace OpenSim.Region.Framework.Scenes
2361 2305
2362 public override void Update() 2306 public override void Update()
2363 { 2307 {
2364 const float VELOCITY_TOLERANCE = 0.01f; 2308 const float ROTATION_TOLERANCE = 0.01f;
2365 const float POSITION_TOLERANCE = 10.0f; 2309 const float VELOCITY_TOLERANCE = 0.001f;
2310 const float POSITION_TOLERANCE = 0.05f;
2311 //const int TIME_MS_TOLERANCE = 3000;
2366 2312
2367 SendPrimUpdates(); 2313 SendPrimUpdates();
2368 2314
@@ -2374,17 +2320,25 @@ namespace OpenSim.Region.Framework.Scenes
2374 2320
2375 if (m_isChildAgent == false) 2321 if (m_isChildAgent == false)
2376 { 2322 {
2323 PhysicsActor actor = m_physicsActor;
2324
2325 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to
2326 // grab the latest PhysicsActor velocity, whereas m_velocity is often
2327 // storing a requested force instead of an actual traveling velocity
2328
2377 // Throw away duplicate or insignificant updates 2329 // Throw away duplicate or insignificant updates
2378 if (m_bodyRot != m_lastRotation || 2330 if (!m_bodyRot.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) ||
2379 (m_velocity - m_lastVelocity).Length() > VELOCITY_TOLERANCE || 2331 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
2380 (m_pos - m_lastPosition).Length() > POSITION_TOLERANCE) 2332 !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
2333 //Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE)
2381 { 2334 {
2382 SendTerseUpdateToAllClients(); 2335 SendTerseUpdateToAllClients();
2383 2336
2384 // Update the "last" values 2337 // Update the "last" values
2385 m_lastPosition = m_pos; 2338 m_lastPosition = m_pos;
2386 m_lastRotation = m_bodyRot; 2339 m_lastRotation = m_bodyRot;
2387 m_lastVelocity = m_velocity; 2340 m_lastVelocity = Velocity;
2341 //m_lastTerseSent = Environment.TickCount;
2388 } 2342 }
2389 2343
2390 // followed suggestion from mic bowman. reversed the two lines below. 2344 // followed suggestion from mic bowman. reversed the two lines below.
@@ -2410,11 +2364,16 @@ namespace OpenSim.Region.Framework.Scenes
2410 { 2364 {
2411 m_perfMonMS = Environment.TickCount; 2365 m_perfMonMS = Environment.TickCount;
2412 2366
2367 PhysicsActor actor = m_physicsActor;
2368 Vector3 velocity = (actor != null) ? actor.Velocity : Vector3.Zero;
2369
2413 Vector3 pos = m_pos; 2370 Vector3 pos = m_pos;
2414 pos.Z -= m_appearance.HipOffset; 2371 pos.Z += m_appearance.HipOffset;
2415 2372
2416 remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_regionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 2373 //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity);
2417 pos, m_velocity, Vector3.Zero, m_bodyRot, Vector4.UnitW, m_uuid, null, GetUpdatePriority(remoteClient))); 2374
2375 remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
2376 pos, velocity, Vector3.Zero, m_bodyRot, CollisionPlane, m_uuid, null, GetUpdatePriority(remoteClient)));
2418 2377
2419 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); 2378 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS);
2420 m_scene.StatsReporter.AddAgentUpdates(1); 2379 m_scene.StatsReporter.AddAgentUpdates(1);
@@ -2510,7 +2469,7 @@ namespace OpenSim.Region.Framework.Scenes
2510 return; 2469 return;
2511 2470
2512 Vector3 pos = m_pos; 2471 Vector3 pos = m_pos;
2513 pos.Z -= m_appearance.HipOffset; 2472 pos.Z += m_appearance.HipOffset;
2514 2473
2515 remoteAvatar.m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, 2474 remoteAvatar.m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid,
2516 LocalId, pos, m_appearance.Texture.GetBytes(), 2475 LocalId, pos, m_appearance.Texture.GetBytes(),
@@ -2581,7 +2540,7 @@ namespace OpenSim.Region.Framework.Scenes
2581 // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); 2540 // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance);
2582 2541
2583 Vector3 pos = m_pos; 2542 Vector3 pos = m_pos;
2584 pos.Z -= m_appearance.HipOffset; 2543 pos.Z += m_appearance.HipOffset;
2585 2544
2586 m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, 2545 m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId,
2587 pos, m_appearance.Texture.GetBytes(), m_parentID, m_bodyRot)); 2546 pos, m_appearance.Texture.GetBytes(), m_parentID, m_bodyRot));
@@ -2690,7 +2649,7 @@ namespace OpenSim.Region.Framework.Scenes
2690 } 2649 }
2691 2650
2692 Vector3 pos = m_pos; 2651 Vector3 pos = m_pos;
2693 pos.Z -= m_appearance.HipOffset; 2652 pos.Z += m_appearance.HipOffset;
2694 2653
2695 m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, 2654 m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId,
2696 pos, m_appearance.Texture.GetBytes(), m_parentID, m_bodyRot)); 2655 pos, m_appearance.Texture.GetBytes(), m_parentID, m_bodyRot));
@@ -2778,7 +2737,8 @@ namespace OpenSim.Region.Framework.Scenes
2778 } 2737 }
2779 2738
2780 // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m 2739 // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m
2781 if (Util.GetDistanceTo(AbsolutePosition, m_LastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance) 2740 if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance ||
2741 Util.GetDistanceTo(CameraPosition, m_lastChildAgentUpdateCamPosition) >= Scene.ChildReprioritizationDistance)
2782 { 2742 {
2783 ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); 2743 ChildAgentDataUpdate cadu = new ChildAgentDataUpdate();
2784 cadu.ActiveGroupID = UUID.Zero.Guid; 2744 cadu.ActiveGroupID = UUID.Zero.Guid;
@@ -2792,7 +2752,7 @@ namespace OpenSim.Region.Framework.Scenes
2792 cadu.godlevel = m_godlevel; 2752 cadu.godlevel = m_godlevel;
2793 cadu.GroupAccess = 0; 2753 cadu.GroupAccess = 0;
2794 cadu.Position = new sLLVector3(AbsolutePosition); 2754 cadu.Position = new sLLVector3(AbsolutePosition);
2795 cadu.regionHandle = m_scene.RegionInfo.RegionHandle; 2755 cadu.regionHandle = m_rootRegionHandle;
2796 float multiplier = 1; 2756 float multiplier = 1;
2797 int innacurateNeighbors = m_scene.GetInaccurateNeighborCount(); 2757 int innacurateNeighbors = m_scene.GetInaccurateNeighborCount();
2798 if (innacurateNeighbors != 0) 2758 if (innacurateNeighbors != 0)
@@ -2812,11 +2772,9 @@ namespace OpenSim.Region.Framework.Scenes
2812 agentpos.CopyFrom(cadu); 2772 agentpos.CopyFrom(cadu);
2813 2773
2814 m_scene.SendOutChildAgentUpdates(agentpos, this); 2774 m_scene.SendOutChildAgentUpdates(agentpos, this);
2815
2816 m_LastChildAgentUpdatePosition.X = AbsolutePosition.X;
2817 m_LastChildAgentUpdatePosition.Y = AbsolutePosition.Y;
2818 m_LastChildAgentUpdatePosition.Z = AbsolutePosition.Z;
2819 2775
2776 m_lastChildAgentUpdatePosition = AbsolutePosition;
2777 m_lastChildAgentUpdateCamPosition = CameraPosition;
2820 } 2778 }
2821 } 2779 }
2822 2780
@@ -2941,9 +2899,9 @@ namespace OpenSim.Region.Framework.Scenes
2941 m_inTransit = true; 2899 m_inTransit = true;
2942 2900
2943 if ((m_physicsActor != null) && m_physicsActor.Flying) 2901 if ((m_physicsActor != null) && m_physicsActor.Flying)
2944 m_AgentControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; 2902 m_AgentControlFlags |= AgentManager.ControlFlags.AGENT_CONTROL_FLY;
2945 else if ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0) 2903 else if ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0)
2946 m_AgentControlFlags &= ~(uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; 2904 m_AgentControlFlags &= ~AgentManager.ControlFlags.AGENT_CONTROL_FLY;
2947 } 2905 }
2948 2906
2949 public void NotInTransit() 2907 public void NotInTransit()
@@ -2959,7 +2917,7 @@ namespace OpenSim.Region.Framework.Scenes
2959 public void Reset() 2917 public void Reset()
2960 { 2918 {
2961 // Put the child agent back at the center 2919 // Put the child agent back at the center
2962 AbsolutePosition = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 70); 2920 AbsolutePosition = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f), 70);
2963 ResetAnimations(); 2921 ResetAnimations();
2964 } 2922 }
2965 2923
@@ -3069,9 +3027,11 @@ namespace OpenSim.Region.Framework.Scenes
3069 int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize; 3027 int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize;
3070 int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize; 3028 int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize;
3071 3029
3030 Vector3 offset = new Vector3(shiftx, shifty, 0f);
3031
3072 m_DrawDistance = cAgentData.Far; 3032 m_DrawDistance = cAgentData.Far;
3073 if (cAgentData.Position != new Vector3(-1, -1, -1)) // UGH!! 3033 if (cAgentData.Position != new Vector3(-1f, -1f, -1f)) // UGH!!
3074 m_pos = new Vector3(cAgentData.Position.X + shiftx, cAgentData.Position.Y + shifty, cAgentData.Position.Z); 3034 m_pos = cAgentData.Position + offset;
3075 3035
3076 if (Vector3.Distance(AbsolutePosition, posLastSignificantMove) >= Scene.ChildReprioritizationDistance) 3036 if (Vector3.Distance(AbsolutePosition, posLastSignificantMove) >= Scene.ChildReprioritizationDistance)
3077 { 3037 {
@@ -3079,8 +3039,7 @@ namespace OpenSim.Region.Framework.Scenes
3079 ReprioritizeUpdates(); 3039 ReprioritizeUpdates();
3080 } 3040 }
3081 3041
3082 // It's hard to say here.. We can't really tell where the camera position is unless it's in world cordinates from the sending region 3042 m_CameraCenter = cAgentData.Center + offset;
3083 m_CameraCenter = cAgentData.Center;
3084 3043
3085 m_avHeight = cAgentData.Size.Z; 3044 m_avHeight = cAgentData.Size.Z;
3086 //SetHeight(cAgentData.AVHeight); 3045 //SetHeight(cAgentData.AVHeight);
@@ -3093,16 +3052,16 @@ namespace OpenSim.Region.Framework.Scenes
3093 m_sceneViewer.Reset(); 3052 m_sceneViewer.Reset();
3094 3053
3095 //cAgentData.AVHeight; 3054 //cAgentData.AVHeight;
3096 //cAgentData.regionHandle; 3055 m_rootRegionHandle = cAgentData.RegionHandle;
3097 //m_velocity = cAgentData.Velocity; 3056 //m_velocity = cAgentData.Velocity;
3098 } 3057 }
3099 3058
3100 public void CopyTo(AgentData cAgent) 3059 public void CopyTo(AgentData cAgent)
3101 { 3060 {
3102 cAgent.AgentID = UUID; 3061 cAgent.AgentID = UUID;
3103 cAgent.RegionHandle = m_scene.RegionInfo.RegionHandle; 3062 cAgent.RegionHandle = m_rootRegionHandle;
3104 3063
3105 cAgent.Position = m_pos; 3064 cAgent.Position = AbsolutePosition;
3106 cAgent.Velocity = m_velocity; 3065 cAgent.Velocity = m_velocity;
3107 cAgent.Center = m_CameraCenter; 3066 cAgent.Center = m_CameraCenter;
3108 // Don't copy the size; it is inferred from apearance parameters 3067 // Don't copy the size; it is inferred from apearance parameters
@@ -3129,7 +3088,7 @@ namespace OpenSim.Region.Framework.Scenes
3129 3088
3130 cAgent.HeadRotation = m_headrotation; 3089 cAgent.HeadRotation = m_headrotation;
3131 cAgent.BodyRotation = m_bodyRot; 3090 cAgent.BodyRotation = m_bodyRot;
3132 cAgent.ControlFlags = m_AgentControlFlags; 3091 cAgent.ControlFlags = (uint)m_AgentControlFlags;
3133 3092
3134 if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID))) 3093 if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID)))
3135 cAgent.GodLevel = (byte)m_godlevel; 3094 cAgent.GodLevel = (byte)m_godlevel;
@@ -3199,7 +3158,8 @@ namespace OpenSim.Region.Framework.Scenes
3199 3158
3200 public void CopyFrom(AgentData cAgent) 3159 public void CopyFrom(AgentData cAgent)
3201 { 3160 {
3202 m_rootRegionHandle= cAgent.RegionHandle; 3161 m_rootRegionHandle = cAgent.RegionHandle;
3162
3203 m_callbackURI = cAgent.CallbackURI; 3163 m_callbackURI = cAgent.CallbackURI;
3204 3164
3205 m_pos = cAgent.Position; 3165 m_pos = cAgent.Position;
@@ -3217,7 +3177,7 @@ namespace OpenSim.Region.Framework.Scenes
3217 3177
3218 m_headrotation = cAgent.HeadRotation; 3178 m_headrotation = cAgent.HeadRotation;
3219 m_bodyRot = cAgent.BodyRotation; 3179 m_bodyRot = cAgent.BodyRotation;
3220 m_AgentControlFlags = cAgent.ControlFlags; 3180 m_AgentControlFlags = (AgentManager.ControlFlags)cAgent.ControlFlags;
3221 3181
3222 if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID))) 3182 if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID)))
3223 m_godlevel = cAgent.GodLevel; 3183 m_godlevel = cAgent.GodLevel;
@@ -3291,47 +3251,18 @@ namespace OpenSim.Region.Framework.Scenes
3291 /// </summary> 3251 /// </summary>
3292 public override void UpdateMovement() 3252 public override void UpdateMovement()
3293 { 3253 {
3294 lock (m_forcesList) 3254 if (m_forceToApply.HasValue)
3295 { 3255 {
3296 if (m_forcesList.Count > 0) 3256 Vector3 force = m_forceToApply.Value;
3297 {
3298 //we are only interested in the last velocity added to the list [Although they are called forces, they are actually velocities]
3299 NewForce force = m_forcesList[m_forcesList.Count - 1];
3300 3257
3301 m_updateflag = true; 3258 m_updateflag = true;
3302 try 3259 movementvector = force;
3303 { 3260 Velocity = force;
3304 movementvector.X = force.X;
3305 movementvector.Y = force.Y;
3306 movementvector.Z = force.Z;
3307 Velocity = movementvector;
3308 }
3309 catch (NullReferenceException)
3310 {
3311 // Under extreme load, this returns a NullReference Exception that we can ignore.
3312 // Ignoring this causes no movement to be sent to the physics engine...
3313 // which when the scene is moving at 1 frame every 10 seconds, it doesn't really matter!
3314 }
3315 3261
3316 m_forcesList.Clear(); 3262 m_forceToApply = null;
3317 }
3318 } 3263 }
3319 } 3264 }
3320 3265
3321 static ScenePresence()
3322 {
3323 Primitive.TextureEntry textu = AvatarAppearance.GetDefaultTexture();
3324 DefaultTexture = textu.GetBytes();
3325
3326 }
3327
3328 public class NewForce
3329 {
3330 public float X;
3331 public float Y;
3332 public float Z;
3333 }
3334
3335 public override void SetText(string text, Vector3 color, double alpha) 3266 public override void SetText(string text, Vector3 color, double alpha)
3336 { 3267 {
3337 throw new Exception("Can't set Text on avatar."); 3268 throw new Exception("Can't set Text on avatar.");
@@ -3342,7 +3273,6 @@ namespace OpenSim.Region.Framework.Scenes
3342 /// </summary> 3273 /// </summary>
3343 public void AddToPhysicalScene(bool isFlying) 3274 public void AddToPhysicalScene(bool isFlying)
3344 { 3275 {
3345
3346 PhysicsScene scene = m_scene.PhysicsScene; 3276 PhysicsScene scene = m_scene.PhysicsScene;
3347 3277
3348 Vector3 pVec = AbsolutePosition; 3278 Vector3 pVec = AbsolutePosition;
@@ -3388,15 +3318,48 @@ namespace OpenSim.Region.Framework.Scenes
3388 // as of this comment the interval is set in AddToPhysicalScene 3318 // as of this comment the interval is set in AddToPhysicalScene
3389 UpdateMovementAnimations(); 3319 UpdateMovementAnimations();
3390 3320
3321 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3322 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3323
3324 CollisionPlane = Vector4.UnitW;
3325
3326 if (coldata.Count != 0)
3327 {
3328 switch (m_movementAnimation)
3329 {
3330 case "STAND":
3331 case "WALK":
3332 case "RUN":
3333 case "CROUCH":
3334 case "CROUCHWALK":
3335 {
3336 ContactPoint lowest;
3337 lowest.SurfaceNormal = Vector3.Zero;
3338 lowest.Position = Vector3.Zero;
3339 lowest.Position.Z = Single.NaN;
3340
3341 foreach (ContactPoint contact in coldata.Values)
3342 {
3343 if (Single.IsNaN(lowest.Position.Z) || contact.Position.Z < lowest.Position.Z)
3344 {
3345 lowest = contact;
3346 }
3347 }
3348
3349 CollisionPlane = new Vector4(-lowest.SurfaceNormal, -Vector3.Dot(lowest.Position, lowest.SurfaceNormal));
3350 }
3351 break;
3352 }
3353 }
3354
3391 if (m_invulnerable) 3355 if (m_invulnerable)
3392 return; 3356 return;
3393 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3357
3394 Dictionary<uint, float> coldata = collisionData.m_objCollisionList;
3395 float starthealth = Health; 3358 float starthealth = Health;
3396 uint killerObj = 0; 3359 uint killerObj = 0;
3397 foreach (uint localid in coldata.Keys) 3360 foreach (uint localid in coldata.Keys)
3398 { 3361 {
3399 if (coldata[localid] <= 0.10f || m_invulnerable) 3362 if (coldata[localid].PenetrationDepth <= 0.10f || m_invulnerable)
3400 continue; 3363 continue;
3401 //if (localid == 0) 3364 //if (localid == 0)
3402 //continue; 3365 //continue;
@@ -3406,9 +3369,9 @@ namespace OpenSim.Region.Framework.Scenes
3406 if (part != null && part.ParentGroup.Damage != -1.0f) 3369 if (part != null && part.ParentGroup.Damage != -1.0f)
3407 Health -= part.ParentGroup.Damage; 3370 Health -= part.ParentGroup.Damage;
3408 else 3371 else
3409 Health -= coldata[localid] * 5; 3372 Health -= coldata[localid].PenetrationDepth * 5.0f;
3410 3373
3411 if (Health <= 0) 3374 if (Health <= 0.0f)
3412 { 3375 {
3413 if (localid != 0) 3376 if (localid != 0)
3414 killerObj = localid; 3377 killerObj = localid;
@@ -3471,11 +3434,6 @@ namespace OpenSim.Region.Framework.Scenes
3471 3434
3472 public ScenePresence() 3435 public ScenePresence()
3473 { 3436 {
3474 if (DefaultTexture == null)
3475 {
3476 Primitive.TextureEntry textu = AvatarAppearance.GetDefaultTexture();
3477 DefaultTexture = textu.GetBytes();
3478 }
3479 m_sendCourseLocationsMethod = SendCoarseLocationsDefault; 3437 m_sendCourseLocationsMethod = SendCoarseLocationsDefault;
3480 CreateSceneViewer(); 3438 CreateSceneViewer();
3481 } 3439 }
@@ -3632,19 +3590,10 @@ namespace OpenSim.Region.Framework.Scenes
3632 IgnoredControls &= ~(ScriptControlled)controls; 3590 IgnoredControls &= ~(ScriptControlled)controls;
3633 if (scriptedcontrols.ContainsKey(Script_item_UUID)) 3591 if (scriptedcontrols.ContainsKey(Script_item_UUID))
3634 scriptedcontrols.Remove(Script_item_UUID); 3592 scriptedcontrols.Remove(Script_item_UUID);
3635
3636 } 3593 }
3637 else 3594 else
3638 { 3595 {
3639 3596 scriptedcontrols[Script_item_UUID] = obj;
3640 if (scriptedcontrols.ContainsKey(Script_item_UUID))
3641 {
3642 scriptedcontrols[Script_item_UUID] = obj;
3643 }
3644 else
3645 {
3646 scriptedcontrols.Add(Script_item_UUID, obj);
3647 }
3648 } 3597 }
3649 } 3598 }
3650 ControllingClient.SendTakeControls(controls, pass_on == 1 ? true : false, true); 3599 ControllingClient.SendTakeControls(controls, pass_on == 1 ? true : false, true);
@@ -3662,12 +3611,14 @@ namespace OpenSim.Region.Framework.Scenes
3662 3611
3663 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID) 3612 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID)
3664 { 3613 {
3614 ScriptControllers takecontrols;
3615
3665 lock (scriptedcontrols) 3616 lock (scriptedcontrols)
3666 { 3617 {
3667 if (scriptedcontrols.ContainsKey(Script_item_UUID)) 3618 if (scriptedcontrols.TryGetValue(Script_item_UUID, out takecontrols))
3668 { 3619 {
3669 ScriptControllers takecontrolls = scriptedcontrols[Script_item_UUID]; 3620 ScriptControlled sctc = takecontrols.eventControls;
3670 ScriptControlled sctc = takecontrolls.eventControls; 3621
3671 ControllingClient.SendTakeControls((int)sctc, false, false); 3622 ControllingClient.SendTakeControls((int)sctc, false, false);
3672 ControllingClient.SendTakeControls((int)sctc, true, false); 3623 ControllingClient.SendTakeControls((int)sctc, true, false);
3673 3624
@@ -3678,7 +3629,6 @@ namespace OpenSim.Region.Framework.Scenes
3678 IgnoredControls |= scData.ignoreControls; 3629 IgnoredControls |= scData.ignoreControls;
3679 } 3630 }
3680 } 3631 }
3681
3682 } 3632 }
3683 } 3633 }
3684 3634
@@ -3745,9 +3695,11 @@ namespace OpenSim.Region.Framework.Scenes
3745 { 3695 {
3746 lock (scriptedcontrols) 3696 lock (scriptedcontrols)
3747 { 3697 {
3748 foreach (UUID scriptUUID in scriptedcontrols.Keys) 3698 foreach (KeyValuePair<UUID, ScriptControllers> kvp in scriptedcontrols)
3749 { 3699 {
3750 ScriptControllers scriptControlData = scriptedcontrols[scriptUUID]; 3700 UUID scriptUUID = kvp.Key;
3701 ScriptControllers scriptControlData = kvp.Value;
3702
3751 ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us 3703 ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us
3752 ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle 3704 ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle
3753 ScriptControlled localChange = localHeld ^ localLast; // the changed bits 3705 ScriptControlled localChange = localHeld ^ localLast; // the changed bits
@@ -3763,37 +3715,40 @@ namespace OpenSim.Region.Framework.Scenes
3763 LastCommands = allflags; 3715 LastCommands = allflags;
3764 } 3716 }
3765 3717
3766 internal static uint RemoveIgnoredControls(uint flags, ScriptControlled Ignored) 3718 internal static AgentManager.ControlFlags RemoveIgnoredControls(AgentManager.ControlFlags flags, ScriptControlled ignored)
3767 { 3719 {
3768 if (Ignored == ScriptControlled.CONTROL_ZERO) 3720 if (ignored == ScriptControlled.CONTROL_ZERO)
3769 return flags; 3721 return flags;
3770 if ((Ignored & ScriptControlled.CONTROL_BACK) != 0) 3722
3771 flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG | (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG); 3723 if ((ignored & ScriptControlled.CONTROL_BACK) != 0)
3772 if ((Ignored & ScriptControlled.CONTROL_FWD) != 0) 3724 flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG);
3773 flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS | (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS); 3725 if ((ignored & ScriptControlled.CONTROL_FWD) != 0)
3774 if ((Ignored & ScriptControlled.CONTROL_DOWN) != 0) 3726 flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS | AgentManager.ControlFlags.AGENT_CONTROL_AT_POS);
3775 flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG | (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG); 3727 if ((ignored & ScriptControlled.CONTROL_DOWN) != 0)
3776 if ((Ignored & ScriptControlled.CONTROL_UP) != 0) 3728 flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG);
3777 flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS | (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS); 3729 if ((ignored & ScriptControlled.CONTROL_UP) != 0)
3778 if ((Ignored & ScriptControlled.CONTROL_LEFT) != 0) 3730 flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS | AgentManager.ControlFlags.AGENT_CONTROL_UP_POS);
3779 flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS); 3731 if ((ignored & ScriptControlled.CONTROL_LEFT) != 0)
3780 if ((Ignored & ScriptControlled.CONTROL_RIGHT) != 0) 3732 flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS);
3781 flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG | (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG); 3733 if ((ignored & ScriptControlled.CONTROL_RIGHT) != 0)
3782 if ((Ignored & ScriptControlled.CONTROL_ROT_LEFT) != 0) 3734 flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG);
3783 flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG); 3735 if ((ignored & ScriptControlled.CONTROL_ROT_LEFT) != 0)
3784 if ((Ignored & ScriptControlled.CONTROL_ROT_RIGHT) != 0) 3736 flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG);
3785 flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS); 3737 if ((ignored & ScriptControlled.CONTROL_ROT_RIGHT) != 0)
3786 if ((Ignored & ScriptControlled.CONTROL_ML_LBUTTON) != 0) 3738 flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS);
3787 flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN); 3739 if ((ignored & ScriptControlled.CONTROL_ML_LBUTTON) != 0)
3788 if ((Ignored & ScriptControlled.CONTROL_LBUTTON) != 0) 3740 flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN);
3789 flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP | (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN); 3741 if ((ignored & ScriptControlled.CONTROL_LBUTTON) != 0)
3790 //DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS, 3742 flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP | AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN);
3791 //DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG, 3743
3792 //DIR_CONTROL_FLAG_LEFT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS, 3744 //DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS,
3793 //DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, 3745 //DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG,
3794 //DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 3746 //DIR_CONTROL_FLAG_LEFT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS,
3795 //DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 3747 //DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG,
3796 //DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 3748 //DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
3749 //DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
3750 //DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
3751
3797 return flags; 3752 return flags;
3798 } 3753 }
3799 3754
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs
index 19c0fea..f495022 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs
@@ -219,7 +219,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
219 Assert.That(presence.IsChildAgent, Is.True, "Did not change to child agent after MakeChildAgent"); 219 Assert.That(presence.IsChildAgent, Is.True, "Did not change to child agent after MakeChildAgent");
220 220
221 // Accepts 0 but rejects Constants.RegionSize 221 // Accepts 0 but rejects Constants.RegionSize
222 Vector3 pos = new Vector3(0,Constants.RegionSize-1,0); 222 Vector3 pos = new Vector3(0,unchecked(Constants.RegionSize-1),0);
223 presence.MakeRootAgent(pos,true); 223 presence.MakeRootAgent(pos,true);
224 Assert.That(presence.IsChildAgent, Is.False, "Did not go back to root agent"); 224 Assert.That(presence.IsChildAgent, Is.False, "Did not go back to root agent");
225 Assert.That(presence.AbsolutePosition, Is.EqualTo(pos), "Position is not the same one entered"); 225 Assert.That(presence.AbsolutePosition, Is.EqualTo(pos), "Position is not the same one entered");
@@ -246,7 +246,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
246 scene2.AddNewClient(testclient); 246 scene2.AddNewClient(testclient);
247 247
248 ScenePresence presence = scene.GetScenePresence(agent1); 248 ScenePresence presence = scene.GetScenePresence(agent1);
249 presence.MakeRootAgent(new Vector3(0,Constants.RegionSize-1,0), true); 249 presence.MakeRootAgent(new Vector3(0,unchecked(Constants.RegionSize-1),0), true);
250 250
251 ScenePresence presence2 = scene2.GetScenePresence(agent1); 251 ScenePresence presence2 = scene2.GetScenePresence(agent1);
252 252
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs
index fbe43d6..2c5093f 100644
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs
@@ -81,12 +81,11 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
81 y.Scale = new Vector3(0.01f,0.01f,0.01f); 81 y.Scale = new Vector3(0.01f,0.01f,0.01f);
82 y.LastOwnerID = UUID.Zero; 82 y.LastOwnerID = UUID.Zero;
83 y.GroupPosition = groupPos; 83 y.GroupPosition = groupPos;
84 y.OffsetPosition = new Vector3(0, 0, 0); 84 y.OffsetPosition = Vector3.Zero;
85 y.RotationOffset = new Quaternion(0,0,0,0); 85 y.RotationOffset = Quaternion.Identity;
86 y.Velocity = new Vector3(0, 0, 0); 86 y.Velocity = Vector3.Zero;
87 y.RotationalVelocity = new Vector3(0, 0, 0); 87 y.AngularVelocity = Vector3.Zero;
88 y.AngularVelocity = new Vector3(0, 0, 0); 88 y.Acceleration = Vector3.Zero;
89 y.Acceleration = new Vector3(0, 0, 0);
90 89
91 y.Flags = 0; 90 y.Flags = 0;
92 y.TrimPermissions(); 91 y.TrimPermissions();
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs
index e185351..a6afa5a 100644
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs
@@ -172,8 +172,6 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
172 result |= Diff.ANGULARVELOCITY; 172 result |= Diff.ANGULARVELOCITY;
173 if (!AreVectorsEquivalent(first.OffsetPosition, second.OffsetPosition)) 173 if (!AreVectorsEquivalent(first.OffsetPosition, second.OffsetPosition))
174 result |= Diff.OFFSETPOSITION; 174 result |= Diff.OFFSETPOSITION;
175 if (!AreVectorsEquivalent(first.RotationalVelocity, second.RotationalVelocity))
176 result |= Diff.ROTATIONALVELOCITY;
177 if (!AreVectorsEquivalent(first.Scale, second.Scale)) 175 if (!AreVectorsEquivalent(first.Scale, second.Scale))
178 result |= Diff.SCALE; 176 result |= Diff.SCALE;
179 if (!AreVectorsEquivalent(first.Velocity, second.Velocity)) 177 if (!AreVectorsEquivalent(first.Velocity, second.Velocity))
diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
index 6bfdff2..f58129d 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
@@ -52,6 +52,20 @@ namespace OpenSim.Region.Physics.Manager
52 , Absolute 52 , Absolute
53 } 53 }
54 54
55 public struct ContactPoint
56 {
57 public Vector3 Position;
58 public Vector3 SurfaceNormal;
59 public float PenetrationDepth;
60
61 public ContactPoint(Vector3 position, Vector3 surfaceNormal, float penetrationDepth)
62 {
63 Position = position;
64 SurfaceNormal = surfaceNormal;
65 PenetrationDepth = penetrationDepth;
66 }
67 }
68
55 public class CollisionEventUpdate : EventArgs 69 public class CollisionEventUpdate : EventArgs
56 { 70 {
57 // Raising the event on the object, so don't need to provide location.. further up the tree knows that info. 71 // Raising the event on the object, so don't need to provide location.. further up the tree knows that info.
@@ -59,9 +73,9 @@ namespace OpenSim.Region.Physics.Manager
59 public int m_colliderType; 73 public int m_colliderType;
60 public int m_GenericStartEnd; 74 public int m_GenericStartEnd;
61 //public uint m_LocalID; 75 //public uint m_LocalID;
62 public Dictionary<uint,float> m_objCollisionList = new Dictionary<uint,float>(); 76 public Dictionary<uint, ContactPoint> m_objCollisionList = new Dictionary<uint, ContactPoint>();
63 77
64 public CollisionEventUpdate(uint localID, int colliderType, int GenericStartEnd, Dictionary<uint, float> objCollisionList) 78 public CollisionEventUpdate(uint localID, int colliderType, int GenericStartEnd, Dictionary<uint, ContactPoint> objCollisionList)
65 { 79 {
66 m_colliderType = colliderType; 80 m_colliderType = colliderType;
67 m_GenericStartEnd = GenericStartEnd; 81 m_GenericStartEnd = GenericStartEnd;
@@ -72,8 +86,7 @@ namespace OpenSim.Region.Physics.Manager
72 { 86 {
73 m_colliderType = (int) ActorTypes.Unknown; 87 m_colliderType = (int) ActorTypes.Unknown;
74 m_GenericStartEnd = 1; 88 m_GenericStartEnd = 1;
75 // m_objCollisionList = null; 89 m_objCollisionList = new Dictionary<uint, ContactPoint>();
76 m_objCollisionList = new Dictionary<uint, float>();
77 } 90 }
78 91
79 public int collidertype 92 public int collidertype
@@ -88,16 +101,16 @@ namespace OpenSim.Region.Physics.Manager
88 set { m_GenericStartEnd = value; } 101 set { m_GenericStartEnd = value; }
89 } 102 }
90 103
91 public void addCollider(uint localID, float depth) 104 public void addCollider(uint localID, ContactPoint contact)
92 { 105 {
93 if (!m_objCollisionList.ContainsKey(localID)) 106 if (!m_objCollisionList.ContainsKey(localID))
94 { 107 {
95 m_objCollisionList.Add(localID, depth); 108 m_objCollisionList.Add(localID, contact);
96 } 109 }
97 else 110 else
98 { 111 {
99 if (m_objCollisionList[localID] < depth) 112 if (m_objCollisionList[localID].PenetrationDepth < contact.PenetrationDepth)
100 m_objCollisionList[localID] = depth; 113 m_objCollisionList[localID] = contact;
101 } 114 }
102 } 115 }
103 } 116 }
diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
index bb0d18e..6d515e9 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
@@ -75,6 +75,11 @@ namespace OpenSim.Region.Physics.Manager
75 public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, 75 public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
76 Vector3 size, Quaternion rotation, bool isPhysical); 76 Vector3 size, Quaternion rotation, bool isPhysical);
77 77
78 public virtual float TimeDilation
79 {
80 get { return 1.0f; }
81 }
82
78 public virtual bool SupportsNINJAJoints 83 public virtual bool SupportsNINJAJoints
79 { 84 {
80 get { return false; } 85 get { return false; }
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index fbe1949..fded95e 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -284,9 +284,13 @@ namespace OpenSim.Region.Physics.Meshing
284 284
285 try 285 try
286 { 286 {
287 idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData); 287 OpenMetaverse.Imaging.ManagedImage unusedData;
288 OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(primShape.SculptData, out unusedData, out idata);
289 unusedData = null;
288 290
289 if (cacheSculptMaps) 291 //idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData);
292
293 if (cacheSculptMaps && idata != null)
290 { 294 {
291 try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); } 295 try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); }
292 catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); } 296 catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); }
@@ -299,12 +303,12 @@ namespace OpenSim.Region.Physics.Meshing
299 } 303 }
300 catch (IndexOutOfRangeException) 304 catch (IndexOutOfRangeException)
301 { 305 {
302 m_log.Error("[PHYSICS]: OpenJpeg was unable to decode this. Physics Proxy generation failed"); 306 m_log.Error("[PHYSICS]: OpenJpeg was unable to decode this. Physics Proxy generation failed");
303 return null; 307 return null;
304 } 308 }
305 catch (Exception) 309 catch (Exception ex)
306 { 310 {
307 m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed!"); 311 m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " + ex.Message);
308 return null; 312 return null;
309 } 313 }
310 } 314 }
diff --git a/OpenSim/Region/Physics/Meshing/PrimMesher.cs b/OpenSim/Region/Physics/Meshing/PrimMesher.cs
index 47ce615..c7c9160 100644
--- a/OpenSim/Region/Physics/Meshing/PrimMesher.cs
+++ b/OpenSim/Region/Physics/Meshing/PrimMesher.cs
@@ -67,11 +67,6 @@ namespace PrimMesher
67 Normalize(); 67 Normalize();
68 } 68 }
69 69
70 public Quat Identity()
71 {
72 return new Quat(0.0f, 0.0f, 0.0f, 1.0f);
73 }
74
75 public float Length() 70 public float Length()
76 { 71 {
77 return (float)Math.Sqrt(X * X + Y * Y + Z * Z + W * W); 72 return (float)Math.Sqrt(X * X + Y * Y + Z * Z + W * W);
@@ -660,7 +655,7 @@ namespace PrimMesher
660 this.faceNumbers = new List<int>(); 655 this.faceNumbers = new List<int>();
661 656
662 Coord center = new Coord(0.0f, 0.0f, 0.0f); 657 Coord center = new Coord(0.0f, 0.0f, 0.0f);
663 bool hasCenter = false; 658 //bool hasCenter = false;
664 659
665 List<Coord> hollowCoords = new List<Coord>(); 660 List<Coord> hollowCoords = new List<Coord>();
666 List<Coord> hollowNormals = new List<Coord>(); 661 List<Coord> hollowNormals = new List<Coord>();
@@ -727,7 +722,7 @@ namespace PrimMesher
727 else if (!simpleFace) 722 else if (!simpleFace)
728 { 723 {
729 this.coords.Add(center); 724 this.coords.Add(center);
730 hasCenter = true; 725 //hasCenter = true;
731 if (this.calcVertexNormals) 726 if (this.calcVertexNormals)
732 this.vertexNormals.Add(new Coord(0.0f, 0.0f, 1.0f)); 727 this.vertexNormals.Add(new Coord(0.0f, 0.0f, 1.0f));
733 this.us.Add(0.0f); 728 this.us.Add(0.0f);
@@ -1541,7 +1536,7 @@ namespace PrimMesher
1541 } 1536 }
1542 1537
1543 /// <summary> 1538 /// <summary>
1544 /// Extrudes a profile along a straight line path. Used for prim types box, cylinder, and prism. 1539 /// Extrudes a profile along a path.
1545 /// </summary> 1540 /// </summary>
1546 public void Extrude(PathType pathType) 1541 public void Extrude(PathType pathType)
1547 { 1542 {
@@ -1557,7 +1552,6 @@ namespace PrimMesher
1557 if (this.calcVertexNormals) 1552 if (this.calcVertexNormals)
1558 this.normals = new List<Coord>(); 1553 this.normals = new List<Coord>();
1559 1554
1560 //int step = 0;
1561 int steps = 1; 1555 int steps = 1;
1562 1556
1563 float length = this.pathCutEnd - this.pathCutBegin; 1557 float length = this.pathCutEnd - this.pathCutBegin;
@@ -1579,20 +1573,6 @@ namespace PrimMesher
1579 if (twistTotalAbs > 0.01f) 1573 if (twistTotalAbs > 0.01f)
1580 steps += (int)(twistTotalAbs * 3.66); // dahlia's magic number 1574 steps += (int)(twistTotalAbs * 3.66); // dahlia's magic number
1581 1575
1582 //float start = -0.5f;
1583 //float stepSize = length / (float)steps;
1584 //float percentOfPathMultiplier = stepSize;
1585 //float xProfileScale = 1.0f;
1586 //float yProfileScale = 1.0f;
1587 //float xOffset = 0.0f;
1588 //float yOffset = 0.0f;
1589 //float zOffset = start;
1590 //float xOffsetStepIncrement = this.topShearX / steps;
1591 //float yOffsetStepIncrement = this.topShearY / steps;
1592
1593 //float percentOfPath = this.pathCutBegin;
1594 //zOffset += percentOfPath;
1595
1596 float hollow = this.hollow; 1576 float hollow = this.hollow;
1597 1577
1598 // sanity checks 1578 // sanity checks
@@ -1662,7 +1642,6 @@ namespace PrimMesher
1662 cut2Vert = hasHollow ? profile.numOuterVerts - 1 : profile.numOuterVerts; 1642 cut2Vert = hasHollow ? profile.numOuterVerts - 1 : profile.numOuterVerts;
1663 } 1643 }
1664 1644
1665
1666 if (initialProfileRot != 0.0f) 1645 if (initialProfileRot != 0.0f)
1667 { 1646 {
1668 profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot)); 1647 profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot));
@@ -1693,24 +1672,6 @@ namespace PrimMesher
1693 path.stepsPerRevolution = stepsPerRevolution; 1672 path.stepsPerRevolution = stepsPerRevolution;
1694 1673
1695 path.Create(pathType, steps); 1674 path.Create(pathType, steps);
1696 /*
1697 public int twistBegin = 0;
1698 public int twistEnd = 0;
1699 public float topShearX = 0.0f;
1700 public float topShearY = 0.0f;
1701 public float pathCutBegin = 0.0f;
1702 public float pathCutEnd = 1.0f;
1703 public float dimpleBegin = 0.0f;
1704 public float dimpleEnd = 1.0f;
1705 public float skew = 0.0f;
1706 public float holeSizeX = 1.0f; // called pathScaleX in pbs
1707 public float holeSizeY = 0.25f;
1708 public float taperX = 0.0f;
1709 public float taperY = 0.0f;
1710 public float radius = 0.0f;
1711 public float revolutions = 1.0f;
1712 public int stepsPerRevolution = 24;
1713 */
1714 1675
1715 bool needEndFaces = false; 1676 bool needEndFaces = false;
1716 if (pathType == PathType.Circular) 1677 if (pathType == PathType.Circular)
@@ -1796,7 +1757,6 @@ namespace PrimMesher
1796 int numVerts = newLayer.coords.Count; 1757 int numVerts = newLayer.coords.Count;
1797 Face newFace = new Face(); 1758 Face newFace = new Face();
1798 1759
1799 //if (step > 0)
1800 if (nodeIndex > 0) 1760 if (nodeIndex > 0)
1801 { 1761 {
1802 int startVert = coordsLen + 1; 1762 int startVert = coordsLen + 1;
@@ -1812,7 +1772,6 @@ namespace PrimMesher
1812 iNext = startVert; 1772 iNext = startVert;
1813 1773
1814 int whichVert = i - startVert; 1774 int whichVert = i - startVert;
1815 //int whichVert2 = i - lastCoordsLen;
1816 1775
1817 newFace.v1 = i; 1776 newFace.v1 = i;
1818 newFace.v2 = i - numVerts; 1777 newFace.v2 = i - numVerts;
@@ -1982,809 +1941,27 @@ namespace PrimMesher
1982 1941
1983 1942
1984 /// <summary> 1943 /// <summary>
1944 /// DEPRICATED - use Extrude(PathType.Linear) instead
1985 /// Extrudes a profile along a straight line path. Used for prim types box, cylinder, and prism. 1945 /// Extrudes a profile along a straight line path. Used for prim types box, cylinder, and prism.
1986 /// </summary> 1946 /// </summary>
1947 ///
1987 public void ExtrudeLinear() 1948 public void ExtrudeLinear()
1988 { 1949 {
1989 this.coords = new List<Coord>(); 1950 this.Extrude(PathType.Linear);
1990 this.faces = new List<Face>();
1991
1992 if (this.viewerMode)
1993 {
1994 this.viewerFaces = new List<ViewerFace>();
1995 this.calcVertexNormals = true;
1996 }
1997
1998 if (this.calcVertexNormals)
1999 this.normals = new List<Coord>();
2000
2001 int step = 0;
2002 int steps = 1;
2003
2004 float length = this.pathCutEnd - this.pathCutBegin;
2005 normalsProcessed = false;
2006
2007 if (this.viewerMode && this.sides == 3)
2008 {
2009 // prisms don't taper well so add some vertical resolution
2010 // other prims may benefit from this but just do prisms for now
2011 if (Math.Abs(this.taperX) > 0.01 || Math.Abs(this.taperY) > 0.01)
2012 steps = (int)(steps * 4.5 * length);
2013 }
2014
2015
2016 float twistBegin = this.twistBegin / 360.0f * twoPi;
2017 float twistEnd = this.twistEnd / 360.0f * twoPi;
2018 float twistTotal = twistEnd - twistBegin;
2019 float twistTotalAbs = Math.Abs(twistTotal);
2020 if (twistTotalAbs > 0.01f)
2021 steps += (int)(twistTotalAbs * 3.66); // dahlia's magic number
2022
2023 float start = -0.5f;
2024 float stepSize = length / (float)steps;
2025 float percentOfPathMultiplier = stepSize;
2026 float xProfileScale = 1.0f;
2027 float yProfileScale = 1.0f;
2028 float xOffset = 0.0f;
2029 float yOffset = 0.0f;
2030 float zOffset = start;
2031 float xOffsetStepIncrement = this.topShearX / steps;
2032 float yOffsetStepIncrement = this.topShearY / steps;
2033
2034 float percentOfPath = this.pathCutBegin;
2035 zOffset += percentOfPath;
2036
2037 float hollow = this.hollow;
2038
2039 // sanity checks
2040 float initialProfileRot = 0.0f;
2041 if (this.sides == 3)
2042 {
2043 if (this.hollowSides == 4)
2044 {
2045 if (hollow > 0.7f)
2046 hollow = 0.7f;
2047 hollow *= 0.707f;
2048 }
2049 else hollow *= 0.5f;
2050 }
2051 else if (this.sides == 4)
2052 {
2053 initialProfileRot = 1.25f * (float)Math.PI;
2054 if (this.hollowSides != 4)
2055 hollow *= 0.707f;
2056 }
2057 else if (this.sides == 24 && this.hollowSides == 4)
2058 hollow *= 1.414f;
2059
2060 Profile profile = new Profile(this.sides, this.profileStart, this.profileEnd, hollow, this.hollowSides, true, calcVertexNormals);
2061 this.errorMessage = profile.errorMessage;
2062
2063 this.numPrimFaces = profile.numPrimFaces;
2064
2065 int cut1Vert = -1;
2066 int cut2Vert = -1;
2067 if (hasProfileCut)
2068 {
2069 cut1Vert = hasHollow ? profile.coords.Count - 1 : 0;
2070 cut2Vert = hasHollow ? profile.numOuterVerts - 1 : profile.numOuterVerts;
2071 }
2072
2073 if (initialProfileRot != 0.0f)
2074 {
2075 profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot));
2076 if (viewerMode)
2077 profile.MakeFaceUVs();
2078 }
2079
2080 Coord lastCutNormal1 = new Coord();
2081 Coord lastCutNormal2 = new Coord();
2082 float lastV = 1.0f;
2083
2084 bool done = false;
2085 while (!done)
2086 {
2087 Profile newLayer = profile.Copy();
2088
2089 if (this.taperX == 0.0f)
2090 xProfileScale = 1.0f;
2091 else if (this.taperX > 0.0f)
2092 xProfileScale = 1.0f - percentOfPath * this.taperX;
2093 else xProfileScale = 1.0f + (1.0f - percentOfPath) * this.taperX;
2094
2095 if (this.taperY == 0.0f)
2096 yProfileScale = 1.0f;
2097 else if (this.taperY > 0.0f)
2098 yProfileScale = 1.0f - percentOfPath * this.taperY;
2099 else yProfileScale = 1.0f + (1.0f - percentOfPath) * this.taperY;
2100
2101 if (xProfileScale != 1.0f || yProfileScale != 1.0f)
2102 newLayer.Scale(xProfileScale, yProfileScale);
2103
2104 float twist = twistBegin + twistTotal * percentOfPath;
2105 if (twist != 0.0f)
2106 newLayer.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), twist));
2107
2108 newLayer.AddPos(xOffset, yOffset, zOffset);
2109
2110 if (step == 0)
2111 {
2112 newLayer.FlipNormals();
2113
2114 // add the top faces to the viewerFaces list here
2115 if (this.viewerMode)
2116 {
2117 Coord faceNormal = newLayer.faceNormal;
2118 ViewerFace newViewerFace = new ViewerFace(profile.bottomFaceNumber);
2119 int numFaces = newLayer.faces.Count;
2120 List<Face> faces = newLayer.faces;
2121
2122 for (int i = 0; i < numFaces; i++)
2123 {
2124 Face face = faces[i];
2125 newViewerFace.v1 = newLayer.coords[face.v1];
2126 newViewerFace.v2 = newLayer.coords[face.v2];
2127 newViewerFace.v3 = newLayer.coords[face.v3];
2128
2129 newViewerFace.coordIndex1 = face.v1;
2130 newViewerFace.coordIndex2 = face.v2;
2131 newViewerFace.coordIndex3 = face.v3;
2132
2133 newViewerFace.n1 = faceNormal;
2134 newViewerFace.n2 = faceNormal;
2135 newViewerFace.n3 = faceNormal;
2136
2137 newViewerFace.uv1 = newLayer.faceUVs[face.v1];
2138 newViewerFace.uv2 = newLayer.faceUVs[face.v2];
2139 newViewerFace.uv3 = newLayer.faceUVs[face.v3];
2140
2141 this.viewerFaces.Add(newViewerFace);
2142 }
2143 }
2144 }
2145
2146 // append this layer
2147
2148 int coordsLen = this.coords.Count;
2149 int lastCoordsLen = coordsLen;
2150 newLayer.AddValue2FaceVertexIndices(coordsLen);
2151
2152 this.coords.AddRange(newLayer.coords);
2153
2154 if (this.calcVertexNormals)
2155 {
2156 newLayer.AddValue2FaceNormalIndices(this.normals.Count);
2157 this.normals.AddRange(newLayer.vertexNormals);
2158 }
2159
2160 if (percentOfPath < this.pathCutBegin + 0.01f || percentOfPath > this.pathCutEnd - 0.01f)
2161 this.faces.AddRange(newLayer.faces);
2162
2163 // fill faces between layers
2164
2165 int numVerts = newLayer.coords.Count;
2166 Face newFace = new Face();
2167
2168 if (step > 0)
2169 {
2170 int startVert = coordsLen + 1;
2171 int endVert = this.coords.Count;
2172
2173 if (sides < 5 || this.hasProfileCut || hollow > 0.0f)
2174 startVert--;
2175
2176 for (int i = startVert; i < endVert; i++)
2177 {
2178 int iNext = i + 1;
2179 if (i == endVert - 1)
2180 iNext = startVert;
2181
2182 int whichVert = i - startVert;
2183 //int whichVert2 = i - lastCoordsLen;
2184
2185 newFace.v1 = i;
2186 newFace.v2 = i - numVerts;
2187 newFace.v3 = iNext - numVerts;
2188 this.faces.Add(newFace);
2189
2190 newFace.v2 = iNext - numVerts;
2191 newFace.v3 = iNext;
2192 this.faces.Add(newFace);
2193
2194 if (this.viewerMode)
2195 {
2196 // add the side faces to the list of viewerFaces here
2197 //int primFaceNum = 1;
2198 //if (whichVert >= sides)
2199 // primFaceNum = 2;
2200 int primFaceNum = profile.faceNumbers[whichVert];
2201
2202 ViewerFace newViewerFace1 = new ViewerFace(primFaceNum);
2203 ViewerFace newViewerFace2 = new ViewerFace(primFaceNum);
2204
2205 float u1 = newLayer.us[whichVert];
2206 float u2 = 1.0f;
2207 if (whichVert < newLayer.us.Count - 1)
2208 u2 = newLayer.us[whichVert + 1];
2209
2210 if (whichVert == cut1Vert || whichVert == cut2Vert)
2211 {
2212 u1 = 0.0f;
2213 u2 = 1.0f;
2214 }
2215 else if (sides < 5)
2216 { // boxes and prisms have one texture face per side of the prim, so the U values have to be scaled
2217 // to reflect the entire texture width
2218 u1 *= sides;
2219 u2 *= sides;
2220 u2 -= (int)u1;
2221 u1 -= (int)u1;
2222 if (u2 < 0.1f)
2223 u2 = 1.0f;
2224
2225 //newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = whichVert + 1;
2226 }
2227
2228 newViewerFace1.uv1.U = u1;
2229 newViewerFace1.uv2.U = u1;
2230 newViewerFace1.uv3.U = u2;
2231
2232 newViewerFace1.uv1.V = 1.0f - percentOfPath;
2233 newViewerFace1.uv2.V = lastV;
2234 newViewerFace1.uv3.V = lastV;
2235
2236 newViewerFace2.uv1.U = u1;
2237 newViewerFace2.uv2.U = u2;
2238 newViewerFace2.uv3.U = u2;
2239
2240 newViewerFace2.uv1.V = 1.0f - percentOfPath;
2241 newViewerFace2.uv2.V = lastV;
2242 newViewerFace2.uv3.V = 1.0f - percentOfPath;
2243
2244 newViewerFace1.v1 = this.coords[i];
2245 newViewerFace1.v2 = this.coords[i - numVerts];
2246 newViewerFace1.v3 = this.coords[iNext - numVerts];
2247
2248 newViewerFace2.v1 = this.coords[i];
2249 newViewerFace2.v2 = this.coords[iNext - numVerts];
2250 newViewerFace2.v3 = this.coords[iNext];
2251
2252 newViewerFace1.coordIndex1 = i;
2253 newViewerFace1.coordIndex2 = i - numVerts;
2254 newViewerFace1.coordIndex3 = iNext - numVerts;
2255
2256 newViewerFace2.coordIndex1 = i;
2257 newViewerFace2.coordIndex2 = iNext - numVerts;
2258 newViewerFace2.coordIndex3 = iNext;
2259
2260 // profile cut faces
2261 if (whichVert == cut1Vert)
2262 {
2263 newViewerFace1.n1 = newLayer.cutNormal1;
2264 newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal1;
2265
2266 newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal1;
2267 newViewerFace2.n2 = lastCutNormal1;
2268 }
2269 else if (whichVert == cut2Vert)
2270 {
2271 newViewerFace1.n1 = newLayer.cutNormal2;
2272 newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal2;
2273
2274 newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal2;
2275 newViewerFace2.n2 = lastCutNormal2;
2276 }
2277
2278 else // outer and hollow faces
2279 {
2280 if ((sides < 5 && whichVert < newLayer.numOuterVerts) || (hollowSides < 5 && whichVert >= newLayer.numOuterVerts))
2281 {
2282 newViewerFace1.CalcSurfaceNormal();
2283 newViewerFace2.CalcSurfaceNormal();
2284 }
2285 else
2286 {
2287 newViewerFace1.n1 = this.normals[i];
2288 newViewerFace1.n2 = this.normals[i - numVerts];
2289 newViewerFace1.n3 = this.normals[iNext - numVerts];
2290
2291 newViewerFace2.n1 = this.normals[i];
2292 newViewerFace2.n2 = this.normals[iNext - numVerts];
2293 newViewerFace2.n3 = this.normals[iNext];
2294 }
2295 }
2296
2297 //newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = newLayer.faceNumbers[whichVert];
2298
2299 this.viewerFaces.Add(newViewerFace1);
2300 this.viewerFaces.Add(newViewerFace2);
2301
2302 }
2303 }
2304 }
2305
2306 lastCutNormal1 = newLayer.cutNormal1;
2307 lastCutNormal2 = newLayer.cutNormal2;
2308 lastV = 1.0f - percentOfPath;
2309
2310 // calc the step for the next iteration of the loop
2311
2312 if (step < steps)
2313 {
2314 step += 1;
2315 percentOfPath += percentOfPathMultiplier;
2316 xOffset += xOffsetStepIncrement;
2317 yOffset += yOffsetStepIncrement;
2318 zOffset += stepSize;
2319 if (percentOfPath > this.pathCutEnd)
2320 done = true;
2321 }
2322 else done = true;
2323
2324 if (done && viewerMode)
2325 {
2326 // add the top faces to the viewerFaces list here
2327 Coord faceNormal = newLayer.faceNormal;
2328 ViewerFace newViewerFace = new ViewerFace();
2329 newViewerFace.primFaceNumber = 0;
2330 int numFaces = newLayer.faces.Count;
2331 List<Face> faces = newLayer.faces;
2332
2333 for (int i = 0; i < numFaces; i++)
2334 {
2335 Face face = faces[i];
2336 newViewerFace.v1 = newLayer.coords[face.v1 - coordsLen];
2337 newViewerFace.v2 = newLayer.coords[face.v2 - coordsLen];
2338 newViewerFace.v3 = newLayer.coords[face.v3 - coordsLen];
2339
2340 newViewerFace.coordIndex1 = face.v1 - coordsLen;
2341 newViewerFace.coordIndex2 = face.v2 - coordsLen;
2342 newViewerFace.coordIndex3 = face.v3 - coordsLen;
2343
2344 newViewerFace.n1 = faceNormal;
2345 newViewerFace.n2 = faceNormal;
2346 newViewerFace.n3 = faceNormal;
2347
2348 newViewerFace.uv1 = newLayer.faceUVs[face.v1 - coordsLen];
2349 newViewerFace.uv2 = newLayer.faceUVs[face.v2 - coordsLen];
2350 newViewerFace.uv3 = newLayer.faceUVs[face.v3 - coordsLen];
2351
2352 this.viewerFaces.Add(newViewerFace);
2353 }
2354 }
2355 }
2356 } 1951 }
2357 1952
2358 1953
2359 /// <summary> 1954 /// <summary>
1955 /// DEPRICATED - use Extrude(PathType.Circular) instead
2360 /// Extrude a profile into a circular path prim mesh. Used for prim types torus, tube, and ring. 1956 /// Extrude a profile into a circular path prim mesh. Used for prim types torus, tube, and ring.
2361 /// </summary> 1957 /// </summary>
1958 ///
2362 public void ExtrudeCircular() 1959 public void ExtrudeCircular()
2363 { 1960 {
2364 this.coords = new List<Coord>(); 1961 this.Extrude(PathType.Circular);
2365 this.faces = new List<Face>();
2366
2367 if (this.viewerMode)
2368 {
2369 this.viewerFaces = new List<ViewerFace>();
2370 this.calcVertexNormals = true;
2371 }
2372
2373 if (this.calcVertexNormals)
2374 this.normals = new List<Coord>();
2375
2376 int step = 0;
2377 int steps = 24;
2378
2379 normalsProcessed = false;
2380
2381 float twistBegin = this.twistBegin / 360.0f * twoPi;
2382 float twistEnd = this.twistEnd / 360.0f * twoPi;
2383 float twistTotal = twistEnd - twistBegin;
2384
2385 // if the profile has a lot of twist, add more layers otherwise the layers may overlap
2386 // and the resulting mesh may be quite inaccurate. This method is arbitrary and doesn't
2387 // accurately match the viewer
2388 float twistTotalAbs = Math.Abs(twistTotal);
2389 if (twistTotalAbs > 0.01f)
2390 {
2391 if (twistTotalAbs > Math.PI * 1.5f)
2392 steps *= 2;
2393 if (twistTotalAbs > Math.PI * 3.0f)
2394 steps *= 2;
2395 }
2396
2397 float yPathScale = this.holeSizeY * 0.5f;
2398 float pathLength = this.pathCutEnd - this.pathCutBegin;
2399 float totalSkew = this.skew * 2.0f * pathLength;
2400 float skewStart = this.pathCutBegin * 2.0f * this.skew - this.skew;
2401 float xOffsetTopShearXFactor = this.topShearX * (0.25f + 0.5f * (0.5f - this.holeSizeY));
2402 float yShearCompensation = 1.0f + Math.Abs(this.topShearY) * 0.25f;
2403
2404 // It's not quite clear what pushY (Y top shear) does, but subtracting it from the start and end
2405 // angles appears to approximate it's effects on path cut. Likewise, adding it to the angle used
2406 // to calculate the sine for generating the path radius appears to approximate it's effects there
2407 // too, but there are some subtle differences in the radius which are noticeable as the prim size
2408 // increases and it may affect megaprims quite a bit. The effect of the Y top shear parameter on
2409 // the meshes generated with this technique appear nearly identical in shape to the same prims when
2410 // displayed by the viewer.
2411
2412 float startAngle = (twoPi * this.pathCutBegin * this.revolutions) - this.topShearY * 0.9f;
2413 float endAngle = (twoPi * this.pathCutEnd * this.revolutions) - this.topShearY * 0.9f;
2414 float stepSize = twoPi / this.stepsPerRevolution;
2415
2416 step = (int)(startAngle / stepSize);
2417 int firstStep = step;
2418 float angle = startAngle;
2419 float hollow = this.hollow;
2420
2421 // sanity checks
2422 float initialProfileRot = 0.0f;
2423 if (this.sides == 3)
2424 {
2425 initialProfileRot = (float)Math.PI;
2426 if (this.hollowSides == 4)
2427 {
2428 if (hollow > 0.7f)
2429 hollow = 0.7f;
2430 hollow *= 0.707f;
2431 }
2432 else hollow *= 0.5f;
2433 }
2434 else if (this.sides == 4)
2435 {
2436 initialProfileRot = 0.25f * (float)Math.PI;
2437 if (this.hollowSides != 4)
2438 hollow *= 0.707f;
2439 }
2440 else if (this.sides > 4)
2441 {
2442 initialProfileRot = (float)Math.PI;
2443 if (this.hollowSides == 4)
2444 {
2445 if (hollow > 0.7f)
2446 hollow = 0.7f;
2447 hollow /= 0.7f;
2448 }
2449 }
2450
2451 bool needEndFaces = false;
2452 if (this.pathCutBegin != 0.0f || this.pathCutEnd != 1.0f)
2453 needEndFaces = true;
2454 else if (this.taperX != 0.0f || this.taperY != 0.0f)
2455 needEndFaces = true;
2456 else if (this.skew != 0.0f)
2457 needEndFaces = true;
2458 else if (twistTotal != 0.0f)
2459 needEndFaces = true;
2460 else if (this.radius != 0.0f)
2461 needEndFaces = true;
2462
2463 Profile profile = new Profile(this.sides, this.profileStart, this.profileEnd, hollow, this.hollowSides, needEndFaces, calcVertexNormals);
2464 this.errorMessage = profile.errorMessage;
2465
2466 this.numPrimFaces = profile.numPrimFaces;
2467
2468 int cut1Vert = -1;
2469 int cut2Vert = -1;
2470 if (hasProfileCut)
2471 {
2472 cut1Vert = hasHollow ? profile.coords.Count - 1 : 0;
2473 cut2Vert = hasHollow ? profile.numOuterVerts - 1 : profile.numOuterVerts;
2474 }
2475
2476 if (initialProfileRot != 0.0f)
2477 {
2478 profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot));
2479 if (viewerMode)
2480 profile.MakeFaceUVs();
2481 }
2482
2483 Coord lastCutNormal1 = new Coord();
2484 Coord lastCutNormal2 = new Coord();
2485 float lastV = 1.0f;
2486
2487 bool done = false;
2488 while (!done) // loop through the length of the path and add the layers
2489 {
2490 bool isEndLayer = false;
2491 if (angle <= startAngle + .01f || angle >= endAngle - .01f)
2492 isEndLayer = true;
2493
2494 Profile newLayer = profile.Copy();
2495
2496 float xProfileScale = (1.0f - Math.Abs(this.skew)) * this.holeSizeX;
2497 float yProfileScale = this.holeSizeY;
2498
2499 float percentOfPath = angle / (twoPi * this.revolutions);
2500 float percentOfAngles = (angle - startAngle) / (endAngle - startAngle);
2501
2502 if (this.taperX > 0.01f)
2503 xProfileScale *= 1.0f - percentOfPath * this.taperX;
2504 else if (this.taperX < -0.01f)
2505 xProfileScale *= 1.0f + (1.0f - percentOfPath) * this.taperX;
2506
2507 if (this.taperY > 0.01f)
2508 yProfileScale *= 1.0f - percentOfPath * this.taperY;
2509 else if (this.taperY < -0.01f)
2510 yProfileScale *= 1.0f + (1.0f - percentOfPath) * this.taperY;
2511
2512 if (xProfileScale != 1.0f || yProfileScale != 1.0f)
2513 newLayer.Scale(xProfileScale, yProfileScale);
2514
2515 float radiusScale = 1.0f;
2516 if (this.radius > 0.001f)
2517 radiusScale = 1.0f - this.radius * percentOfPath;
2518 else if (this.radius < 0.001f)
2519 radiusScale = 1.0f + this.radius * (1.0f - percentOfPath);
2520
2521 float twist = twistBegin + twistTotal * percentOfPath;
2522
2523 float xOffset = 0.5f * (skewStart + totalSkew * percentOfAngles);
2524 xOffset += (float)Math.Sin(angle) * xOffsetTopShearXFactor;
2525
2526 float yOffset = yShearCompensation * (float)Math.Cos(angle) * (0.5f - yPathScale) * radiusScale;
2527
2528 float zOffset = (float)Math.Sin(angle + this.topShearY) * (0.5f - yPathScale) * radiusScale;
2529
2530 // next apply twist rotation to the profile layer
2531 if (twistTotal != 0.0f || twistBegin != 0.0f)
2532 newLayer.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), twist));
2533
2534 // now orient the rotation of the profile layer relative to it's position on the path
2535 // adding taperY to the angle used to generate the quat appears to approximate the viewer
2536 newLayer.AddRot(new Quat(new Coord(1.0f, 0.0f, 0.0f), angle + this.topShearY));
2537 newLayer.AddPos(xOffset, yOffset, zOffset);
2538
2539 if (isEndLayer && angle <= startAngle + .01f)
2540 {
2541 newLayer.FlipNormals();
2542
2543 // add the top faces to the viewerFaces list here
2544 if (this.viewerMode && needEndFaces)
2545 {
2546 Coord faceNormal = newLayer.faceNormal;
2547 ViewerFace newViewerFace = new ViewerFace();
2548 newViewerFace.primFaceNumber = 0;
2549 foreach (Face face in newLayer.faces)
2550 {
2551 newViewerFace.v1 = newLayer.coords[face.v1];
2552 newViewerFace.v2 = newLayer.coords[face.v2];
2553 newViewerFace.v3 = newLayer.coords[face.v3];
2554
2555 newViewerFace.coordIndex1 = face.v1;
2556 newViewerFace.coordIndex2 = face.v2;
2557 newViewerFace.coordIndex3 = face.v3;
2558
2559 newViewerFace.n1 = faceNormal;
2560 newViewerFace.n2 = faceNormal;
2561 newViewerFace.n3 = faceNormal;
2562
2563 newViewerFace.uv1 = newLayer.faceUVs[face.v1];
2564 newViewerFace.uv2 = newLayer.faceUVs[face.v2];
2565 newViewerFace.uv3 = newLayer.faceUVs[face.v3];
2566
2567 this.viewerFaces.Add(newViewerFace);
2568 }
2569 }
2570 }
2571
2572 // append the layer and fill in the sides
2573
2574 int coordsLen = this.coords.Count;
2575 newLayer.AddValue2FaceVertexIndices(coordsLen);
2576
2577 this.coords.AddRange(newLayer.coords);
2578
2579 if (this.calcVertexNormals)
2580 {
2581 newLayer.AddValue2FaceNormalIndices(this.normals.Count);
2582 this.normals.AddRange(newLayer.vertexNormals);
2583 }
2584
2585 if (isEndLayer)
2586 this.faces.AddRange(newLayer.faces);
2587
2588 // fill faces between layers
2589
2590 int numVerts = newLayer.coords.Count;
2591 Face newFace = new Face();
2592 if (step > firstStep)
2593 {
2594 int startVert = coordsLen + 1;
2595 int endVert = this.coords.Count;
2596
2597 if (sides < 5 || this.hasProfileCut || hollow > 0.0f)
2598 startVert--;
2599
2600 for (int i = startVert; i < endVert; i++)
2601 {
2602 int iNext = i + 1;
2603 if (i == endVert - 1)
2604 iNext = startVert;
2605
2606 int whichVert = i - startVert;
2607
2608 newFace.v1 = i;
2609 newFace.v2 = i - numVerts;
2610 newFace.v3 = iNext - numVerts;
2611 this.faces.Add(newFace);
2612
2613 newFace.v2 = iNext - numVerts;
2614 newFace.v3 = iNext;
2615 this.faces.Add(newFace);
2616
2617 if (this.viewerMode)
2618 {
2619 int primFaceNumber = profile.faceNumbers[whichVert];
2620 if (!needEndFaces)
2621 primFaceNumber -= 1;
2622
2623 // add the side faces to the list of viewerFaces here
2624 ViewerFace newViewerFace1 = new ViewerFace(primFaceNumber);
2625 ViewerFace newViewerFace2 = new ViewerFace(primFaceNumber);
2626 float u1 = newLayer.us[whichVert];
2627 float u2 = 1.0f;
2628 if (whichVert < newLayer.us.Count - 1)
2629 u2 = newLayer.us[whichVert + 1];
2630
2631 if (whichVert == cut1Vert || whichVert == cut2Vert)
2632 {
2633 u1 = 0.0f;
2634 u2 = 1.0f;
2635 }
2636 else if (sides < 5)
2637 { // boxes and prisms have one texture face per side of the prim, so the U values have to be scaled
2638 // to reflect the entire texture width
2639 u1 *= sides;
2640 u2 *= sides;
2641 u2 -= (int)u1;
2642 u1 -= (int)u1;
2643 if (u2 < 0.1f)
2644 u2 = 1.0f;
2645
2646 //newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = whichVert + 1;
2647 }
2648
2649 newViewerFace1.uv1.U = u1;
2650 newViewerFace1.uv2.U = u1;
2651 newViewerFace1.uv3.U = u2;
2652
2653 newViewerFace1.uv1.V = 1.0f - percentOfPath;
2654 newViewerFace1.uv2.V = lastV;
2655 newViewerFace1.uv3.V = lastV;
2656
2657 newViewerFace2.uv1.U = u1;
2658 newViewerFace2.uv2.U = u2;
2659 newViewerFace2.uv3.U = u2;
2660
2661 newViewerFace2.uv1.V = 1.0f - percentOfPath;
2662 newViewerFace2.uv2.V = lastV;
2663 newViewerFace2.uv3.V = 1.0f - percentOfPath;
2664
2665 newViewerFace1.v1 = this.coords[i];
2666 newViewerFace1.v2 = this.coords[i - numVerts];
2667 newViewerFace1.v3 = this.coords[iNext - numVerts];
2668
2669 newViewerFace2.v1 = this.coords[i];
2670 newViewerFace2.v2 = this.coords[iNext - numVerts];
2671 newViewerFace2.v3 = this.coords[iNext];
2672
2673 newViewerFace1.coordIndex1 = i;
2674 newViewerFace1.coordIndex2 = i - numVerts;
2675 newViewerFace1.coordIndex3 = iNext - numVerts;
2676
2677 newViewerFace2.coordIndex1 = i;
2678 newViewerFace2.coordIndex2 = iNext - numVerts;
2679 newViewerFace2.coordIndex3 = iNext;
2680
2681 // profile cut faces
2682 if (whichVert == cut1Vert)
2683 {
2684 newViewerFace1.n1 = newLayer.cutNormal1;
2685 newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal1;
2686
2687 newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal1;
2688 newViewerFace2.n2 = lastCutNormal1;
2689 }
2690 else if (whichVert == cut2Vert)
2691 {
2692 newViewerFace1.n1 = newLayer.cutNormal2;
2693 newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal2;
2694
2695 newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal2;
2696 newViewerFace2.n2 = lastCutNormal2;
2697 }
2698 else // periphery faces
2699 {
2700 if (sides < 5 && whichVert < newLayer.numOuterVerts)
2701 {
2702 newViewerFace1.n1 = this.normals[i];
2703 newViewerFace1.n2 = this.normals[i - numVerts];
2704 newViewerFace1.n3 = this.normals[i - numVerts];
2705
2706 newViewerFace2.n1 = this.normals[i];
2707 newViewerFace2.n2 = this.normals[i - numVerts];
2708 newViewerFace2.n3 = this.normals[i];
2709 }
2710 else if (hollowSides < 5 && whichVert >= newLayer.numOuterVerts)
2711 {
2712 newViewerFace1.n1 = this.normals[iNext];
2713 newViewerFace1.n2 = this.normals[iNext - numVerts];
2714 newViewerFace1.n3 = this.normals[iNext - numVerts];
2715
2716 newViewerFace2.n1 = this.normals[iNext];
2717 newViewerFace2.n2 = this.normals[iNext - numVerts];
2718 newViewerFace2.n3 = this.normals[iNext];
2719 }
2720 else
2721 {
2722 newViewerFace1.n1 = this.normals[i];
2723 newViewerFace1.n2 = this.normals[i - numVerts];
2724 newViewerFace1.n3 = this.normals[iNext - numVerts];
2725
2726 newViewerFace2.n1 = this.normals[i];
2727 newViewerFace2.n2 = this.normals[iNext - numVerts];
2728 newViewerFace2.n3 = this.normals[iNext];
2729 }
2730 }
2731
2732 //newViewerFace1.primFaceNumber = newViewerFace2.primFaceNumber = newLayer.faceNumbers[whichVert];
2733 this.viewerFaces.Add(newViewerFace1);
2734 this.viewerFaces.Add(newViewerFace2);
2735
2736 }
2737 }
2738 }
2739
2740 lastCutNormal1 = newLayer.cutNormal1;
2741 lastCutNormal2 = newLayer.cutNormal2;
2742 lastV = 1.0f - percentOfPath;
2743
2744 // calculate terms for next iteration
2745 // calculate the angle for the next iteration of the loop
2746
2747 if (angle >= endAngle - 0.01)
2748 done = true;
2749 else
2750 {
2751 step += 1;
2752 angle = stepSize * step;
2753 if (angle > endAngle)
2754 angle = endAngle;
2755 }
2756
2757 if (done && viewerMode && needEndFaces)
2758 {
2759 // add the bottom faces to the viewerFaces list here
2760 Coord faceNormal = newLayer.faceNormal;
2761 ViewerFace newViewerFace = new ViewerFace();
2762 //newViewerFace.primFaceNumber = newLayer.bottomFaceNumber + 1;
2763 newViewerFace.primFaceNumber = newLayer.bottomFaceNumber;
2764 foreach (Face face in newLayer.faces)
2765 {
2766 newViewerFace.v1 = newLayer.coords[face.v1 - coordsLen];
2767 newViewerFace.v2 = newLayer.coords[face.v2 - coordsLen];
2768 newViewerFace.v3 = newLayer.coords[face.v3 - coordsLen];
2769
2770 newViewerFace.coordIndex1 = face.v1 - coordsLen;
2771 newViewerFace.coordIndex2 = face.v2 - coordsLen;
2772 newViewerFace.coordIndex3 = face.v3 - coordsLen;
2773
2774 newViewerFace.n1 = faceNormal;
2775 newViewerFace.n2 = faceNormal;
2776 newViewerFace.n3 = faceNormal;
2777
2778 newViewerFace.uv1 = newLayer.faceUVs[face.v1 - coordsLen];
2779 newViewerFace.uv2 = newLayer.faceUVs[face.v2 - coordsLen];
2780 newViewerFace.uv3 = newLayer.faceUVs[face.v3 - coordsLen];
2781
2782 this.viewerFaces.Add(newViewerFace);
2783 }
2784 }
2785 }
2786 } 1962 }
2787 1963
1964
2788 private Coord SurfaceNormal(Coord c1, Coord c2, Coord c3) 1965 private Coord SurfaceNormal(Coord c1, Coord c2, Coord c3)
2789 { 1966 {
2790 Coord edge1 = new Coord(c2.X - c1.X, c2.Y - c1.Y, c2.Z - c1.Z); 1967 Coord edge1 = new Coord(c2.X - c1.X, c2.Y - c1.Y, c2.Z - c1.Z);
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index c86bc62..1bc4a25 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -1209,11 +1209,11 @@ namespace OpenSim.Region.Physics.OdePlugin
1209 m_requestedUpdateFrequency = 0; 1209 m_requestedUpdateFrequency = 0;
1210 m_eventsubscription = 0; 1210 m_eventsubscription = 0;
1211 } 1211 }
1212 public void AddCollisionEvent(uint CollidedWith, float depth) 1212 public void AddCollisionEvent(uint CollidedWith, ContactPoint contact)
1213 { 1213 {
1214 if (m_eventsubscription > 0) 1214 if (m_eventsubscription > 0)
1215 { 1215 {
1216 CollisionEventsThisFrame.addCollider(CollidedWith, depth); 1216 CollisionEventsThisFrame.addCollider(CollidedWith, contact);
1217 } 1217 }
1218 } 1218 }
1219 1219
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index 49bbab9..fa42023 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -2958,11 +2958,11 @@ Console.WriteLine(" JointCreateFixed");
2958 m_eventsubscription = 0; 2958 m_eventsubscription = 0;
2959 } 2959 }
2960 2960
2961 public void AddCollisionEvent(uint CollidedWith, float depth) 2961 public void AddCollisionEvent(uint CollidedWith, ContactPoint contact)
2962 { 2962 {
2963 if (CollisionEventsThisFrame == null) 2963 if (CollisionEventsThisFrame == null)
2964 CollisionEventsThisFrame = new CollisionEventUpdate(); 2964 CollisionEventsThisFrame = new CollisionEventUpdate();
2965 CollisionEventsThisFrame.addCollider(CollidedWith,depth); 2965 CollisionEventsThisFrame.addCollider(CollidedWith, contact);
2966 } 2966 }
2967 2967
2968 public void SendCollisions() 2968 public void SendCollisions()
diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
index 73ad15e..3c9a31d 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
@@ -159,6 +159,7 @@ namespace OpenSim.Region.Physics.OdePlugin
159 159
160 private float ODE_STEPSIZE = 0.020f; 160 private float ODE_STEPSIZE = 0.020f;
161 private float metersInSpace = 29.9f; 161 private float metersInSpace = 29.9f;
162 private float m_timeDilation = 1.0f;
162 163
163 public float gravityx = 0f; 164 public float gravityx = 0f;
164 public float gravityy = 0f; 165 public float gravityy = 0f;
@@ -177,8 +178,8 @@ namespace OpenSim.Region.Physics.OdePlugin
177 //private int m_returncollisions = 10; 178 //private int m_returncollisions = 10;
178 179
179 private readonly IntPtr contactgroup; 180 private readonly IntPtr contactgroup;
180 internal IntPtr LandGeom;
181 181
182 internal IntPtr LandGeom;
182 internal IntPtr WaterGeom; 183 internal IntPtr WaterGeom;
183 184
184 private float nmTerrainContactFriction = 255.0f; 185 private float nmTerrainContactFriction = 255.0f;
@@ -250,7 +251,7 @@ namespace OpenSim.Region.Physics.OdePlugin
250 private bool m_NINJA_physics_joints_enabled = false; 251 private bool m_NINJA_physics_joints_enabled = false;
251 //private Dictionary<String, IntPtr> jointpart_name_map = new Dictionary<String,IntPtr>(); 252 //private Dictionary<String, IntPtr> jointpart_name_map = new Dictionary<String,IntPtr>();
252 private readonly Dictionary<String, List<PhysicsJoint>> joints_connecting_actor = new Dictionary<String, List<PhysicsJoint>>(); 253 private readonly Dictionary<String, List<PhysicsJoint>> joints_connecting_actor = new Dictionary<String, List<PhysicsJoint>>();
253 private d.ContactGeom[] contacts = new d.ContactGeom[80]; 254 private d.ContactGeom[] contacts;
254 private readonly List<PhysicsJoint> requestedJointsToBeCreated = new List<PhysicsJoint>(); // lock only briefly. accessed by external code (to request new joints) and by OdeScene.Simulate() to move those joints into pending/active 255 private readonly List<PhysicsJoint> requestedJointsToBeCreated = new List<PhysicsJoint>(); // lock only briefly. accessed by external code (to request new joints) and by OdeScene.Simulate() to move those joints into pending/active
255 private readonly List<PhysicsJoint> pendingJoints = new List<PhysicsJoint>(); // can lock for longer. accessed only by OdeScene. 256 private readonly List<PhysicsJoint> pendingJoints = new List<PhysicsJoint>(); // can lock for longer. accessed only by OdeScene.
256 private readonly List<PhysicsJoint> activeJoints = new List<PhysicsJoint>(); // can lock for longer. accessed only by OdeScene. 257 private readonly List<PhysicsJoint> activeJoints = new List<PhysicsJoint>(); // can lock for longer. accessed only by OdeScene.
@@ -396,6 +397,8 @@ namespace OpenSim.Region.Physics.OdePlugin
396 avStandupTensor = 550000f; 397 avStandupTensor = 550000f;
397 } 398 }
398 399
400 int contactsPerCollision = 80;
401
399 if (m_config != null) 402 if (m_config != null)
400 { 403 {
401 IConfig physicsconfig = m_config.Configs["ODEPhysicsSettings"]; 404 IConfig physicsconfig = m_config.Configs["ODEPhysicsSettings"];
@@ -438,6 +441,8 @@ namespace OpenSim.Region.Physics.OdePlugin
438 avCapRadius = physicsconfig.GetFloat("av_capsule_radius", 0.37f); 441 avCapRadius = physicsconfig.GetFloat("av_capsule_radius", 0.37f);
439 avCapsuleTilted = physicsconfig.GetBoolean("av_capsule_tilted", true); 442 avCapsuleTilted = physicsconfig.GetBoolean("av_capsule_tilted", true);
440 443
444 contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", 80);
445
441 geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 3); 446 geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 3);
442 geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15); 447 geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15);
443 geomCrossingFailuresBeforeOutofbounds = physicsconfig.GetInt("geom_crossing_failures_before_outofbounds", 5); 448 geomCrossingFailuresBeforeOutofbounds = physicsconfig.GetInt("geom_crossing_failures_before_outofbounds", 5);
@@ -475,10 +480,11 @@ namespace OpenSim.Region.Physics.OdePlugin
475 480
476 m_NINJA_physics_joints_enabled = physicsconfig.GetBoolean("use_NINJA_physics_joints", false); 481 m_NINJA_physics_joints_enabled = physicsconfig.GetBoolean("use_NINJA_physics_joints", false);
477 minimumGroundFlightOffset = physicsconfig.GetFloat("minimum_ground_flight_offset", 3f); 482 minimumGroundFlightOffset = physicsconfig.GetFloat("minimum_ground_flight_offset", 3f);
478
479 } 483 }
480 } 484 }
481 485
486 contacts = new d.ContactGeom[contactsPerCollision];
487
482 staticPrimspace = new IntPtr[(int)(300 / metersInSpace), (int)(300 / metersInSpace)]; 488 staticPrimspace = new IntPtr[(int)(300 / metersInSpace), (int)(300 / metersInSpace)];
483 489
484 // Centeral contact friction and bounce 490 // Centeral contact friction and bounce
@@ -771,7 +777,9 @@ namespace OpenSim.Region.Physics.OdePlugin
771 777
772 lock (contacts) 778 lock (contacts)
773 { 779 {
774 count = d.Collide(g1, g2, contacts.GetLength(0), contacts, d.ContactGeom.SizeOf); 780 count = d.Collide(g1, g2, contacts.Length, contacts, d.ContactGeom.SizeOf);
781 if (count > contacts.Length)
782 m_log.Error("[PHYSICS]: Got " + count + " contacts when we asked for a maximum of " + contacts.Length);
775 } 783 }
776 } 784 }
777 catch (SEHException) 785 catch (SEHException)
@@ -799,7 +807,7 @@ namespace OpenSim.Region.Physics.OdePlugin
799 p2 = PANull; 807 p2 = PANull;
800 } 808 }
801 809
802 float max_collision_depth = 0f; 810 ContactPoint maxDepthContact = new ContactPoint();
803 if (p1.CollisionScore + count >= float.MaxValue) 811 if (p1.CollisionScore + count >= float.MaxValue)
804 p1.CollisionScore = 0; 812 p1.CollisionScore = 0;
805 p1.CollisionScore += count; 813 p1.CollisionScore += count;
@@ -810,9 +818,17 @@ namespace OpenSim.Region.Physics.OdePlugin
810 818
811 for (int i = 0; i < count; i++) 819 for (int i = 0; i < count; i++)
812 { 820 {
821 d.ContactGeom curContact = contacts[i];
813 822
823 if (curContact.depth > maxDepthContact.PenetrationDepth)
824 {
825 maxDepthContact = new ContactPoint(
826 new Vector3(curContact.pos.X, curContact.pos.Y, curContact.pos.Z),
827 new Vector3(curContact.normal.X, curContact.normal.Y, curContact.normal.Z),
828 curContact.depth
829 );
830 }
814 831
815 max_collision_depth = (contacts[i].depth > max_collision_depth) ? contacts[i].depth : max_collision_depth;
816 //m_log.Warn("[CCOUNT]: " + count); 832 //m_log.Warn("[CCOUNT]: " + count);
817 IntPtr joint; 833 IntPtr joint;
818 // If we're colliding with terrain, use 'TerrainContact' instead of contact. 834 // If we're colliding with terrain, use 'TerrainContact' instead of contact.
@@ -829,7 +845,7 @@ namespace OpenSim.Region.Physics.OdePlugin
829 p2.CollidingObj = true; 845 p2.CollidingObj = true;
830 break; 846 break;
831 case (int)ActorTypes.Prim: 847 case (int)ActorTypes.Prim:
832 if (p2.Velocity.X > 0 || p2.Velocity.Y > 0 || p2.Velocity.Z > 0) 848 if (p2.Velocity.LengthSquared() > 0.0f)
833 p2.CollidingObj = true; 849 p2.CollidingObj = true;
834 break; 850 break;
835 case (int)ActorTypes.Unknown: 851 case (int)ActorTypes.Unknown:
@@ -845,14 +861,14 @@ namespace OpenSim.Region.Physics.OdePlugin
845 #region InterPenetration Handling - Unintended physics explosions 861 #region InterPenetration Handling - Unintended physics explosions
846# region disabled code1 862# region disabled code1
847 863
848 if (contacts[i].depth >= 0.08f) 864 if (curContact.depth >= 0.08f)
849 { 865 {
850 //This is disabled at the moment only because it needs more tweaking 866 //This is disabled at the moment only because it needs more tweaking
851 //It will eventually be uncommented 867 //It will eventually be uncommented
852 /* 868 /*
853 if (contacts[i].depth >= 1.00f) 869 if (contact.depth >= 1.00f)
854 { 870 {
855 //m_log.Debug("[PHYSICS]: " + contacts[i].depth.ToString()); 871 //m_log.Debug("[PHYSICS]: " + contact.depth.ToString());
856 } 872 }
857 873
858 //If you interpenetrate a prim with an agent 874 //If you interpenetrate a prim with an agent
@@ -862,37 +878,37 @@ namespace OpenSim.Region.Physics.OdePlugin
862 p2.PhysicsActorType == (int) ActorTypes.Prim)) 878 p2.PhysicsActorType == (int) ActorTypes.Prim))
863 { 879 {
864 880
865 //contacts[i].depth = contacts[i].depth * 4.15f; 881 //contact.depth = contact.depth * 4.15f;
866 /* 882 /*
867 if (p2.PhysicsActorType == (int) ActorTypes.Agent) 883 if (p2.PhysicsActorType == (int) ActorTypes.Agent)
868 { 884 {
869 p2.CollidingObj = true; 885 p2.CollidingObj = true;
870 contacts[i].depth = 0.003f; 886 contact.depth = 0.003f;
871 p2.Velocity = p2.Velocity + new PhysicsVector(0, 0, 2.5f); 887 p2.Velocity = p2.Velocity + new PhysicsVector(0, 0, 2.5f);
872 OdeCharacter character = (OdeCharacter) p2; 888 OdeCharacter character = (OdeCharacter) p2;
873 character.SetPidStatus(true); 889 character.SetPidStatus(true);
874 contacts[i].pos = new d.Vector3(contacts[i].pos.X + (p1.Size.X / 2), contacts[i].pos.Y + (p1.Size.Y / 2), contacts[i].pos.Z + (p1.Size.Z / 2)); 890 contact.pos = new d.Vector3(contact.pos.X + (p1.Size.X / 2), contact.pos.Y + (p1.Size.Y / 2), contact.pos.Z + (p1.Size.Z / 2));
875 891
876 } 892 }
877 else 893 else
878 { 894 {
879 895
880 //contacts[i].depth = 0.0000000f; 896 //contact.depth = 0.0000000f;
881 } 897 }
882 if (p1.PhysicsActorType == (int) ActorTypes.Agent) 898 if (p1.PhysicsActorType == (int) ActorTypes.Agent)
883 { 899 {
884 900
885 p1.CollidingObj = true; 901 p1.CollidingObj = true;
886 contacts[i].depth = 0.003f; 902 contact.depth = 0.003f;
887 p1.Velocity = p1.Velocity + new PhysicsVector(0, 0, 2.5f); 903 p1.Velocity = p1.Velocity + new PhysicsVector(0, 0, 2.5f);
888 contacts[i].pos = new d.Vector3(contacts[i].pos.X + (p2.Size.X / 2), contacts[i].pos.Y + (p2.Size.Y / 2), contacts[i].pos.Z + (p2.Size.Z / 2)); 904 contact.pos = new d.Vector3(contact.pos.X + (p2.Size.X / 2), contact.pos.Y + (p2.Size.Y / 2), contact.pos.Z + (p2.Size.Z / 2));
889 OdeCharacter character = (OdeCharacter)p1; 905 OdeCharacter character = (OdeCharacter)p1;
890 character.SetPidStatus(true); 906 character.SetPidStatus(true);
891 } 907 }
892 else 908 else
893 { 909 {
894 910
895 //contacts[i].depth = 0.0000000f; 911 //contact.depth = 0.0000000f;
896 } 912 }
897 913
898 914
@@ -917,7 +933,7 @@ namespace OpenSim.Region.Physics.OdePlugin
917 //AddPhysicsActorTaint(p2); 933 //AddPhysicsActorTaint(p2);
918 //} 934 //}
919 935
920 //if (contacts[i].depth >= 0.25f) 936 //if (contact.depth >= 0.25f)
921 //{ 937 //{
922 // Don't collide, one or both prim will expld. 938 // Don't collide, one or both prim will expld.
923 939
@@ -935,21 +951,21 @@ namespace OpenSim.Region.Physics.OdePlugin
935 //AddPhysicsActorTaint(p2); 951 //AddPhysicsActorTaint(p2);
936 //} 952 //}
937 953
938 //contacts[i].depth = contacts[i].depth / 8f; 954 //contact.depth = contact.depth / 8f;
939 //contacts[i].normal = new d.Vector3(0, 0, 1); 955 //contact.normal = new d.Vector3(0, 0, 1);
940 //} 956 //}
941 //if (op1.m_disabled || op2.m_disabled) 957 //if (op1.m_disabled || op2.m_disabled)
942 //{ 958 //{
943 //Manually disabled objects stay disabled 959 //Manually disabled objects stay disabled
944 //contacts[i].depth = 0f; 960 //contact.depth = 0f;
945 //} 961 //}
946 #endregion 962 #endregion
947 } 963 }
948 */ 964 */
949#endregion 965#endregion
950 if (contacts[i].depth >= 1.00f) 966 if (curContact.depth >= 1.00f)
951 { 967 {
952 //m_log.Info("[P]: " + contacts[i].depth.ToString()); 968 //m_log.Info("[P]: " + contact.depth.ToString());
953 if ((p2.PhysicsActorType == (int) ActorTypes.Agent && 969 if ((p2.PhysicsActorType == (int) ActorTypes.Agent &&
954 p1.PhysicsActorType == (int) ActorTypes.Unknown) || 970 p1.PhysicsActorType == (int) ActorTypes.Unknown) ||
955 (p1.PhysicsActorType == (int) ActorTypes.Agent && 971 (p1.PhysicsActorType == (int) ActorTypes.Agent &&
@@ -962,12 +978,12 @@ namespace OpenSim.Region.Physics.OdePlugin
962 OdeCharacter character = (OdeCharacter) p2; 978 OdeCharacter character = (OdeCharacter) p2;
963 979
964 //p2.CollidingObj = true; 980 //p2.CollidingObj = true;
965 contacts[i].depth = 0.00000003f; 981 curContact.depth = 0.00000003f;
966 p2.Velocity = p2.Velocity + new Vector3(0f, 0f, 0.5f); 982 p2.Velocity = p2.Velocity + new Vector3(0f, 0f, 0.5f);
967 contacts[i].pos = 983 curContact.pos =
968 new d.Vector3(contacts[i].pos.X + (p1.Size.X/2), 984 new d.Vector3(curContact.pos.X + (p1.Size.X/2),
969 contacts[i].pos.Y + (p1.Size.Y/2), 985 curContact.pos.Y + (p1.Size.Y/2),
970 contacts[i].pos.Z + (p1.Size.Z/2)); 986 curContact.pos.Z + (p1.Size.Z/2));
971 character.SetPidStatus(true); 987 character.SetPidStatus(true);
972 } 988 }
973 } 989 }
@@ -980,12 +996,12 @@ namespace OpenSim.Region.Physics.OdePlugin
980 OdeCharacter character = (OdeCharacter) p1; 996 OdeCharacter character = (OdeCharacter) p1;
981 997
982 //p2.CollidingObj = true; 998 //p2.CollidingObj = true;
983 contacts[i].depth = 0.00000003f; 999 curContact.depth = 0.00000003f;
984 p1.Velocity = p1.Velocity + new Vector3(0f, 0f, 0.5f); 1000 p1.Velocity = p1.Velocity + new Vector3(0f, 0f, 0.5f);
985 contacts[i].pos = 1001 curContact.pos =
986 new d.Vector3(contacts[i].pos.X + (p1.Size.X/2), 1002 new d.Vector3(curContact.pos.X + (p1.Size.X/2),
987 contacts[i].pos.Y + (p1.Size.Y/2), 1003 curContact.pos.Y + (p1.Size.Y/2),
988 contacts[i].pos.Z + (p1.Size.Z/2)); 1004 curContact.pos.Z + (p1.Size.Z/2));
989 character.SetPidStatus(true); 1005 character.SetPidStatus(true);
990 } 1006 }
991 } 1007 }
@@ -1007,16 +1023,15 @@ namespace OpenSim.Region.Physics.OdePlugin
1007 if (!skipThisContact && (p2 is OdePrim) && (((OdePrim)p2).m_isVolumeDetect)) 1023 if (!skipThisContact && (p2 is OdePrim) && (((OdePrim)p2).m_isVolumeDetect))
1008 skipThisContact = true; // No collision on volume detect prims 1024 skipThisContact = true; // No collision on volume detect prims
1009 1025
1010 if (!skipThisContact && contacts[i].depth < 0f) 1026 if (!skipThisContact && curContact.depth < 0f)
1011 skipThisContact = true; 1027 skipThisContact = true;
1012 1028
1013 if (!skipThisContact && checkDupe(contacts[i], p2.PhysicsActorType)) 1029 if (!skipThisContact && checkDupe(curContact, p2.PhysicsActorType))
1014 skipThisContact = true; 1030 skipThisContact = true;
1015 1031
1016 int maxContactsbeforedeath = 4000; 1032 const int maxContactsbeforedeath = 4000;
1017 joint = IntPtr.Zero; 1033 joint = IntPtr.Zero;
1018 1034
1019
1020 if (!skipThisContact) 1035 if (!skipThisContact)
1021 { 1036 {
1022 // If we're colliding against terrain 1037 // If we're colliding against terrain
@@ -1027,8 +1042,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1027 (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) 1042 (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f))
1028 { 1043 {
1029 // Use the movement terrain contact 1044 // Use the movement terrain contact
1030 AvatarMovementTerrainContact.geom = contacts[i]; 1045 AvatarMovementTerrainContact.geom = curContact;
1031 _perloopContact.Add(contacts[i]); 1046 _perloopContact.Add(curContact);
1032 if (m_global_contactcount < maxContactsbeforedeath) 1047 if (m_global_contactcount < maxContactsbeforedeath)
1033 { 1048 {
1034 joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact); 1049 joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact);
@@ -1040,8 +1055,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1040 if (p2.PhysicsActorType == (int)ActorTypes.Agent) 1055 if (p2.PhysicsActorType == (int)ActorTypes.Agent)
1041 { 1056 {
1042 // Use the non moving terrain contact 1057 // Use the non moving terrain contact
1043 TerrainContact.geom = contacts[i]; 1058 TerrainContact.geom = curContact;
1044 _perloopContact.Add(contacts[i]); 1059 _perloopContact.Add(curContact);
1045 if (m_global_contactcount < maxContactsbeforedeath) 1060 if (m_global_contactcount < maxContactsbeforedeath)
1046 { 1061 {
1047 joint = d.JointCreateContact(world, contactgroup, ref TerrainContact); 1062 joint = d.JointCreateContact(world, contactgroup, ref TerrainContact);
@@ -1066,8 +1081,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1066 material = ((OdePrim)p2).m_material; 1081 material = ((OdePrim)p2).m_material;
1067 1082
1068 //m_log.DebugFormat("Material: {0}", material); 1083 //m_log.DebugFormat("Material: {0}", material);
1069 m_materialContacts[material, movintYN].geom = contacts[i]; 1084 m_materialContacts[material, movintYN].geom = curContact;
1070 _perloopContact.Add(contacts[i]); 1085 _perloopContact.Add(curContact);
1071 1086
1072 if (m_global_contactcount < maxContactsbeforedeath) 1087 if (m_global_contactcount < maxContactsbeforedeath)
1073 { 1088 {
@@ -1092,8 +1107,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1092 if (p2 is OdePrim) 1107 if (p2 is OdePrim)
1093 material = ((OdePrim)p2).m_material; 1108 material = ((OdePrim)p2).m_material;
1094 //m_log.DebugFormat("Material: {0}", material); 1109 //m_log.DebugFormat("Material: {0}", material);
1095 m_materialContacts[material, movintYN].geom = contacts[i]; 1110 m_materialContacts[material, movintYN].geom = curContact;
1096 _perloopContact.Add(contacts[i]); 1111 _perloopContact.Add(curContact);
1097 1112
1098 if (m_global_contactcount < maxContactsbeforedeath) 1113 if (m_global_contactcount < maxContactsbeforedeath)
1099 { 1114 {
@@ -1121,20 +1136,20 @@ namespace OpenSim.Region.Physics.OdePlugin
1121 */ 1136 */
1122 //WaterContact.surface.soft_cfm = 0.0000f; 1137 //WaterContact.surface.soft_cfm = 0.0000f;
1123 //WaterContact.surface.soft_erp = 0.00000f; 1138 //WaterContact.surface.soft_erp = 0.00000f;
1124 if (contacts[i].depth > 0.1f) 1139 if (curContact.depth > 0.1f)
1125 { 1140 {
1126 contacts[i].depth *= 52; 1141 curContact.depth *= 52;
1127 //contacts[i].normal = new d.Vector3(0, 0, 1); 1142 //contact.normal = new d.Vector3(0, 0, 1);
1128 //contacts[i].pos = new d.Vector3(0, 0, contacts[i].pos.Z - 5f); 1143 //contact.pos = new d.Vector3(0, 0, contact.pos.Z - 5f);
1129 } 1144 }
1130 WaterContact.geom = contacts[i]; 1145 WaterContact.geom = curContact;
1131 _perloopContact.Add(contacts[i]); 1146 _perloopContact.Add(curContact);
1132 if (m_global_contactcount < maxContactsbeforedeath) 1147 if (m_global_contactcount < maxContactsbeforedeath)
1133 { 1148 {
1134 joint = d.JointCreateContact(world, contactgroup, ref WaterContact); 1149 joint = d.JointCreateContact(world, contactgroup, ref WaterContact);
1135 m_global_contactcount++; 1150 m_global_contactcount++;
1136 } 1151 }
1137 //m_log.Info("[PHYSICS]: Prim Water Contact" + contacts[i].depth); 1152 //m_log.Info("[PHYSICS]: Prim Water Contact" + contact.depth);
1138 } 1153 }
1139 else 1154 else
1140 { 1155 {
@@ -1145,8 +1160,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1145 if ((Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) 1160 if ((Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f))
1146 { 1161 {
1147 // Use the Movement prim contact 1162 // Use the Movement prim contact
1148 AvatarMovementprimContact.geom = contacts[i]; 1163 AvatarMovementprimContact.geom = curContact;
1149 _perloopContact.Add(contacts[i]); 1164 _perloopContact.Add(curContact);
1150 if (m_global_contactcount < maxContactsbeforedeath) 1165 if (m_global_contactcount < maxContactsbeforedeath)
1151 { 1166 {
1152 joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact); 1167 joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact);
@@ -1156,8 +1171,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1156 else 1171 else
1157 { 1172 {
1158 // Use the non movement contact 1173 // Use the non movement contact
1159 contact.geom = contacts[i]; 1174 contact.geom = curContact;
1160 _perloopContact.Add(contacts[i]); 1175 _perloopContact.Add(curContact);
1161 1176
1162 if (m_global_contactcount < maxContactsbeforedeath) 1177 if (m_global_contactcount < maxContactsbeforedeath)
1163 { 1178 {
@@ -1175,8 +1190,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1175 material = ((OdePrim)p2).m_material; 1190 material = ((OdePrim)p2).m_material;
1176 1191
1177 //m_log.DebugFormat("Material: {0}", material); 1192 //m_log.DebugFormat("Material: {0}", material);
1178 m_materialContacts[material, 0].geom = contacts[i]; 1193 m_materialContacts[material, 0].geom = curContact;
1179 _perloopContact.Add(contacts[i]); 1194 _perloopContact.Add(curContact);
1180 1195
1181 if (m_global_contactcount < maxContactsbeforedeath) 1196 if (m_global_contactcount < maxContactsbeforedeath)
1182 { 1197 {
@@ -1194,7 +1209,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1194 } 1209 }
1195 1210
1196 } 1211 }
1197 collision_accounting_events(p1, p2, max_collision_depth); 1212 collision_accounting_events(p1, p2, maxDepthContact);
1198 if (count > geomContactPointsStartthrottle) 1213 if (count > geomContactPointsStartthrottle)
1199 { 1214 {
1200 // If there are more then 3 contact points, it's likely 1215 // If there are more then 3 contact points, it's likely
@@ -1278,7 +1293,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1278 return result; 1293 return result;
1279 } 1294 }
1280 1295
1281 private void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, float collisiondepth) 1296 private void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, ContactPoint contact)
1282 { 1297 {
1283 // obj1LocalID = 0; 1298 // obj1LocalID = 0;
1284 //returncollisions = false; 1299 //returncollisions = false;
@@ -1299,7 +1314,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1299 case ActorTypes.Agent: 1314 case ActorTypes.Agent:
1300 cc1 = (OdeCharacter)p1; 1315 cc1 = (OdeCharacter)p1;
1301 obj2LocalID = cc1.m_localID; 1316 obj2LocalID = cc1.m_localID;
1302 cc1.AddCollisionEvent(cc2.m_localID, collisiondepth); 1317 cc1.AddCollisionEvent(cc2.m_localID, contact);
1303 //ctype = (int)CollisionCategories.Character; 1318 //ctype = (int)CollisionCategories.Character;
1304 1319
1305 //if (cc1.CollidingObj) 1320 //if (cc1.CollidingObj)
@@ -1314,7 +1329,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1314 { 1329 {
1315 cp1 = (OdePrim) p1; 1330 cp1 = (OdePrim) p1;
1316 obj2LocalID = cp1.m_localID; 1331 obj2LocalID = cp1.m_localID;
1317 cp1.AddCollisionEvent(cc2.m_localID, collisiondepth); 1332 cp1.AddCollisionEvent(cc2.m_localID, contact);
1318 } 1333 }
1319 //ctype = (int)CollisionCategories.Geom; 1334 //ctype = (int)CollisionCategories.Geom;
1320 1335
@@ -1334,7 +1349,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1334 break; 1349 break;
1335 } 1350 }
1336 1351
1337 cc2.AddCollisionEvent(obj2LocalID, collisiondepth); 1352 cc2.AddCollisionEvent(obj2LocalID, contact);
1338 break; 1353 break;
1339 case ActorTypes.Prim: 1354 case ActorTypes.Prim:
1340 1355
@@ -1350,7 +1365,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1350 { 1365 {
1351 cc1 = (OdeCharacter) p1; 1366 cc1 = (OdeCharacter) p1;
1352 obj2LocalID = cc1.m_localID; 1367 obj2LocalID = cc1.m_localID;
1353 cc1.AddCollisionEvent(cp2.m_localID, collisiondepth); 1368 cc1.AddCollisionEvent(cp2.m_localID, contact);
1354 //ctype = (int)CollisionCategories.Character; 1369 //ctype = (int)CollisionCategories.Character;
1355 1370
1356 //if (cc1.CollidingObj) 1371 //if (cc1.CollidingObj)
@@ -1366,7 +1381,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1366 { 1381 {
1367 cp1 = (OdePrim) p1; 1382 cp1 = (OdePrim) p1;
1368 obj2LocalID = cp1.m_localID; 1383 obj2LocalID = cp1.m_localID;
1369 cp1.AddCollisionEvent(cp2.m_localID, collisiondepth); 1384 cp1.AddCollisionEvent(cp2.m_localID, contact);
1370 //ctype = (int)CollisionCategories.Geom; 1385 //ctype = (int)CollisionCategories.Geom;
1371 1386
1372 //if (cp1.CollidingObj) 1387 //if (cp1.CollidingObj)
@@ -1387,7 +1402,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1387 break; 1402 break;
1388 } 1403 }
1389 1404
1390 cp2.AddCollisionEvent(obj2LocalID, collisiondepth); 1405 cp2.AddCollisionEvent(obj2LocalID, contact);
1391 } 1406 }
1392 break; 1407 break;
1393 } 1408 }
@@ -1750,6 +1765,11 @@ namespace OpenSim.Region.Physics.OdePlugin
1750 return result; 1765 return result;
1751 } 1766 }
1752 1767
1768 public override float TimeDilation
1769 {
1770 get { return m_timeDilation; }
1771 }
1772
1753 public override bool SupportsNINJAJoints 1773 public override bool SupportsNINJAJoints
1754 { 1774 {
1755 get { return m_NINJA_physics_joints_enabled; } 1775 get { return m_NINJA_physics_joints_enabled; }
@@ -2657,8 +2677,10 @@ namespace OpenSim.Region.Physics.OdePlugin
2657 2677
2658 // Figure out the Frames Per Second we're going at. 2678 // Figure out the Frames Per Second we're going at.
2659 //(step_time == 0.004f, there's 250 of those per second. Times the step time/step size 2679 //(step_time == 0.004f, there's 250 of those per second. Times the step time/step size
2660 2680
2661 fps = (step_time/ODE_STEPSIZE) * 1000; 2681 fps = (step_time / ODE_STEPSIZE) * 1000;
2682 // HACK: Using a time dilation of 1.0 to debug rubberbanding issues
2683 //m_timeDilation = Math.Min((step_time / ODE_STEPSIZE) / (0.09375f / ODE_STEPSIZE), 1.0f);
2662 2684
2663 step_time = 0.09375f; 2685 step_time = 0.09375f;
2664 2686
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/ICompiler.cs b/OpenSim/Region/ScriptEngine/Interfaces/ICompiler.cs
index f8af902..e4ca635 100644
--- a/OpenSim/Region/ScriptEngine/Interfaces/ICompiler.cs
+++ b/OpenSim/Region/ScriptEngine/Interfaces/ICompiler.cs
@@ -34,9 +34,7 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
34{ 34{
35 public interface ICompiler 35 public interface ICompiler
36 { 36 {
37 object PerformScriptCompile(string source, string asset, UUID ownerID); 37 void PerformScriptCompile(string source, string asset, UUID ownerID, out string assembly, out Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap);
38 string[] GetWarnings(); 38 string[] GetWarnings();
39 Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>
40 LineMap();
41 } 39 }
42} 40}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 3849558..0ea62d7 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -2163,7 +2163,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2163 public LSL_Vector llGetOmega() 2163 public LSL_Vector llGetOmega()
2164 { 2164 {
2165 m_host.AddScriptLPS(1); 2165 m_host.AddScriptLPS(1);
2166 return new LSL_Vector(m_host.RotationalVelocity.X, m_host.RotationalVelocity.Y, m_host.RotationalVelocity.Z); 2166 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z);
2167 } 2167 }
2168 2168
2169 public LSL_Float llGetTimeOfDay() 2169 public LSL_Float llGetTimeOfDay()
@@ -3159,7 +3159,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3159 public void llTargetOmega(LSL_Vector axis, double spinrate, double gain) 3159 public void llTargetOmega(LSL_Vector axis, double spinrate, double gain)
3160 { 3160 {
3161 m_host.AddScriptLPS(1); 3161 m_host.AddScriptLPS(1);
3162 m_host.RotationalVelocity = new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate));
3163 m_host.AngularVelocity = new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate)); 3162 m_host.AngularVelocity = new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate));
3164 m_host.ScheduleTerseUpdate(); 3163 m_host.ScheduleTerseUpdate();
3165 m_host.SendTerseUpdateToAllClients(); 3164 m_host.SendTerseUpdateToAllClients();
@@ -3817,7 +3816,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3817 { 3816 {
3818 case 1: // DATA_ONLINE (0|1) 3817 case 1: // DATA_ONLINE (0|1)
3819 // TODO: implement fetching of this information 3818 // TODO: implement fetching of this information
3820 if (userProfile.CurrentAgent.AgentOnline) 3819 if (userProfile.CurrentAgent!=null && userProfile.CurrentAgent.AgentOnline)
3821 reply = "1"; 3820 reply = "1";
3822 else 3821 else
3823 reply = "0"; 3822 reply = "0";
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index 917ca44..121159c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -113,7 +113,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
113 return; 113 return;
114 114
115 //ILease lease = (ILease)RemotingServices.GetLifetimeService(data as MarshalByRefObject); 115 //ILease lease = (ILease)RemotingServices.GetLifetimeService(data as MarshalByRefObject);
116 RemotingServices.GetLifetimeService(data as MarshalByRefObject); 116 //RemotingServices.GetLifetimeService(data as MarshalByRefObject);
117// lease.Register(m_sponser); 117// lease.Register(m_sponser);
118 118
119 MethodInfo mi = inits[api]; 119 MethodInfo mi = inits[api];
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
index fe26429..3080c71 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
@@ -74,7 +74,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
74 private string FilePrefix; 74 private string FilePrefix;
75 private string ScriptEnginesPath = "ScriptEngines"; 75 private string ScriptEnginesPath = "ScriptEngines";
76 // mapping between LSL and C# line/column numbers 76 // mapping between LSL and C# line/column numbers
77 private Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> m_positionMap;
78 private ICodeConverter LSL_Converter; 77 private ICodeConverter LSL_Converter;
79 78
80 private List<string> m_warnings = new List<string>(); 79 private List<string> m_warnings = new List<string>();
@@ -91,6 +90,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
91 private static UInt64 scriptCompileCounter = 0; // And a counter 90 private static UInt64 scriptCompileCounter = 0; // And a counter
92 91
93 public IScriptEngine m_scriptEngine; 92 public IScriptEngine m_scriptEngine;
93 private Dictionary<string, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>> m_lineMaps =
94 new Dictionary<string, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>>();
95
94 public Compiler(IScriptEngine scriptEngine) 96 public Compiler(IScriptEngine scriptEngine)
95 { 97 {
96 m_scriptEngine = scriptEngine; 98 m_scriptEngine = scriptEngine;
@@ -172,8 +174,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
172 else 174 else
173 { 175 {
174#if DEBUG 176#if DEBUG
175// m_log.Debug("[Compiler]: " + 177 // m_log.Debug("[Compiler]: " +
176// "Config OK. Default language \"" + defaultCompileLanguage + "\" specified in \"DefaultCompileLanguage\" is recognized as a valid language."); 178 // "Config OK. Default language \"" + defaultCompileLanguage + "\" specified in \"DefaultCompileLanguage\" is recognized as a valid language.");
177#endif 179#endif
178 // LANGUAGE IS IN ALLOW-LIST 180 // LANGUAGE IS IN ALLOW-LIST
179 DefaultCompileLanguage = LanguageMapping[defaultCompileLanguage]; 181 DefaultCompileLanguage = LanguageMapping[defaultCompileLanguage];
@@ -212,12 +214,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
212 catch (Exception ex) 214 catch (Exception ex)
213 { 215 {
214 m_log.Error("[Compiler]: Exception trying to create ScriptEngine directory \"" + Path.Combine(ScriptEnginesPath, 216 m_log.Error("[Compiler]: Exception trying to create ScriptEngine directory \"" + Path.Combine(ScriptEnginesPath,
215 m_scriptEngine.World.RegionInfo.RegionID.ToString())+ "\": " + ex.ToString()); 217 m_scriptEngine.World.RegionInfo.RegionID.ToString()) + "\": " + ex.ToString());
216 } 218 }
217 } 219 }
218 220
219 foreach (string file in Directory.GetFiles(Path.Combine(ScriptEnginesPath, 221 foreach (string file in Directory.GetFiles(Path.Combine(ScriptEnginesPath,
220 m_scriptEngine.World.RegionInfo.RegionID.ToString()),FilePrefix + "_compiled*")) 222 m_scriptEngine.World.RegionInfo.RegionID.ToString()), FilePrefix + "_compiled*"))
221 { 223 {
222 try 224 try
223 { 225 {
@@ -271,16 +273,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
271 /// </summary> 273 /// </summary>
272 /// <param name="Script">LSL script</param> 274 /// <param name="Script">LSL script</param>
273 /// <returns>Filename to .dll assembly</returns> 275 /// <returns>Filename to .dll assembly</returns>
274 public object PerformScriptCompile(string Script, string asset, UUID ownerUUID) 276 public void PerformScriptCompile(string Script, string asset, UUID ownerUUID,
277 out string assembly, out Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap)
275 { 278 {
276 m_positionMap = null; 279 linemap = null;
277 m_warnings.Clear(); 280 m_warnings.Clear();
278 281
279 string OutFile = Path.Combine(ScriptEnginesPath, Path.Combine( 282 assembly = Path.Combine(ScriptEnginesPath, Path.Combine(
280 m_scriptEngine.World.RegionInfo.RegionID.ToString(), 283 m_scriptEngine.World.RegionInfo.RegionID.ToString(),
281 FilePrefix + "_compiled_" + asset + ".dll")); 284 FilePrefix + "_compiled_" + asset + ".dll"));
282// string OutFile = Path.Combine(ScriptEnginesPath,
283// FilePrefix + "_compiled_" + asset + ".dll");
284 285
285 if (!Directory.Exists(ScriptEnginesPath)) 286 if (!Directory.Exists(ScriptEnginesPath))
286 { 287 {
@@ -305,60 +306,63 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
305 } 306 }
306 } 307 }
307 308
308 if (Script == String.Empty) 309 // Don't recompile if we already have it
310 // Performing 3 file exists tests for every script can still be slow
311 if (File.Exists(assembly) && File.Exists(assembly + ".text") && File.Exists(assembly + ".map"))
309 { 312 {
310 if (File.Exists(OutFile)) 313 // If we have already read this linemap file, then it will be in our dictionary.
311 return OutFile; 314 // Don't build another copy of the dictionary (saves memory) and certainly
312 315 // don't keep reading the same file from disk multiple times.
313 throw new Exception("Cannot find script assembly and no script text present"); 316 if (!m_lineMaps.ContainsKey(assembly))
317 m_lineMaps[assembly] = ReadMapFile(assembly + ".map");
318 linemap = m_lineMaps[assembly];
319 return;
314 } 320 }
315 321
316 // Don't recompile if we already have it 322 if (Script == String.Empty)
317 //
318 if (File.Exists(OutFile) && File.Exists(OutFile+".text") && File.Exists(OutFile+".map"))
319 { 323 {
320 ReadMapFile(OutFile+".map"); 324 throw new Exception("Cannot find script assembly and no script text present");
321 return OutFile;
322 } 325 }
323 326
324 enumCompileType l = DefaultCompileLanguage; 327 enumCompileType language = DefaultCompileLanguage;
325 328
326 if (Script.StartsWith("//c#", true, CultureInfo.InvariantCulture)) 329 if (Script.StartsWith("//c#", true, CultureInfo.InvariantCulture))
327 l = enumCompileType.cs; 330 language = enumCompileType.cs;
328 if (Script.StartsWith("//vb", true, CultureInfo.InvariantCulture)) 331 if (Script.StartsWith("//vb", true, CultureInfo.InvariantCulture))
329 { 332 {
330 l = enumCompileType.vb; 333 language = enumCompileType.vb;
331 // We need to remove //vb, it won't compile with that 334 // We need to remove //vb, it won't compile with that
332 335
333 Script = Script.Substring(4, Script.Length - 4); 336 Script = Script.Substring(4, Script.Length - 4);
334 } 337 }
335 if (Script.StartsWith("//lsl", true, CultureInfo.InvariantCulture)) 338 if (Script.StartsWith("//lsl", true, CultureInfo.InvariantCulture))
336 l = enumCompileType.lsl; 339 language = enumCompileType.lsl;
337 340
338 if (Script.StartsWith("//js", true, CultureInfo.InvariantCulture)) 341 if (Script.StartsWith("//js", true, CultureInfo.InvariantCulture))
339 l = enumCompileType.js; 342 language = enumCompileType.js;
340 343
341 if (Script.StartsWith("//yp", true, CultureInfo.InvariantCulture)) 344 if (Script.StartsWith("//yp", true, CultureInfo.InvariantCulture))
342 l = enumCompileType.yp; 345 language = enumCompileType.yp;
343 346
344 if (!AllowedCompilers.ContainsKey(l.ToString())) 347 if (!AllowedCompilers.ContainsKey(language.ToString()))
345 { 348 {
346 // Not allowed to compile to this language! 349 // Not allowed to compile to this language!
347 string errtext = String.Empty; 350 string errtext = String.Empty;
348 errtext += "The compiler for language \"" + l.ToString() + "\" is not in list of allowed compilers. Script will not be executed!"; 351 errtext += "The compiler for language \"" + language.ToString() + "\" is not in list of allowed compilers. Script will not be executed!";
349 throw new Exception(errtext); 352 throw new Exception(errtext);
350 } 353 }
351 354
352 if (m_scriptEngine.World.Permissions.CanCompileScript(ownerUUID, (int)l) == false) { 355 if (m_scriptEngine.World.Permissions.CanCompileScript(ownerUUID, (int)language) == false)
356 {
353 // Not allowed to compile to this language! 357 // Not allowed to compile to this language!
354 string errtext = String.Empty; 358 string errtext = String.Empty;
355 errtext += ownerUUID + " is not in list of allowed users for this scripting language. Script will not be executed!"; 359 errtext += ownerUUID + " is not in list of allowed users for this scripting language. Script will not be executed!";
356 throw new Exception(errtext); 360 throw new Exception(errtext);
357 } 361 }
358 362
359 string compileScript = Script; 363 string compileScript = Script;
360 364
361 if (l == enumCompileType.lsl) 365 if (language == enumCompileType.lsl)
362 { 366 {
363 // Its LSL, convert it to C# 367 // Its LSL, convert it to C#
364 LSL_Converter = (ICodeConverter)new CSCodeGenerator(); 368 LSL_Converter = (ICodeConverter)new CSCodeGenerator();
@@ -370,16 +374,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
370 AddWarning(warning); 374 AddWarning(warning);
371 } 375 }
372 376
373 m_positionMap = ((CSCodeGenerator) LSL_Converter).PositionMap; 377 linemap = ((CSCodeGenerator)LSL_Converter).PositionMap;
378 // Write the linemap to a file and save it in our dictionary for next time.
379 m_lineMaps[assembly] = linemap;
380 WriteMapFile(assembly + ".map", linemap);
374 } 381 }
375 382
376 if (l == enumCompileType.yp) 383 if (language == enumCompileType.yp)
377 { 384 {
378 // Its YP, convert it to C# 385 // Its YP, convert it to C#
379 compileScript = YP_Converter.Convert(Script); 386 compileScript = YP_Converter.Convert(Script);
380 } 387 }
381 388
382 switch (l) 389 switch (language)
383 { 390 {
384 case enumCompileType.cs: 391 case enumCompileType.cs:
385 case enumCompileType.lsl: 392 case enumCompileType.lsl:
@@ -396,7 +403,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
396 break; 403 break;
397 } 404 }
398 405
399 return CompileFromDotNetText(compileScript, l, asset); 406 assembly = CompileFromDotNetText(compileScript, language, asset, assembly);
407 return;
400 } 408 }
401 409
402 public string[] GetWarnings() 410 public string[] GetWarnings()
@@ -468,22 +476,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
468 /// </summary> 476 /// </summary>
469 /// <param name="Script">CS script</param> 477 /// <param name="Script">CS script</param>
470 /// <returns>Filename to .dll assembly</returns> 478 /// <returns>Filename to .dll assembly</returns>
471 internal string CompileFromDotNetText(string Script, enumCompileType lang, string asset) 479 internal string CompileFromDotNetText(string Script, enumCompileType lang, string asset, string assembly)
472 { 480 {
473 string ext = "." + lang.ToString(); 481 string ext = "." + lang.ToString();
474 482
475 // Output assembly name 483 // Output assembly name
476 scriptCompileCounter++; 484 scriptCompileCounter++;
477 string OutFile = Path.Combine(ScriptEnginesPath, Path.Combine(
478 m_scriptEngine.World.RegionInfo.RegionID.ToString(),
479 FilePrefix + "_compiled_" + asset + ".dll"));
480 try 485 try
481 { 486 {
482 File.Delete(OutFile); 487 File.Delete(assembly);
483 } 488 }
484 catch (Exception e) // NOTLEGIT - Should be just FileIOException 489 catch (Exception e) // NOTLEGIT - Should be just FileIOException
485 { 490 {
486 throw new Exception("Unable to delete old existing "+ 491 throw new Exception("Unable to delete old existing " +
487 "script-file before writing new. Compile aborted: " + 492 "script-file before writing new. Compile aborted: " +
488 e.ToString()); 493 e.ToString());
489 } 494 }
@@ -492,7 +497,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
492 if (WriteScriptSourceToDebugFile) 497 if (WriteScriptSourceToDebugFile)
493 { 498 {
494 string srcFileName = FilePrefix + "_source_" + 499 string srcFileName = FilePrefix + "_source_" +
495 Path.GetFileNameWithoutExtension(OutFile) + ext; 500 Path.GetFileNameWithoutExtension(assembly) + ext;
496 try 501 try
497 { 502 {
498 File.WriteAllText(Path.Combine(Path.Combine( 503 File.WriteAllText(Path.Combine(Path.Combine(
@@ -502,7 +507,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
502 } 507 }
503 catch (Exception ex) //NOTLEGIT - Should be just FileIOException 508 catch (Exception ex) //NOTLEGIT - Should be just FileIOException
504 { 509 {
505 m_log.Error("[Compiler]: Exception while "+ 510 m_log.Error("[Compiler]: Exception while " +
506 "trying to write script source to file \"" + 511 "trying to write script source to file \"" +
507 srcFileName + "\": " + ex.ToString()); 512 srcFileName + "\": " + ex.ToString());
508 } 513 }
@@ -528,7 +533,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
528 } 533 }
529 534
530 parameters.GenerateExecutable = false; 535 parameters.GenerateExecutable = false;
531 parameters.OutputAssembly = OutFile; 536 parameters.OutputAssembly = assembly;
532 parameters.IncludeDebugInformation = CompileWithDebugInformation; 537 parameters.IncludeDebugInformation = CompileWithDebugInformation;
533 //parameters.WarningLevel = 1; // Should be 4? 538 //parameters.WarningLevel = 1; // Should be 4?
534 parameters.TreatWarningsAsErrors = false; 539 parameters.TreatWarningsAsErrors = false;
@@ -543,7 +548,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
543 case enumCompileType.cs: 548 case enumCompileType.cs:
544 case enumCompileType.lsl: 549 case enumCompileType.lsl:
545 bool complete = false; 550 bool complete = false;
546 bool retried = false; 551 bool retried = false;
547 do 552 do
548 { 553 {
549 lock (CScodeProvider) 554 lock (CScodeProvider)
@@ -584,7 +589,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
584 parameters, Script); 589 parameters, Script);
585 break; 590 break;
586 default: 591 default:
587 throw new Exception("Compiler is not able to recongnize "+ 592 throw new Exception("Compiler is not able to recongnize " +
588 "language type \"" + lang.ToString() + "\""); 593 "language type \"" + lang.ToString() + "\"");
589 } 594 }
590 595
@@ -609,7 +614,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
609 614
610 if (severity == "Error") 615 if (severity == "Error")
611 { 616 {
612 lslPos = FindErrorPosition(CompErr.Line, CompErr.Column); 617 lslPos = FindErrorPosition(CompErr.Line, CompErr.Column, m_lineMaps[assembly]);
613 string text = CompErr.ErrorText; 618 string text = CompErr.ErrorText;
614 619
615 // Use LSL type names 620 // Use LSL type names
@@ -635,14 +640,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
635 // the compile may not be immediately apparent. Wait a 640 // the compile may not be immediately apparent. Wait a
636 // reasonable amount of time before giving up on it. 641 // reasonable amount of time before giving up on it.
637 642
638 if (!File.Exists(OutFile)) 643 if (!File.Exists(assembly))
639 { 644 {
640 for (int i=0; i<20 && !File.Exists(OutFile); i++) 645 for (int i = 0; i < 20 && !File.Exists(assembly); i++)
641 { 646 {
642 System.Threading.Thread.Sleep(250); 647 System.Threading.Thread.Sleep(250);
643 } 648 }
644 // One final chance... 649 // One final chance...
645 if (!File.Exists(OutFile)) 650 if (!File.Exists(assembly))
646 { 651 {
647 errtext = String.Empty; 652 errtext = String.Empty;
648 errtext += "No compile error. But not able to locate compiled file."; 653 errtext += "No compile error. But not able to locate compiled file.";
@@ -650,15 +655,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
650 } 655 }
651 } 656 }
652 657
653// m_log.DebugFormat("[Compiler] Compiled new assembly "+ 658 // m_log.DebugFormat("[Compiler] Compiled new assembly "+
654// "for {0}", asset); 659 // "for {0}", asset);
655 660
656 // Because windows likes to perform exclusive locks, we simply 661 // Because windows likes to perform exclusive locks, we simply
657 // write out a textual representation of the file here 662 // write out a textual representation of the file here
658 // 663 //
659 // Read the binary file into a buffer 664 // Read the binary file into a buffer
660 // 665 //
661 FileInfo fi = new FileInfo(OutFile); 666 FileInfo fi = new FileInfo(assembly);
662 667
663 if (fi == null) 668 if (fi == null)
664 { 669 {
@@ -671,7 +676,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
671 676
672 try 677 try
673 { 678 {
674 FileStream fs = File.Open(OutFile, FileMode.Open, FileAccess.Read); 679 FileStream fs = File.Open(assembly, FileMode.Open, FileAccess.Read);
675 fs.Read(data, 0, data.Length); 680 fs.Read(data, 0, data.Length);
676 fs.Close(); 681 fs.Close();
677 } 682 }
@@ -690,40 +695,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
690 695
691 Byte[] buf = enc.GetBytes(filetext); 696 Byte[] buf = enc.GetBytes(filetext);
692 697
693 FileStream sfs = File.Create(OutFile+".text"); 698 FileStream sfs = File.Create(assembly + ".text");
694 sfs.Write(buf, 0, buf.Length); 699 sfs.Write(buf, 0, buf.Length);
695 sfs.Close(); 700 sfs.Close();
696 701
697 string posmap = String.Empty; 702 return assembly;
698 if (m_positionMap != null)
699 {
700 foreach (KeyValuePair<KeyValuePair<int, int>, KeyValuePair<int, int>> kvp in m_positionMap)
701 {
702 KeyValuePair<int, int> k = kvp.Key;
703 KeyValuePair<int, int> v = kvp.Value;
704 posmap += String.Format("{0},{1},{2},{3}\n",
705 k.Key, k.Value, v.Key, v.Value);
706 }
707 }
708
709 buf = enc.GetBytes(posmap);
710
711 FileStream mfs = File.Create(OutFile+".map");
712 mfs.Write(buf, 0, buf.Length);
713 mfs.Close();
714
715 return OutFile;
716 }
717
718 public KeyValuePair<int, int> FindErrorPosition(int line, int col)
719 {
720 return FindErrorPosition(line, col, m_positionMap);
721 } 703 }
722 704
723 private class kvpSorter : IComparer<KeyValuePair<int,int>> 705 private class kvpSorter : IComparer<KeyValuePair<int, int>>
724 { 706 {
725 public int Compare(KeyValuePair<int,int> a, 707 public int Compare(KeyValuePair<int, int> a,
726 KeyValuePair<int,int> b) 708 KeyValuePair<int, int> b)
727 { 709 {
728 return a.Key.CompareTo(b.Key); 710 return a.Key.CompareTo(b.Key);
729 } 711 }
@@ -742,8 +724,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
742 out ret)) 724 out ret))
743 return ret; 725 return ret;
744 726
745 List<KeyValuePair<int,int>> sorted = 727 List<KeyValuePair<int, int>> sorted =
746 new List<KeyValuePair<int,int>>(positionMap.Keys); 728 new List<KeyValuePair<int, int>>(positionMap.Keys);
747 729
748 sorted.Sort(new kvpSorter()); 730 sorted.Sort(new kvpSorter());
749 731
@@ -791,32 +773,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
791 return message; 773 return message;
792 } 774 }
793 775
794 public Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> LineMap() 776
777 private static void WriteMapFile(string filename, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap)
795 { 778 {
796 if (m_positionMap == null) 779 string mapstring = String.Empty;
797 return null; 780 foreach (KeyValuePair<KeyValuePair<int, int>, KeyValuePair<int, int>> kvp in linemap)
798 781 {
799 Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> ret = 782 KeyValuePair<int, int> k = kvp.Key;
800 new Dictionary<KeyValuePair<int,int>, KeyValuePair<int, int>>(); 783 KeyValuePair<int, int> v = kvp.Value;
801 784 mapstring += String.Format("{0},{1},{2},{3}\n", k.Key, k.Value, v.Key, v.Value);
802 foreach (KeyValuePair<int, int> kvp in m_positionMap.Keys) 785 }
803 ret.Add(kvp, m_positionMap[kvp]); 786
804 787 System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
805 return ret; 788 Byte[] mapbytes = enc.GetBytes(mapstring);
789 FileStream mfs = File.Create(filename);
790 mfs.Write(mapbytes, 0, mapbytes.Length);
791 mfs.Close();
806 } 792 }
807 793
808 private void ReadMapFile(string filename) 794
795 private static Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> ReadMapFile(string filename)
809 { 796 {
797 Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap;
810 try 798 try
811 { 799 {
812 StreamReader r = File.OpenText(filename); 800 StreamReader r = File.OpenText(filename);
801 linemap = new Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>();
813 802
814 m_positionMap = new Dictionary<KeyValuePair<int,int>, KeyValuePair<int, int>>();
815
816 string line; 803 string line;
817 while ((line = r.ReadLine()) != null) 804 while ((line = r.ReadLine()) != null)
818 { 805 {
819 String[] parts = line.Split(new Char[] {','}); 806 String[] parts = line.Split(new Char[] { ',' });
820 int kk = System.Convert.ToInt32(parts[0]); 807 int kk = System.Convert.ToInt32(parts[0]);
821 int kv = System.Convert.ToInt32(parts[1]); 808 int kv = System.Convert.ToInt32(parts[1]);
822 int vk = System.Convert.ToInt32(parts[2]); 809 int vk = System.Convert.ToInt32(parts[2]);
@@ -825,12 +812,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
825 KeyValuePair<int, int> k = new KeyValuePair<int, int>(kk, kv); 812 KeyValuePair<int, int> k = new KeyValuePair<int, int>(kk, kv);
826 KeyValuePair<int, int> v = new KeyValuePair<int, int>(vk, vv); 813 KeyValuePair<int, int> v = new KeyValuePair<int, int>(vk, vv);
827 814
828 m_positionMap[k] = v; 815 linemap[k] = v;
829 } 816 }
830 } 817 }
831 catch 818 catch
832 { 819 {
820 linemap = new Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>();
833 } 821 }
822 return linemap;
834 } 823 }
835 } 824 }
836} 825}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 2b858ec..549c038 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -74,27 +74,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
74 private string m_PrimName; 74 private string m_PrimName;
75 private string m_ScriptName; 75 private string m_ScriptName;
76 private string m_Assembly; 76 private string m_Assembly;
77 private int m_StartParam = 0; 77 private int m_StartParam;
78 private string m_CurrentEvent = String.Empty; 78 private string m_CurrentEvent = String.Empty;
79 private bool m_InSelfDelete = false; 79 private bool m_InSelfDelete;
80 private int m_MaxScriptQueue; 80 private int m_MaxScriptQueue;
81 private bool m_SaveState = true; 81 private bool m_SaveState = true;
82 private bool m_ShuttingDown = false; 82 private bool m_ShuttingDown;
83 private int m_ControlEventsInQueue = 0; 83 private int m_ControlEventsInQueue;
84 private int m_LastControlLevel = 0; 84 private int m_LastControlLevel;
85 private bool m_CollisionInQueue = false; 85 private bool m_CollisionInQueue;
86 private TaskInventoryItem m_thisScriptTask; 86 private TaskInventoryItem m_thisScriptTask;
87 // The following is for setting a minimum delay between events 87 // The following is for setting a minimum delay between events
88 private double m_minEventDelay = 0; 88 private double m_minEventDelay;
89 private long m_eventDelayTicks = 0; 89 private long m_eventDelayTicks;
90 private long m_nextEventTimeTicks = 0; 90 private long m_nextEventTimeTicks;
91 private bool m_startOnInit = true; 91 private bool m_startOnInit = true;
92 private UUID m_AttachedAvatar = UUID.Zero; 92 private UUID m_AttachedAvatar;
93 private StateSource m_stateSource; 93 private StateSource m_stateSource;
94 private bool m_postOnRez; 94 private bool m_postOnRez;
95 private bool m_startedFromSavedState = false; 95 private bool m_startedFromSavedState;
96 private string m_CurrentState = String.Empty; 96 private UUID m_CurrentStateHash;
97 private UUID m_RegionID = UUID.Zero; 97 private UUID m_RegionID;
98 98
99 private Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> 99 private Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>
100 m_LineMap; 100 m_LineMap;
@@ -252,16 +252,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
252 { 252 {
253 m_Apis[api] = am.CreateApi(api); 253 m_Apis[api] = am.CreateApi(api);
254 m_Apis[api].Initialize(engine, part, m_LocalID, itemID); 254 m_Apis[api].Initialize(engine, part, m_LocalID, itemID);
255 } 255 }
256
257 try
258 {
259 if (dom != System.AppDomain.CurrentDomain)
260 m_Script = (IScript)dom.CreateInstanceAndUnwrap(
261 Path.GetFileNameWithoutExtension(assembly),
262 "SecondLife.Script");
263 else
264 m_Script = (IScript)Assembly.Load(
265 Path.GetFileNameWithoutExtension(assembly)).CreateInstance(
266 "SecondLife.Script");
256 267
257 try
258 {
259 m_Script = (IScript)dom.CreateInstanceAndUnwrap(
260 Path.GetFileNameWithoutExtension(assembly),
261 "SecondLife.Script");
262 268
263 //ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 269 //ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
264 RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 270 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
265// lease.Register(this); 271// lease.Register(this);
266 } 272 }
267 catch (Exception) 273 catch (Exception)
@@ -893,7 +899,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
893 899
894 string xml = ScriptSerializer.Serialize(this); 900 string xml = ScriptSerializer.Serialize(this);
895 901
896 if (m_CurrentState != xml) 902 // Compare hash of the state we just just created with the state last written to disk
903 // If the state is different, update the disk file.
904 UUID hash = UUID.Parse(Utils.MD5String(xml));
905
906 if(hash != m_CurrentStateHash)
897 { 907 {
898 try 908 try
899 { 909 {
@@ -911,7 +921,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
911 //{ 921 //{
912 // throw new Exception("Completed persistence save, but no file was created"); 922 // throw new Exception("Completed persistence save, but no file was created");
913 //} 923 //}
914 m_CurrentState = xml; 924 m_CurrentStateHash = hash;
915 } 925 }
916 } 926 }
917 927
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 7b19ce3..b0fce75 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -50,6 +50,9 @@ using OpenSim.Region.ScriptEngine.Shared.CodeTools;
50using OpenSim.Region.ScriptEngine.Shared.Instance; 50using OpenSim.Region.ScriptEngine.Shared.Instance;
51using OpenSim.Region.ScriptEngine.Interfaces; 51using OpenSim.Region.ScriptEngine.Interfaces;
52 52
53using ScriptCompileQueue = OpenSim.Framework.LocklessQueue<object[]>;
54using Parallel = OpenSim.Framework.Parallel;
55
53namespace OpenSim.Region.ScriptEngine.XEngine 56namespace OpenSim.Region.ScriptEngine.XEngine
54{ 57{
55 public class XEngine : INonSharedRegionModule, IScriptModule, IScriptEngine 58 public class XEngine : INonSharedRegionModule, IScriptModule, IScriptEngine
@@ -73,9 +76,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine
73 private bool m_InitialStartup = true; 76 private bool m_InitialStartup = true;
74 private int m_ScriptFailCount; // Number of script fails since compile queue was last empty 77 private int m_ScriptFailCount; // Number of script fails since compile queue was last empty
75 private string m_ScriptErrorMessage; 78 private string m_ScriptErrorMessage;
79 private Dictionary<string, string> m_uniqueScripts = new Dictionary<string, string>();
80 private bool m_AppDomainLoading;
76 81
77// disable warning: need to keep a reference to XEngine.EventManager 82 // disable warning: need to keep a reference to XEngine.EventManager
78// alive to avoid it being garbage collected 83 // alive to avoid it being garbage collected
79#pragma warning disable 414 84#pragma warning disable 414
80 private EventManager m_EventManager; 85 private EventManager m_EventManager;
81#pragma warning restore 414 86#pragma warning restore 414
@@ -114,7 +119,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
114 private Dictionary<UUID, List<UUID> > m_DomainScripts = 119 private Dictionary<UUID, List<UUID> > m_DomainScripts =
115 new Dictionary<UUID, List<UUID> >(); 120 new Dictionary<UUID, List<UUID> >();
116 121
117 private Queue m_CompileQueue = new Queue(100); 122 private ScriptCompileQueue m_CompileQueue = new ScriptCompileQueue();
118 IWorkItemResult m_CurrentCompile = null; 123 IWorkItemResult m_CurrentCompile = null;
119 124
120 public string ScriptEngineName 125 public string ScriptEngineName
@@ -201,6 +206,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
201 m_MaxScriptQueue = m_ScriptConfig.GetInt("MaxScriptEventQueue",300); 206 m_MaxScriptQueue = m_ScriptConfig.GetInt("MaxScriptEventQueue",300);
202 m_StackSize = m_ScriptConfig.GetInt("ThreadStackSize", 262144); 207 m_StackSize = m_ScriptConfig.GetInt("ThreadStackSize", 262144);
203 m_SleepTime = m_ScriptConfig.GetInt("MaintenanceInterval", 10) * 1000; 208 m_SleepTime = m_ScriptConfig.GetInt("MaintenanceInterval", 10) * 1000;
209 m_AppDomainLoading = m_ScriptConfig.GetBoolean("AppDomainLoading", true);
204 210
205 m_EventLimit = m_ScriptConfig.GetInt("EventLimit", 30); 211 m_EventLimit = m_ScriptConfig.GetInt("EventLimit", 30);
206 m_KillTimedOutScripts = m_ScriptConfig.GetBoolean("KillTimedOutScripts", false); 212 m_KillTimedOutScripts = m_ScriptConfig.GetBoolean("KillTimedOutScripts", false);
@@ -470,6 +476,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
470 if (engine != ScriptEngineName) 476 if (engine != ScriptEngineName)
471 return; 477 return;
472 478
479 // If we've seen this exact script text before, use that reference instead
480 if (m_uniqueScripts.ContainsKey(script))
481 script = m_uniqueScripts[script];
482 else
483 m_uniqueScripts[script] = script;
484
473 Object[] parms = new Object[]{localID, itemID, script, startParam, postOnRez, (StateSource)stateSource}; 485 Object[] parms = new Object[]{localID, itemID, script, startParam, postOnRez, (StateSource)stateSource};
474 486
475 if (stateSource == (int)StateSource.ScriptedRez) 487 if (stateSource == (int)StateSource.ScriptedRez)
@@ -478,16 +490,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine
478 } 490 }
479 else 491 else
480 { 492 {
481 lock (m_CompileQueue) 493 m_CompileQueue.Enqueue(parms);
482 {
483 m_CompileQueue.Enqueue(parms);
484 494
485 if (m_CurrentCompile == null) 495 if (m_CurrentCompile == null)
486 { 496 {
487 m_CurrentCompile = m_ThreadPool.QueueWorkItem( 497 m_CurrentCompile = m_ThreadPool.QueueWorkItem(DoOnRezScriptQueue, null);
488 new WorkItemCallback(this.DoOnRezScriptQueue),
489 new Object[0]);
490 }
491 } 498 }
492 } 499 }
493 } 500 }
@@ -498,50 +505,35 @@ namespace OpenSim.Region.ScriptEngine.XEngine
498 { 505 {
499 m_InitialStartup = false; 506 m_InitialStartup = false;
500 System.Threading.Thread.Sleep(15000); 507 System.Threading.Thread.Sleep(15000);
501 lock (m_CompileQueue) 508
509 if (m_CompileQueue.Count == 0)
502 { 510 {
503 if (m_CompileQueue.Count==0) 511 // No scripts on region, so won't get triggered later
504 // No scripts on region, so won't get triggered later 512 // by the queue becoming empty so we trigger it here
505 // by the queue becoming empty so we trigger it here 513 m_Scene.EventManager.TriggerEmptyScriptCompileQueue(0, String.Empty);
506 m_Scene.EventManager.TriggerEmptyScriptCompileQueue(0, String.Empty);
507 } 514 }
508 } 515 }
509 516
510 Object o; 517 List<object[]> compiles = new List<object[]>();
511 lock (m_CompileQueue) 518 object[] o;
519 while (m_CompileQueue.Dequeue(out o))
512 { 520 {
513 o = m_CompileQueue.Dequeue(); 521 compiles.Add(o);
514 if (o == null)
515 {
516 m_CurrentCompile = null;
517 return null;
518 }
519 } 522 }
520 523
521 DoOnRezScript(o); 524 Parallel.For(0, compiles.Count, delegate(int i) { DoOnRezScript(compiles[i]); });
525
526 m_CurrentCompile = null;
527 m_Scene.EventManager.TriggerEmptyScriptCompileQueue(m_ScriptFailCount,
528 m_ScriptErrorMessage);
529 m_ScriptFailCount = 0;
522 530
523 lock (m_CompileQueue)
524 {
525 if (m_CompileQueue.Count > 0)
526 {
527 m_CurrentCompile = m_ThreadPool.QueueWorkItem(
528 new WorkItemCallback(this.DoOnRezScriptQueue),
529 new Object[0]);
530 }
531 else
532 {
533 m_CurrentCompile = null;
534 m_Scene.EventManager.TriggerEmptyScriptCompileQueue(m_ScriptFailCount,
535 m_ScriptErrorMessage);
536 m_ScriptFailCount = 0;
537 }
538 }
539 return null; 531 return null;
540 } 532 }
541 533
542 private bool DoOnRezScript(object parm) 534 private bool DoOnRezScript(object[] parms)
543 { 535 {
544 Object[] p = (Object[])parm; 536 Object[] p = parms;
545 uint localID = (uint)p[0]; 537 uint localID = (uint)p[0];
546 UUID itemID = (UUID)p[1]; 538 UUID itemID = (UUID)p[1];
547 string script =(string)p[2]; 539 string script =(string)p[2];
@@ -590,14 +582,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
590 { 582 {
591 lock (m_AddingAssemblies) 583 lock (m_AddingAssemblies)
592 { 584 {
593 assembly = (string)m_Compiler.PerformScriptCompile(script, 585 m_Compiler.PerformScriptCompile(script, assetID.ToString(), item.OwnerID, out assembly, out linemap);
594 assetID.ToString(), item.OwnerID);
595 if (!m_AddingAssemblies.ContainsKey(assembly)) { 586 if (!m_AddingAssemblies.ContainsKey(assembly)) {
596 m_AddingAssemblies[assembly] = 1; 587 m_AddingAssemblies[assembly] = 1;
597 } else { 588 } else {
598 m_AddingAssemblies[assembly]++; 589 m_AddingAssemblies[assembly]++;
599 } 590 }
600 linemap = m_Compiler.LineMap();
601 } 591 }
602 592
603 string[] warnings = m_Compiler.GetWarnings(); 593 string[] warnings = m_Compiler.GetWarnings();
@@ -696,19 +686,22 @@ namespace OpenSim.Region.ScriptEngine.XEngine
696 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 686 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
697 Evidence evidence = new Evidence(baseEvidence); 687 Evidence evidence = new Evidence(baseEvidence);
698 688
699 AppDomain sandbox = 689 AppDomain sandbox;
700 AppDomain.CreateDomain( 690 if (m_AppDomainLoading)
701 m_Scene.RegionInfo.RegionID.ToString(), 691 sandbox = AppDomain.CreateDomain(
702 evidence, appSetup); 692 m_Scene.RegionInfo.RegionID.ToString(),
703/* 693 evidence, appSetup);
704 PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 694 else
705 AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 695 sandbox = AppDomain.CurrentDomain;
706 PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 696
707 PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 697 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
708 CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 698 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
709 sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 699 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
710 sandbox.SetAppDomainPolicy(sandboxPolicy); 700 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
711*/ 701 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
702 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
703 //sandbox.SetAppDomainPolicy(sandboxPolicy);
704
712 m_AppDomains[appDomain] = sandbox; 705 m_AppDomains[appDomain] = sandbox;
713 706
714 m_AppDomains[appDomain].AssemblyResolve += 707 m_AppDomains[appDomain].AssemblyResolve +=
@@ -905,9 +898,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
905 AppDomain domain = m_AppDomains[id]; 898 AppDomain domain = m_AppDomains[id];
906 m_AppDomains.Remove(id); 899 m_AppDomains.Remove(id);
907 900
908 AppDomain.Unload(domain); 901 if (domain != AppDomain.CurrentDomain)
902 AppDomain.Unload(domain);
909 domain = null; 903 domain = null;
910// m_log.DebugFormat("[XEngine] Unloaded app domain {0}", id.ToString()); 904 // m_log.DebugFormat("[XEngine] Unloaded app domain {0}", id.ToString());
911 } 905 }
912 } 906 }
913 907