aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/Application/Application.cs4
-rw-r--r--OpenSim/Region/Application/OpenSim.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs74
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs29
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs7
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs52
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs9
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs12
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs17
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs24
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs7
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs69
-rw-r--r--OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs11
-rw-r--r--OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs4
-rw-r--r--OpenSim/Region/Framework/Interfaces/INPCModule.cs32
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs12
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs11
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs5
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs21
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs11
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs160
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs433
-rw-r--r--OpenSim/Region/Framework/Scenes/UndoState.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs4
-rw-r--r--OpenSim/Region/OptionalModules/Framework/Monitoring/MonitorServicesModule.cs2
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs5
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs103
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs101
-rw-r--r--OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs12
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsScene.cs4
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs641
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODECharacter.cs10
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs279
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdeScene.cs799
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs2
40 files changed, 1679 insertions, 1309 deletions
diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs
index 3b261e7..c130038 100644
--- a/OpenSim/Region/Application/Application.cs
+++ b/OpenSim/Region/Application/Application.cs
@@ -73,6 +73,7 @@ namespace OpenSim
73 AppDomain.CurrentDomain.UnhandledException += 73 AppDomain.CurrentDomain.UnhandledException +=
74 new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 74 new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
75 75
76
76 // Add the arguments supplied when running the application to the configuration 77 // Add the arguments supplied when running the application to the configuration
77 ArgvConfigSource configSource = new ArgvConfigSource(args); 78 ArgvConfigSource configSource = new ArgvConfigSource(args);
78 79
@@ -91,6 +92,9 @@ namespace OpenSim
91 m_log.Info("[OPENSIM MAIN]: configured log4net using default OpenSim.exe.config"); 92 m_log.Info("[OPENSIM MAIN]: configured log4net using default OpenSim.exe.config");
92 } 93 }
93 94
95 m_log.DebugFormat(
96 "[OPENSIM MAIN]: System Locale is {0}", System.Threading.Thread.CurrentThread.CurrentCulture);
97
94 // Increase the number of IOCP threads available. Mono defaults to a tragically low number 98 // Increase the number of IOCP threads available. Mono defaults to a tragically low number
95 int workerThreads, iocpThreads; 99 int workerThreads, iocpThreads;
96 System.Threading.ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads); 100 System.Threading.ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads);
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index 8add2af..259d753 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -130,7 +130,9 @@ namespace OpenSim
130 //m_log.InfoFormat("[OPENSIM MAIN]: GC Latency Mode: {0}", GCSettings.LatencyMode.ToString()); 130 //m_log.InfoFormat("[OPENSIM MAIN]: GC Latency Mode: {0}", GCSettings.LatencyMode.ToString());
131 131
132 if (m_gui) // Driven by external GUI 132 if (m_gui) // Driven by external GUI
133 {
133 m_console = new CommandConsole("Region"); 134 m_console = new CommandConsole("Region");
135 }
134 else 136 else
135 { 137 {
136 switch (m_consoleType) 138 switch (m_consoleType)
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs
index 14160ae..66b865f 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs
@@ -48,8 +48,8 @@ namespace OpenSim.Region.ClientStack.Linden
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
49 public class BunchOfCapsModule : INonSharedRegionModule 49 public class BunchOfCapsModule : INonSharedRegionModule
50 { 50 {
51 private static readonly ILog m_log = 51// private static readonly ILog m_log =
52 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 52// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53 53
54 private Scene m_Scene; 54 private Scene m_Scene;
55 55
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs
index 29a9199..18c7eae 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs
@@ -48,8 +48,8 @@ namespace OpenSim.Region.ClientStack.Linden
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
49 public class MeshUploadFlagModule : INonSharedRegionModule 49 public class MeshUploadFlagModule : INonSharedRegionModule
50 { 50 {
51 private static readonly ILog m_log = 51// private static readonly ILog m_log =
52 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 52// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53 53
54 /// <summary> 54 /// <summary>
55 /// Is this module enabled? 55 /// Is this module enabled?
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index a34ad62..4a36b5d 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -231,7 +231,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
231 public event ScriptReset OnScriptReset; 231 public event ScriptReset OnScriptReset;
232 public event GetScriptRunning OnGetScriptRunning; 232 public event GetScriptRunning OnGetScriptRunning;
233 public event SetScriptRunning OnSetScriptRunning; 233 public event SetScriptRunning OnSetScriptRunning;
234 public event UpdateVector OnAutoPilotGo; 234 public event Action<Vector3> OnAutoPilotGo;
235 public event TerrainUnacked OnUnackedTerrain; 235 public event TerrainUnacked OnUnackedTerrain;
236 public event ActivateGesture OnActivateGesture; 236 public event ActivateGesture OnActivateGesture;
237 public event DeactivateGesture OnDeactivateGesture; 237 public event DeactivateGesture OnDeactivateGesture;
@@ -5266,6 +5266,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5266 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5266 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5267 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5267 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5268 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5268 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5269
5270 AddGenericPacketHandler("autopilot", HandleAutopilot);
5269 } 5271 }
5270 5272
5271 #region Packet Handlers 5273 #region Packet Handlers
@@ -5308,7 +5310,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5308 ); 5310 );
5309 } 5311 }
5310 else 5312 else
5313 {
5311 update = true; 5314 update = true;
5315 }
5312 5316
5313 // These should be ordered from most-likely to 5317 // These should be ordered from most-likely to
5314 // least likely to change. I've made an initial 5318 // least likely to change. I've made an initial
@@ -5316,6 +5320,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5316 5320
5317 if (update) 5321 if (update)
5318 { 5322 {
5323// m_log.DebugFormat("[LLCLIENTVIEW]: Triggered AgentUpdate for {0}", sener.Name);
5324
5319 AgentUpdateArgs arg = new AgentUpdateArgs(); 5325 AgentUpdateArgs arg = new AgentUpdateArgs();
5320 arg.AgentID = x.AgentID; 5326 arg.AgentID = x.AgentID;
5321 arg.BodyRotation = x.BodyRotation; 5327 arg.BodyRotation = x.BodyRotation;
@@ -11609,55 +11615,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11609 return false; 11615 return false;
11610 } 11616 }
11611 11617
11612 /// <summary> 11618 protected void HandleAutopilot(Object sender, string method, List<String> args)
11613 /// Breaks down the genericMessagePacket into specific events
11614 /// </summary>
11615 /// <param name="gmMethod"></param>
11616 /// <param name="gmInvoice"></param>
11617 /// <param name="gmParams"></param>
11618 public void DecipherGenericMessage(string gmMethod, UUID gmInvoice, GenericMessagePacket.ParamListBlock[] gmParams)
11619 { 11619 {
11620 switch (gmMethod) 11620 float locx = 0;
11621 { 11621 float locy = 0;
11622 case "autopilot": 11622 float locz = 0;
11623 float locx; 11623 uint regionX = 0;
11624 float locy; 11624 uint regionY = 0;
11625 float locz;
11626
11627 try
11628 {
11629 uint regionX;
11630 uint regionY;
11631 Utils.LongToUInts(Scene.RegionInfo.RegionHandle, out regionX, out regionY);
11632 locx = Convert.ToSingle(Utils.BytesToString(gmParams[0].Parameter)) - regionX;
11633 locy = Convert.ToSingle(Utils.BytesToString(gmParams[1].Parameter)) - regionY;
11634 locz = Convert.ToSingle(Utils.BytesToString(gmParams[2].Parameter));
11635 }
11636 catch (InvalidCastException)
11637 {
11638 m_log.Error("[CLIENT]: Invalid autopilot request");
11639 return;
11640 }
11641
11642 UpdateVector handlerAutoPilotGo = OnAutoPilotGo;
11643 if (handlerAutoPilotGo != null)
11644 {
11645 handlerAutoPilotGo(0, new Vector3(locx, locy, locz), this);
11646 }
11647 m_log.InfoFormat("[CLIENT]: Client Requests autopilot to position <{0},{1},{2}>", locx, locy, locz);
11648 11625
11626 Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out regionX, out regionY);
11627 locx = Convert.ToSingle(args[0]) - (float)regionX;
11628 locy = Convert.ToSingle(args[1]) - (float)regionY;
11629 locz = Convert.ToSingle(args[2]);
11649 11630
11650 break; 11631 Action<Vector3> handlerAutoPilotGo = OnAutoPilotGo;
11651 default: 11632 if (handlerAutoPilotGo != null)
11652 m_log.Debug("[CLIENT]: Unknown Generic Message, Method: " + gmMethod + ". Invoice: " + gmInvoice + ". Dumping Params:"); 11633 handlerAutoPilotGo(new Vector3(locx, locy, locz));
11653 for (int hi = 0; hi < gmParams.Length; hi++)
11654 {
11655 Console.WriteLine(gmParams[hi].ToString());
11656 }
11657 //gmpack.MethodData.
11658 break;
11659
11660 }
11661 } 11634 }
11662 11635
11663 /// <summary> 11636 /// <summary>
@@ -12083,7 +12056,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12083 OutPacket(packet, ThrottleOutPacketType.Task); 12056 OutPacket(packet, ThrottleOutPacketType.Task);
12084 } 12057 }
12085 12058
12086 public void SendTextBoxRequest(string message, int chatChannel, string objectname, string ownerFirstName, string ownerLastName, UUID objectId) 12059 public void SendTextBoxRequest(string message, int chatChannel, string objectname, UUID ownerID, string ownerFirstName, string ownerLastName, UUID objectId)
12087 { 12060 {
12088 ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog); 12061 ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog);
12089 dialog.Data.ObjectID = objectId; 12062 dialog.Data.ObjectID = objectId;
@@ -12099,6 +12072,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12099 buttons[0] = new ScriptDialogPacket.ButtonsBlock(); 12072 buttons[0] = new ScriptDialogPacket.ButtonsBlock();
12100 buttons[0].ButtonLabel = Util.StringToBytes256("!!llTextBox!!"); 12073 buttons[0].ButtonLabel = Util.StringToBytes256("!!llTextBox!!");
12101 dialog.Buttons = buttons; 12074 dialog.Buttons = buttons;
12075
12076 dialog.OwnerData = new ScriptDialogPacket.OwnerDataBlock[1];
12077 dialog.OwnerData[0] = new ScriptDialogPacket.OwnerDataBlock();
12078 dialog.OwnerData[0].OwnerID = ownerID;
12079
12102 OutPacket(dialog, ThrottleOutPacketType.Task); 12080 OutPacket(dialog, ThrottleOutPacketType.Task);
12103 } 12081 }
12104 12082
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index aff90c5..f2388cd 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -160,6 +160,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
160 160
161 public Socket Server { get { return null; } } 161 public Socket Server { get { return null; } }
162 162
163 private int m_malformedCount = 0; // Guard against a spamming attack
164
163 public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager) 165 public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager)
164 : base(listenIP, (int)port) 166 : base(listenIP, (int)port)
165 { 167 {
@@ -612,6 +614,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
612 614
613 #region Decoding 615 #region Decoding
614 616
617 if (buffer.DataLength < 7)
618 return; // Drop undersizd packet
619
620 int headerLen = 7;
621 if (buffer.Data[6] == 0xFF)
622 {
623 if (buffer.Data[7] == 0xFF)
624 headerLen = 10;
625 else
626 headerLen = 8;
627 }
628
629 if (buffer.DataLength < headerLen)
630 return; // Malformed header
631
615 try 632 try
616 { 633 {
617 packet = Packet.BuildPacket(buffer.Data, ref packetEnd, 634 packet = Packet.BuildPacket(buffer.Data, ref packetEnd,
@@ -621,6 +638,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
621 catch (MalformedDataException) 638 catch (MalformedDataException)
622 { 639 {
623 } 640 }
641 catch (IndexOutOfRangeException)
642 {
643 return; // Drop short packet
644 }
645 catch(Exception e)
646 {
647 if (m_malformedCount < 100)
648 m_log.DebugFormat("[LLUDPSERVER]: Dropped malformed packet: " + e.ToString());
649 m_malformedCount++;
650 if ((m_malformedCount % 100000) == 0)
651 m_log.DebugFormat("[LLUDPSERVER]: Received {0} malformed packets so far, probable network attack.", m_malformedCount);
652 }
624 653
625 // Fail-safe check 654 // Fail-safe check
626 if (packet == null) 655 if (packet == null)
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
index 29fd1a4..4c33db5 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
@@ -44,7 +44,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 private static Int32 m_counter = 0; 45 private static Int32 m_counter = 0;
46 46
47 private Int32 m_identifier; 47// private Int32 m_identifier;
48 48
49 /// <summary> 49 /// <summary>
50 /// Number of ticks (ms) per quantum, drip rate and max burst 50 /// Number of ticks (ms) per quantum, drip rate and max burst
@@ -173,7 +173,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
173 /// second. If zero, the bucket always remains full</param> 173 /// second. If zero, the bucket always remains full</param>
174 public TokenBucket(TokenBucket parent, Int64 dripRate) 174 public TokenBucket(TokenBucket parent, Int64 dripRate)
175 { 175 {
176 m_identifier = m_counter++; 176// m_identifier = m_counter++;
177 m_counter++;
177 178
178 Parent = parent; 179 Parent = parent;
179 RequestedDripRate = dripRate; 180 RequestedDripRate = dripRate;
@@ -320,7 +321,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
320 321
321 public class AdaptiveTokenBucket : TokenBucket 322 public class AdaptiveTokenBucket : TokenBucket
322 { 323 {
323 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 324// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
324 325
325 /// <summary> 326 /// <summary>
326 /// The minimum rate for flow control. Minimum drip rate is one 327 /// The minimum rate for flow control. Minimum drip rate is one
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index 2b3f7f5..da39202 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -301,7 +301,9 @@ namespace Flotsam.RegionModules.AssetCache
301 } 301 }
302 catch (Exception e) 302 catch (Exception e)
303 { 303 {
304 LogException(e); 304 m_log.ErrorFormat(
305 "[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
306 asset.ID, e.Message, e.StackTrace);
305 } 307 }
306 } 308 }
307 309
@@ -361,7 +363,9 @@ namespace Flotsam.RegionModules.AssetCache
361 } 363 }
362 catch (System.Runtime.Serialization.SerializationException e) 364 catch (System.Runtime.Serialization.SerializationException e)
363 { 365 {
364 LogException(e); 366 m_log.ErrorFormat(
367 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
368 filename, id, e.Message, e.StackTrace);
365 369
366 // If there was a problem deserializing the asset, the asset may 370 // If there was a problem deserializing the asset, the asset may
367 // either be corrupted OR was serialized under an old format 371 // either be corrupted OR was serialized under an old format
@@ -371,7 +375,9 @@ namespace Flotsam.RegionModules.AssetCache
371 } 375 }
372 catch (Exception e) 376 catch (Exception e)
373 { 377 {
374 LogException(e); 378 m_log.ErrorFormat(
379 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
380 filename, id, e.Message, e.StackTrace);
375 } 381 }
376 finally 382 finally
377 { 383 {
@@ -380,7 +386,6 @@ namespace Flotsam.RegionModules.AssetCache
380 } 386 }
381 } 387 }
382 388
383
384#if WAIT_ON_INPROGRESS_REQUESTS 389#if WAIT_ON_INPROGRESS_REQUESTS
385 // Check if we're already downloading this asset. If so, try to wait for it to 390 // Check if we're already downloading this asset. If so, try to wait for it to
386 // download. 391 // download.
@@ -403,7 +408,6 @@ namespace Flotsam.RegionModules.AssetCache
403 m_RequestsForInprogress++; 408 m_RequestsForInprogress++;
404 } 409 }
405#endif 410#endif
406
407 return asset; 411 return asset;
408 } 412 }
409 413
@@ -415,7 +419,7 @@ namespace Flotsam.RegionModules.AssetCache
415 419
416 if (m_MemoryCacheEnabled) 420 if (m_MemoryCacheEnabled)
417 asset = GetFromMemoryCache(id); 421 asset = GetFromMemoryCache(id);
418 else if (m_FileCacheEnabled) 422 if (asset == null && m_FileCacheEnabled)
419 asset = GetFromFileCache(id); 423 asset = GetFromFileCache(id);
420 424
421 if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0)) 425 if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0))
@@ -432,7 +436,6 @@ namespace Flotsam.RegionModules.AssetCache
432 } 436 }
433 437
434 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0} unnessesary requests due to requests for assets that are currently downloading.", m_RequestsForInprogress); 438 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0} unnessesary requests due to requests for assets that are currently downloading.", m_RequestsForInprogress);
435
436 } 439 }
437 440
438 return asset; 441 return asset;
@@ -446,7 +449,7 @@ namespace Flotsam.RegionModules.AssetCache
446 public void Expire(string id) 449 public void Expire(string id)
447 { 450 {
448 if (m_LogLevel >= 2) 451 if (m_LogLevel >= 2)
449 m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Expiring Asset {0}.", id); 452 m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Expiring Asset {0}", id);
450 453
451 try 454 try
452 { 455 {
@@ -464,7 +467,9 @@ namespace Flotsam.RegionModules.AssetCache
464 } 467 }
465 catch (Exception e) 468 catch (Exception e)
466 { 469 {
467 LogException(e); 470 m_log.ErrorFormat(
471 "[FLOTSAM ASSET CACHE]: Failed to expire cached file {0}. Exception {1} {2}",
472 id, e.Message, e.StackTrace);
468 } 473 }
469 } 474 }
470 475
@@ -602,7 +607,9 @@ namespace Flotsam.RegionModules.AssetCache
602 } 607 }
603 catch (Exception e) 608 catch (Exception e)
604 { 609 {
605 LogException(e); 610 m_log.ErrorFormat(
611 "[FLOTSAM ASSET CACHE]: Failed to write asset {0} to cache. Directory {1}, tempname {2}, filename {3}. Exception {4} {5}.",
612 asset.ID, directory, tempname, filename, e.Message, e.StackTrace);
606 } 613 }
607 finally 614 finally
608 { 615 {
@@ -632,15 +639,6 @@ namespace Flotsam.RegionModules.AssetCache
632 } 639 }
633 } 640 }
634 641
635 private static void LogException(Exception e)
636 {
637 string[] text = e.ToString().Split(new char[] { '\n' });
638 foreach (string t in text)
639 {
640 m_log.ErrorFormat("[FLOTSAM ASSET CACHE]: {0} ", t);
641 }
642 }
643
644 /// <summary> 642 /// <summary>
645 /// Scan through the file cache, and return number of assets currently cached. 643 /// Scan through the file cache, and return number of assets currently cached.
646 /// </summary> 644 /// </summary>
@@ -693,8 +691,7 @@ namespace Flotsam.RegionModules.AssetCache
693 s.ForEachSOG(delegate(SceneObjectGroup e) 691 s.ForEachSOG(delegate(SceneObjectGroup e)
694 { 692 {
695 gatherer.GatherAssetUuids(e, assets); 693 gatherer.GatherAssetUuids(e, assets);
696 } 694 });
697 );
698 } 695 }
699 696
700 foreach (UUID assetID in assets.Keys) 697 foreach (UUID assetID in assets.Keys)
@@ -727,7 +724,9 @@ namespace Flotsam.RegionModules.AssetCache
727 } 724 }
728 catch (Exception e) 725 catch (Exception e)
729 { 726 {
730 LogException(e); 727 m_log.ErrorFormat(
728 "[FLOTSAM ASSET CACHE]: Couldn't clear asset cache directory {0} from {1}. Exception {2} {3}",
729 dir, m_CacheDirectory, e.Message, e.StackTrace);
731 } 730 }
732 } 731 }
733 732
@@ -739,7 +738,9 @@ namespace Flotsam.RegionModules.AssetCache
739 } 738 }
740 catch (Exception e) 739 catch (Exception e)
741 { 740 {
742 LogException(e); 741 m_log.ErrorFormat(
742 "[FLOTSAM ASSET CACHE]: Couldn't clear asset cache file {0} from {1}. Exception {1} {2}",
743 file, m_CacheDirectory, e.Message, e.StackTrace);
743 } 744 }
744 } 745 }
745 } 746 }
@@ -765,7 +766,7 @@ namespace Flotsam.RegionModules.AssetCache
765 766
766 foreach (string s in Directory.GetFiles(m_CacheDirectory, "*.fac")) 767 foreach (string s in Directory.GetFiles(m_CacheDirectory, "*.fac"))
767 { 768 {
768 m_log.Info("[FLOTSAM ASSET CACHE]: Deep Scans were performed on the following regions:"); 769 m_log.Info("[FLOTSAM ASSET CACHE]: Deep scans have previously been performed on the following regions:");
769 770
770 string RegionID = s.Remove(0,s.IndexOf("_")).Replace(".fac",""); 771 string RegionID = s.Remove(0,s.IndexOf("_")).Replace(".fac","");
771 DateTime RegionDeepScanTMStamp = File.GetLastWriteTime(s); 772 DateTime RegionDeepScanTMStamp = File.GetLastWriteTime(s);
@@ -836,7 +837,6 @@ namespace Flotsam.RegionModules.AssetCache
836 Util.FireAndForget(delegate { 837 Util.FireAndForget(delegate {
837 int assetsCached = CacheScenes(); 838 int assetsCached = CacheScenes();
838 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Completed Scene Caching, {0} assets found.", assetsCached); 839 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Completed Scene Caching, {0} assets found.", assetsCached);
839
840 }); 840 });
841 841
842 break; 842 break;
@@ -891,7 +891,6 @@ namespace Flotsam.RegionModules.AssetCache
891 891
892 #region IAssetService Members 892 #region IAssetService Members
893 893
894
895 public AssetMetadata GetMetadata(string id) 894 public AssetMetadata GetMetadata(string id)
896 { 895 {
897 AssetBase asset = Get(id); 896 AssetBase asset = Get(id);
@@ -921,7 +920,6 @@ namespace Flotsam.RegionModules.AssetCache
921 Cache(asset); 920 Cache(asset);
922 921
923 return asset.ID; 922 return asset.ID;
924
925 } 923 }
926 924
927 public bool UpdateContent(string id, byte[] data) 925 public bool UpdateContent(string id, byte[] data)
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index 995a552..e3e3452 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -151,6 +151,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
151 if (face == null) 151 if (face == null)
152 continue; 152 continue;
153 153
154// m_log.DebugFormat(
155// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
156// face.TextureID, idx, client.Name, client.AgentId);
157
154 // if the texture is one of the "defaults" then skip it 158 // if the texture is one of the "defaults" then skip it
155 // this should probably be more intelligent (skirt texture doesnt matter 159 // this should probably be more intelligent (skirt texture doesnt matter
156 // if the avatar isnt wearing a skirt) but if any of the main baked 160 // if the avatar isnt wearing a skirt) but if any of the main baked
@@ -305,6 +309,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
305 309
306 private void HandleAppearanceSave(UUID agentid) 310 private void HandleAppearanceSave(UUID agentid)
307 { 311 {
312 // We must set appearance parameters in the en_US culture in order to avoid issues where values are saved
313 // in a culture where decimal points are commas and then reloaded in a culture which just treats them as
314 // number seperators.
315 Culture.SetCurrentCulture();
316
308 ScenePresence sp = m_scene.GetScenePresence(agentid); 317 ScenePresence sp = m_scene.GetScenePresence(agentid);
309 if (sp == null) 318 if (sp == null)
310 { 319 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
index 0db31eb..36fe040 100644
--- a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
@@ -141,10 +141,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
141 { 141 {
142 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, ownerid); 142 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, ownerid);
143 string ownerFirstName, ownerLastName; 143 string ownerFirstName, ownerLastName;
144 UUID ownerID = UUID.Zero;
144 if (account != null) 145 if (account != null)
145 { 146 {
146 ownerFirstName = account.FirstName; 147 ownerFirstName = account.FirstName;
147 ownerLastName = account.LastName; 148 ownerLastName = account.LastName;
149 ownerID = account.PrincipalID;
148 } 150 }
149 else 151 else
150 { 152 {
@@ -155,7 +157,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
155 ScenePresence sp = m_scene.GetScenePresence(avatarid); 157 ScenePresence sp = m_scene.GetScenePresence(avatarid);
156 158
157 if (sp != null) 159 if (sp != null)
158 sp.ControllingClient.SendTextBoxRequest(message, chatChannel, name, ownerFirstName, ownerLastName, objectid); 160 sp.ControllingClient.SendTextBoxRequest(message, chatChannel, name, ownerID, ownerFirstName, ownerLastName, objectid);
159 } 161 }
160 162
161 public void SendNotificationToUsersInRegion( 163 public void SendNotificationToUsersInRegion(
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index b714f2b..4933147 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -984,11 +984,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
984 public virtual bool CanGetAgentInventoryItem(IClientAPI remoteClient, UUID itemID, UUID requestID) 984 public virtual bool CanGetAgentInventoryItem(IClientAPI remoteClient, UUID itemID, UUID requestID)
985 { 985 {
986 InventoryItemBase assetRequestItem = GetItem(remoteClient.AgentId, itemID); 986 InventoryItemBase assetRequestItem = GetItem(remoteClient.AgentId, itemID);
987
987 if (assetRequestItem == null) 988 if (assetRequestItem == null)
988 { 989 {
989 ILibraryService lib = m_Scene.RequestModuleInterface<ILibraryService>(); 990 ILibraryService lib = m_Scene.RequestModuleInterface<ILibraryService>();
991
990 if (lib != null) 992 if (lib != null)
991 assetRequestItem = lib.LibraryRootFolder.FindItem(itemID); 993 assetRequestItem = lib.LibraryRootFolder.FindItem(itemID);
994
992 if (assetRequestItem == null) 995 if (assetRequestItem == null)
993 return false; 996 return false;
994 } 997 }
@@ -1019,6 +1022,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
1019 m_log.WarnFormat( 1022 m_log.WarnFormat(
1020 "[CLIENT]: {0} requested asset {1} from item {2} but this does not match item's asset {3}", 1023 "[CLIENT]: {0} requested asset {1} from item {2} but this does not match item's asset {3}",
1021 Name, requestID, itemID, assetRequestItem.AssetID); 1024 Name, requestID, itemID, assetRequestItem.AssetID);
1025
1022 return false; 1026 return false;
1023 } 1027 }
1024 1028
diff --git a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
index d570608..3155ce7 100644
--- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
@@ -185,6 +185,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library
185 archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, "/", iarFileName, false); 185 archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, "/", iarFileName, false);
186 archread.Execute(); 186 archread.Execute();
187 } 187 }
188
188 foreach (InventoryNodeBase node in nodes) 189 foreach (InventoryNodeBase node in nodes)
189 FixPerms(node); 190 FixPerms(node);
190 } 191 }
@@ -197,18 +198,19 @@ namespace OpenSim.Region.CoreModules.Framework.Library
197 archread.Close(); 198 archread.Close();
198 } 199 }
199 } 200 }
200
201 } 201 }
202 202
203 private void FixPerms(InventoryNodeBase node) 203 private void FixPerms(InventoryNodeBase node)
204 { 204 {
205 m_log.DebugFormat("[LIBRARY MODULE]: Fixing perms for {0} {1}", node.Name, node.ID);
206
205 if (node is InventoryItemBase) 207 if (node is InventoryItemBase)
206 { 208 {
207 InventoryItemBase item = (InventoryItemBase)node; 209 InventoryItemBase item = (InventoryItemBase)node;
208 item.BasePermissions = 0x7FFFFFFF; 210 item.BasePermissions = (uint)PermissionMask.All;
209 item.EveryOnePermissions = 0x7FFFFFFF; 211 item.EveryOnePermissions = (uint)PermissionMask.All - (uint)PermissionMask.Modify;
210 item.CurrentPermissions = 0x7FFFFFFF; 212 item.CurrentPermissions = (uint)PermissionMask.All;
211 item.NextPermissions = 0x7FFFFFFF; 213 item.NextPermissions = (uint)PermissionMask.All;
212 } 214 }
213 } 215 }
214 216
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs
index 85a1ac3..18a7177 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs
@@ -39,8 +39,7 @@ using OpenMetaverse;
39 39
40namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization 40namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
41{ 41{
42 public class LocalAuthorizationServicesConnector : 42 public class LocalAuthorizationServicesConnector : ISharedRegionModule, IAuthorizationService
43 ISharedRegionModule, IAuthorizationService
44 { 43 {
45 private static readonly ILog m_log = 44 private static readonly ILog m_log =
46 LogManager.GetLogger( 45 LogManager.GetLogger(
@@ -127,15 +126,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
127 if (!m_Enabled) 126 if (!m_Enabled)
128 return; 127 return;
129 128
130 m_log.InfoFormat("[AUTHORIZATION CONNECTOR]: Enabled local authorization for region {0}", scene.RegionInfo.RegionName); 129 m_log.InfoFormat(
131 130 "[AUTHORIZATION CONNECTOR]: Enabled local authorization for region {0}",
132 131 scene.RegionInfo.RegionName);
133 } 132 }
134 133
135 public bool IsAuthorizedForRegion(string userID, string regionID, out string message) 134 public bool IsAuthorizedForRegion(
135 string userID, string firstName, string lastName, string regionID, out string message)
136 { 136 {
137 return m_AuthorizationService.IsAuthorizedForRegion(userID, regionID, out message); 137 return m_AuthorizationService.IsAuthorizedForRegion(userID, firstName, lastName, regionID, out message);
138 } 138 }
139
140 } 139 }
141} 140} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs
index 66994fa..5fa27b8 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs
@@ -117,12 +117,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
117 117
118 } 118 }
119 119
120 public bool IsAuthorizedForRegion(string userID, string regionID, out string message) 120 public bool IsAuthorizedForRegion(
121 string userID, string firstName, string lastName, string regionID, out string message)
121 { 122 {
122 m_log.InfoFormat("[REMOTE AUTHORIZATION CONNECTOR]: IsAuthorizedForRegion checking {0} for region {1}", userID, regionID); 123 m_log.InfoFormat(
124 "[REMOTE AUTHORIZATION CONNECTOR]: IsAuthorizedForRegion checking {0} for region {1}", userID, regionID);
123 125
124 bool isAuthorized = true; 126 bool isAuthorized = true;
125 message = String.Empty; 127 message = String.Empty;
128 string mail = String.Empty;
126 129
127 // get the scene this call is being made for 130 // get the scene this call is being made for
128 Scene scene = null; 131 Scene scene = null;
@@ -140,17 +143,22 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
140 if (scene != null) 143 if (scene != null)
141 { 144 {
142 UserAccount account = scene.UserAccountService.GetUserAccount(UUID.Zero, new UUID(userID)); 145 UserAccount account = scene.UserAccountService.GetUserAccount(UUID.Zero, new UUID(userID));
143 isAuthorized = IsAuthorizedForRegion(userID, account.FirstName, account.LastName, 146
144 account.Email, scene.RegionInfo.RegionName, regionID, out message); 147 if (account != null)
148 mail = account.Email;
149
150 isAuthorized
151 = IsAuthorizedForRegion(
152 userID, firstName, lastName, account.Email, scene.RegionInfo.RegionName, regionID, out message);
145 } 153 }
146 else 154 else
147 { 155 {
148 m_log.ErrorFormat("[REMOTE AUTHORIZATION CONNECTOR] IsAuthorizedForRegion, can't find scene to match region id of {0} ",regionID); 156 m_log.ErrorFormat(
157 "[REMOTE AUTHORIZATION CONNECTOR] IsAuthorizedForRegion, can't find scene to match region id of {0}",
158 regionID);
149 } 159 }
150 160
151
152 return isAuthorized; 161 return isAuthorized;
153
154 } 162 }
155 } 163 }
156} 164} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs
index c044407..cd7d6bc 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs
@@ -64,10 +64,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests
64 } 64 }
65 65
66 /// <summary> 66 /// <summary>
67 /// Test saving a V0.2 OpenSim Region Archive. 67 /// Test region registration.
68 /// </summary> 68 /// </summary>
69 [Test] 69 [Test]
70 public void TestRegisterRegionV0_2() 70 public void TestRegisterRegion()
71 { 71 {
72 SetUp(); 72 SetUp();
73 73
@@ -123,6 +123,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests
123 m_LocalConnector.RegisterRegion(UUID.Zero, r1); 123 m_LocalConnector.RegisterRegion(UUID.Zero, r1);
124 124
125 GridRegion result = m_LocalConnector.GetRegionByName(UUID.Zero, "Test"); 125 GridRegion result = m_LocalConnector.GetRegionByName(UUID.Zero, "Test");
126 Assert.IsNull(result, "Retrieved GetRegionByName \"Test\" is not null");
127
128 result = m_LocalConnector.GetRegionByName(UUID.Zero, "Test Region 1");
126 Assert.IsNotNull(result, "Retrieved GetRegionByName is null"); 129 Assert.IsNotNull(result, "Retrieved GetRegionByName is null");
127 Assert.That(result.RegionName, Is.EqualTo("Test Region 1"), "Retrieved region's name does not match"); 130 Assert.That(result.RegionName, Is.EqualTo("Test Region 1"), "Retrieved region's name does not match");
128 131
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index 63dec15..7554e12 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -470,53 +470,48 @@ namespace OpenSim.Region.CoreModules.World.Land
470 SendLandUpdate(avatar, false); 470 SendLandUpdate(avatar, false);
471 } 471 }
472 472
473 public void EventManagerOnSignificantClientMovement(IClientAPI remote_client) 473 public void EventManagerOnSignificantClientMovement(ScenePresence clientAvatar)
474 { 474 {
475 ScenePresence clientAvatar = m_scene.GetScenePresence(remote_client.AgentId); 475 SendLandUpdate(clientAvatar);
476 476 SendOutNearestBanLine(clientAvatar.ControllingClient);
477 if (clientAvatar != null) 477 ILandObject parcel = GetLandObject(clientAvatar.AbsolutePosition.X, clientAvatar.AbsolutePosition.Y);
478 if (parcel != null)
478 { 479 {
479 SendLandUpdate(clientAvatar); 480 if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT &&
480 SendOutNearestBanLine(remote_client); 481 clientAvatar.sentMessageAboutRestrictedParcelFlyingDown)
481 ILandObject parcel = GetLandObject(clientAvatar.AbsolutePosition.X, clientAvatar.AbsolutePosition.Y);
482 if (parcel != null)
483 { 482 {
484 if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT && 483 EventManagerOnAvatarEnteringNewParcel(clientAvatar, parcel.LandData.LocalID,
485 clientAvatar.sentMessageAboutRestrictedParcelFlyingDown) 484 m_scene.RegionInfo.RegionID);
485 //They are going under the safety line!
486 if (!parcel.IsBannedFromLand(clientAvatar.UUID))
486 { 487 {
487 EventManagerOnAvatarEnteringNewParcel(clientAvatar, parcel.LandData.LocalID, 488 clientAvatar.sentMessageAboutRestrictedParcelFlyingDown = false;
488 m_scene.RegionInfo.RegionID);
489 //They are going under the safety line!
490 if (!parcel.IsBannedFromLand(clientAvatar.UUID))
491 {
492 clientAvatar.sentMessageAboutRestrictedParcelFlyingDown = false;
493 }
494 } 489 }
495 else if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT && 490 }
496 parcel.IsBannedFromLand(clientAvatar.UUID)) 491 else if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT &&
492 parcel.IsBannedFromLand(clientAvatar.UUID))
493 {
494 //once we've sent the message once, keep going toward the target until we are done
495 if (forcedPosition.ContainsKey(clientAvatar.ControllingClient.AgentId))
497 { 496 {
498 //once we've sent the message once, keep going toward the target until we are done 497 SendYouAreBannedNotice(clientAvatar);
499 if (forcedPosition.ContainsKey(clientAvatar.ControllingClient.AgentId)) 498 ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar));
500 {
501 SendYouAreBannedNotice(clientAvatar);
502 ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar));
503 }
504 } 499 }
505 else if (parcel.IsRestrictedFromLand(clientAvatar.UUID)) 500 }
506 { 501 else if (parcel.IsRestrictedFromLand(clientAvatar.UUID))
507 //once we've sent the message once, keep going toward the target until we are done 502 {
508 if (forcedPosition.ContainsKey(clientAvatar.ControllingClient.AgentId)) 503 //once we've sent the message once, keep going toward the target until we are done
509 { 504 if (forcedPosition.ContainsKey(clientAvatar.ControllingClient.AgentId))
510 SendYouAreRestrictedNotice(clientAvatar);
511 ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar));
512 }
513 }
514 else
515 { 505 {
516 //when we are finally in a safe place, lets release the forced position lock 506 SendYouAreRestrictedNotice(clientAvatar);
517 forcedPosition.Remove(clientAvatar.ControllingClient.AgentId); 507 ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar));
518 } 508 }
519 } 509 }
510 else
511 {
512 //when we are finally in a safe place, lets release the forced position lock
513 forcedPosition.Remove(clientAvatar.ControllingClient.AgentId);
514 }
520 } 515 }
521 } 516 }
522 517
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index a40517c..7cb3751 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -146,7 +146,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
146 = ParseUserSetConfigSetting(myConfig, "allowed_script_editors", m_allowedScriptEditors); 146 = ParseUserSetConfigSetting(myConfig, "allowed_script_editors", m_allowedScriptEditors);
147 147
148 if (m_bypassPermissions) 148 if (m_bypassPermissions)
149 m_log.Info("[PERMISSIONS]: serviceside_object_permissions = false in ini file so disabling all region service permission checks"); 149 m_log.Info("[PERMISSIONS]: serverside_object_permissions = false in ini file so disabling all region service permission checks");
150 else 150 else
151 m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks"); 151 m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks");
152 152
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
index 2e3b21f..3804017 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
@@ -96,16 +96,7 @@ m_log.DebugFormat("MAP NAME=({0})", mapName);
96 96
97 // try to fetch from GridServer 97 // try to fetch from GridServer
98 List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); 98 List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20);
99 if (regionInfos == null) 99 if (regionInfos.Count == 0)
100 {
101 m_log.Warn("[MAPSEARCHMODULE]: RequestNamedRegions returned null. Old gridserver?");
102 // service wasn't available; maybe still an old GridServer. Try the old API, though it will return only one region
103 regionInfos = new List<GridRegion>();
104 GridRegion info = m_scene.GridService.GetRegionByName(m_scene.RegionInfo.ScopeID, mapName);
105 if (info != null)
106 regionInfos.Add(info);
107 }
108 else if (regionInfos.Count == 0)
109 remoteClient.SendAlertMessage("Hyperlink could not be established."); 100 remoteClient.SendAlertMessage("Hyperlink could not be established.");
110 101
111 m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions. Flags={2}", mapName, regionInfos.Count, flags); 102 m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions. Flags={2}", mapName, regionInfos.Count, flags);
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
index 56b46d7..4f58ab0 100644
--- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
+++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
@@ -222,7 +222,7 @@ namespace OpenSim.Region.Examples.SimpleModule
222 public event ScriptReset OnScriptReset; 222 public event ScriptReset OnScriptReset;
223 public event GetScriptRunning OnGetScriptRunning; 223 public event GetScriptRunning OnGetScriptRunning;
224 public event SetScriptRunning OnSetScriptRunning; 224 public event SetScriptRunning OnSetScriptRunning;
225 public event UpdateVector OnAutoPilotGo; 225 public event Action<Vector3> OnAutoPilotGo;
226 226
227 public event TerrainUnacked OnUnackedTerrain; 227 public event TerrainUnacked OnUnackedTerrain;
228 228
@@ -1152,7 +1152,7 @@ namespace OpenSim.Region.Examples.SimpleModule
1152 { 1152 {
1153 } 1153 }
1154 1154
1155 public void SendTextBoxRequest(string message, int chatChannel, string objectname, string ownerFirstName, string ownerLastName, UUID objectId) 1155 public void SendTextBoxRequest(string message, int chatChannel, string objectname, UUID ownerID, string ownerFirstName, string ownerLastName, UUID objectId)
1156 { 1156 {
1157 } 1157 }
1158 1158
diff --git a/OpenSim/Region/Framework/Interfaces/INPCModule.cs b/OpenSim/Region/Framework/Interfaces/INPCModule.cs
index 21a755f..fa8d6b6 100644
--- a/OpenSim/Region/Framework/Interfaces/INPCModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/INPCModule.cs
@@ -32,9 +32,39 @@ namespace OpenSim.Region.Framework.Interfaces
32{ 32{
33 public interface INPCModule 33 public interface INPCModule
34 { 34 {
35 /// <summary>
36 /// Create an NPC
37 /// </summary>
38 /// <param name="firstname"></param>
39 /// <param name="lastname"></param>
40 /// <param name="position"></param>
41 /// <param name="scene"></param>
42 /// <param name="cloneAppearanceFrom">The UUID of the avatar from which to clone the NPC's appearance from.</param>
43 /// <returns>The UUID of the ScenePresence created.</returns>
35 UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, UUID cloneAppearanceFrom); 44 UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, UUID cloneAppearanceFrom);
36 void Autopilot(UUID agentID, Scene scene, Vector3 pos); 45
46 /// <summary>
47 /// Move an NPC to a target over time.
48 /// </summary>
49 /// <param name="agentID">The UUID of the NPC</param>
50 /// <param name="scene"></param>
51 /// <param name="pos"></param>
52 void MoveToTarget(UUID agentID, Scene scene, Vector3 pos);
53
54 /// <summary>
55 /// Get the NPC to say something.
56 /// </summary>
57 /// <param name="agentID">The UUID of the NPC</param>
58 /// <param name="scene"></param>
59 /// <param name="text"></param>
37 void Say(UUID agentID, Scene scene, string text); 60 void Say(UUID agentID, Scene scene, string text);
61
62
63 /// <summary>
64 /// Delete an NPC.
65 /// </summary>
66 /// <param name="agentID">The UUID of the NPC</param>
67 /// <param name="scene"></param>
38 void DeleteNPC(UUID agentID, Scene scene); 68 void DeleteNPC(UUID agentID, Scene scene);
39 } 69 }
40} \ No newline at end of file 70} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index 4865481..4ab818f 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -27,6 +27,8 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection;
31using log4net;
30using OpenMetaverse; 32using OpenMetaverse;
31using OpenSim.Framework; 33using OpenSim.Framework;
32using OpenSim.Region.Framework.Interfaces; 34using OpenSim.Region.Framework.Interfaces;
@@ -40,6 +42,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation
40 /// </summary> 42 /// </summary>
41 public class ScenePresenceAnimator 43 public class ScenePresenceAnimator
42 { 44 {
45// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46
43 public AnimationSet Animations 47 public AnimationSet Animations
44 { 48 {
45 get { return m_animations; } 49 get { return m_animations; }
@@ -262,7 +266,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
262 266
263 m_animTickFall = 0; 267 m_animTickFall = 0;
264 268
265 if (move.Z > 0f) 269 if (move.Z > 0.2f)
266 { 270 {
267 // Jumping 271 // Jumping
268 if (!jumping) 272 if (!jumping)
@@ -295,7 +299,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
295 if (move.X != 0f || move.Y != 0f) 299 if (move.X != 0f || move.Y != 0f)
296 { 300 {
297 // Walking / crouchwalking / running 301 // Walking / crouchwalking / running
298 if (move.Z < 0f) 302 if (move.Z < 0)
299 return "CROUCHWALK"; 303 return "CROUCHWALK";
300 else if (m_scenePresence.SetAlwaysRun) 304 else if (m_scenePresence.SetAlwaysRun)
301 return "RUN"; 305 return "RUN";
@@ -305,7 +309,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
305 else 309 else
306 { 310 {
307 // Not walking 311 // Not walking
308 if (move.Z < 0f) 312 if (move.Z < 0)
309 return "CROUCH"; 313 return "CROUCH";
310 else 314 else
311 return "STAND"; 315 return "STAND";
@@ -323,6 +327,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation
323 public void UpdateMovementAnimations() 327 public void UpdateMovementAnimations()
324 { 328 {
325 m_movementAnimation = GetMovementAnimation(); 329 m_movementAnimation = GetMovementAnimation();
330// m_log.DebugFormat(
331// "[SCENE PRESENCE ANIMATOR]: Got animation {0} for {1}", m_movementAnimation, m_scenePresence.Name);
326 TrySetMovementAnimation(m_movementAnimation); 332 TrySetMovementAnimation(m_movementAnimation);
327 } 333 }
328 334
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index b67937d..96da2c3 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -165,8 +165,7 @@ namespace OpenSim.Region.Framework.Scenes
165 public delegate void AvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID); 165 public delegate void AvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID);
166 public event AvatarEnteringNewParcel OnAvatarEnteringNewParcel; 166 public event AvatarEnteringNewParcel OnAvatarEnteringNewParcel;
167 167
168 public delegate void SignificantClientMovement(IClientAPI remote_client); 168 public event Action<ScenePresence> OnSignificantClientMovement;
169 public event SignificantClientMovement OnSignificantClientMovement;
170 169
171 public delegate void IncomingInstantMessage(GridInstantMessage message); 170 public delegate void IncomingInstantMessage(GridInstantMessage message);
172 public event IncomingInstantMessage OnIncomingInstantMessage; 171 public event IncomingInstantMessage OnIncomingInstantMessage;
@@ -1592,16 +1591,16 @@ namespace OpenSim.Region.Framework.Scenes
1592 } 1591 }
1593 } 1592 }
1594 1593
1595 public void TriggerSignificantClientMovement(IClientAPI client) 1594 public void TriggerSignificantClientMovement(ScenePresence presence)
1596 { 1595 {
1597 SignificantClientMovement handlerSignificantClientMovement = OnSignificantClientMovement; 1596 Action<ScenePresence> handlerSignificantClientMovement = OnSignificantClientMovement;
1598 if (handlerSignificantClientMovement != null) 1597 if (handlerSignificantClientMovement != null)
1599 { 1598 {
1600 foreach (SignificantClientMovement d in handlerSignificantClientMovement.GetInvocationList()) 1599 foreach (Action<ScenePresence> d in handlerSignificantClientMovement.GetInvocationList())
1601 { 1600 {
1602 try 1601 try
1603 { 1602 {
1604 d(client); 1603 d(presence);
1605 } 1604 }
1606 catch (Exception e) 1605 catch (Exception e)
1607 { 1606 {
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 30421d4..afc1a4f 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -724,7 +724,10 @@ namespace OpenSim.Region.Framework.Scenes
724 newName = item.Name; 724 newName = item.Name;
725 } 725 }
726 726
727 if (remoteClient.AgentId == oldAgentID || (LibraryService != null && LibraryService.LibraryRootFolder != null && oldAgentID == LibraryService.LibraryRootFolder.Owner)) 727 if (remoteClient.AgentId == oldAgentID
728 || (LibraryService != null
729 && LibraryService.LibraryRootFolder != null
730 && oldAgentID == LibraryService.LibraryRootFolder.Owner))
728 { 731 {
729 CreateNewInventoryItem( 732 CreateNewInventoryItem(
730 remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType, 733 remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType,
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 32a2887..b3b6cbc 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -3079,7 +3079,7 @@ namespace OpenSim.Region.Framework.Scenes
3079 if (aCircuit == null) 3079 if (aCircuit == null)
3080 { 3080 {
3081 m_log.DebugFormat("[APPEARANCE] Client did not supply a circuit. Non-Linden? Creating default appearance."); 3081 m_log.DebugFormat("[APPEARANCE] Client did not supply a circuit. Non-Linden? Creating default appearance.");
3082 appearance = new AvatarAppearance(client.AgentId); 3082 appearance = new AvatarAppearance();
3083 return; 3083 return;
3084 } 3084 }
3085 3085
@@ -3087,7 +3087,7 @@ namespace OpenSim.Region.Framework.Scenes
3087 if (appearance == null) 3087 if (appearance == null)
3088 { 3088 {
3089 m_log.DebugFormat("[APPEARANCE]: Appearance not found in {0}, returning default", RegionInfo.RegionName); 3089 m_log.DebugFormat("[APPEARANCE]: Appearance not found in {0}, returning default", RegionInfo.RegionName);
3090 appearance = new AvatarAppearance(client.AgentId); 3090 appearance = new AvatarAppearance();
3091 } 3091 }
3092 } 3092 }
3093 3093
@@ -3553,11 +3553,12 @@ namespace OpenSim.Region.Framework.Scenes
3553 3553
3554 if (AuthorizationService != null) 3554 if (AuthorizationService != null)
3555 { 3555 {
3556 if (!AuthorizationService.IsAuthorizedForRegion(agent.AgentID.ToString(), RegionInfo.RegionID.ToString(),out reason)) 3556 if (!AuthorizationService.IsAuthorizedForRegion(
3557 agent.AgentID.ToString(), agent.firstname, agent.lastname, RegionInfo.RegionID.ToString(), out reason))
3557 { 3558 {
3558 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region", 3559 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region",
3559 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3560 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
3560 //reason = String.Format("You are not currently on the access list for {0}",RegionInfo.RegionName); 3561
3561 return false; 3562 return false;
3562 } 3563 }
3563 } 3564 }
@@ -3880,8 +3881,11 @@ namespace OpenSim.Region.Framework.Scenes
3880 } 3881 }
3881 3882
3882 /// <summary> 3883 /// <summary>
3883 /// Tries to teleport agent to other region. 3884 /// Tries to teleport agent to another region.
3884 /// </summary> 3885 /// </summary>
3886 /// <remarks>
3887 /// The region name must exactly match that given.
3888 /// </remarks>
3885 /// <param name="remoteClient"></param> 3889 /// <param name="remoteClient"></param>
3886 /// <param name="regionName"></param> 3890 /// <param name="regionName"></param>
3887 /// <param name="position"></param> 3891 /// <param name="position"></param>
@@ -3890,15 +3894,16 @@ namespace OpenSim.Region.Framework.Scenes
3890 public void RequestTeleportLocation(IClientAPI remoteClient, string regionName, Vector3 position, 3894 public void RequestTeleportLocation(IClientAPI remoteClient, string regionName, Vector3 position,
3891 Vector3 lookat, uint teleportFlags) 3895 Vector3 lookat, uint teleportFlags)
3892 { 3896 {
3893 List<GridRegion> regions = GridService.GetRegionsByName(RegionInfo.ScopeID, regionName, 1); 3897 GridRegion region = GridService.GetRegionByName(RegionInfo.ScopeID, regionName);
3894 if (regions == null || regions.Count == 0) 3898
3899 if (region == null)
3895 { 3900 {
3896 // can't find the region: Tell viewer and abort 3901 // can't find the region: Tell viewer and abort
3897 remoteClient.SendTeleportFailed("The region '" + regionName + "' could not be found."); 3902 remoteClient.SendTeleportFailed("The region '" + regionName + "' could not be found.");
3898 return; 3903 return;
3899 } 3904 }
3900 3905
3901 RequestTeleportLocation(remoteClient, regions[0].RegionHandle, position, lookat, teleportFlags); 3906 RequestTeleportLocation(remoteClient, region.RegionHandle, position, lookat, teleportFlags);
3902 } 3907 }
3903 3908
3904 /// <summary> 3909 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index b6fb5a4..57baa99 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -1650,16 +1650,7 @@ namespace OpenSim.Region.Framework.Scenes
1650 ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar); 1650 ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar);
1651 if (avatar != null) 1651 if (avatar != null)
1652 { 1652 {
1653 List<string> coords = new List<string>(); 1653 avatar.MoveToTarget(target);
1654 uint regionX = 0;
1655 uint regionY = 0;
1656 Utils.LongToUInts(Scene.RegionInfo.RegionHandle, out regionX, out regionY);
1657 target.X += regionX;
1658 target.Y += regionY;
1659 coords.Add(target.X.ToString());
1660 coords.Add(target.Y.ToString());
1661 coords.Add(target.Z.ToString());
1662 avatar.DoMoveToPosition(avatar, "", coords);
1663 } 1654 }
1664 } 1655 }
1665 else 1656 else
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 4629757..90ad34e 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -1038,7 +1038,7 @@ namespace OpenSim.Region.Framework.Scenes
1038 { 1038 {
1039 actor.Size = m_shape.Scale; 1039 actor.Size = m_shape.Scale;
1040 1040
1041 if (((OpenMetaverse.SculptType)Shape.SculptType) == SculptType.Mesh) 1041 if (Shape.SculptEntry)
1042 CheckSculptAndLoad(); 1042 CheckSculptAndLoad();
1043 else 1043 else
1044 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); 1044 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
@@ -1751,96 +1751,111 @@ namespace OpenSim.Region.Framework.Scenes
1751 return part; 1751 return part;
1752 } 1752 }
1753 1753
1754 public void DoPhysicsPropertyUpdate(bool UsePhysics, bool isNew) 1754 /// <summary>
1755 /// Do a physics property update for a NINJA joint.
1756 /// </summary>
1757 /// <param name="UsePhysics"></param>
1758 /// <param name="isNew"></param>
1759 protected void DoPhysicsPropertyUpdateForNinjaJoint(bool UsePhysics, bool isNew)
1755 { 1760 {
1756 if (IsJoint()) 1761 if (UsePhysics)
1757 { 1762 {
1758 if (UsePhysics) 1763 // by turning a joint proxy object physical, we cause creation of a joint in the ODE scene.
1759 { 1764 // note that, as a special case, joints have no bodies or geoms in the physics scene, even though they are physical.
1760 // by turning a joint proxy object physical, we cause creation of a joint in the ODE scene.
1761 // note that, as a special case, joints have no bodies or geoms in the physics scene, even though they are physical.
1762 1765
1763 PhysicsJointType jointType; 1766 PhysicsJointType jointType;
1764 if (IsHingeJoint()) 1767 if (IsHingeJoint())
1765 { 1768 {
1766 jointType = PhysicsJointType.Hinge; 1769 jointType = PhysicsJointType.Hinge;
1767 } 1770 }
1768 else if (IsBallJoint()) 1771 else if (IsBallJoint())
1769 { 1772 {
1770 jointType = PhysicsJointType.Ball; 1773 jointType = PhysicsJointType.Ball;
1771 } 1774 }
1772 else 1775 else
1773 { 1776 {
1774 jointType = PhysicsJointType.Ball; 1777 jointType = PhysicsJointType.Ball;
1775 } 1778 }
1776 1779
1777 List<string> bodyNames = new List<string>(); 1780 List<string> bodyNames = new List<string>();
1778 string RawParams = Description; 1781 string RawParams = Description;
1779 string[] jointParams = RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries); 1782 string[] jointParams = RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries);
1780 string trackedBodyName = null; 1783 string trackedBodyName = null;
1781 if (jointParams.Length >= 2) 1784 if (jointParams.Length >= 2)
1785 {
1786 for (int iBodyName = 0; iBodyName < 2; iBodyName++)
1782 { 1787 {
1783 for (int iBodyName = 0; iBodyName < 2; iBodyName++) 1788 string bodyName = jointParams[iBodyName];
1789 bodyNames.Add(bodyName);
1790 if (bodyName != "NULL")
1784 { 1791 {
1785 string bodyName = jointParams[iBodyName]; 1792 if (trackedBodyName == null)
1786 bodyNames.Add(bodyName);
1787 if (bodyName != "NULL")
1788 { 1793 {
1789 if (trackedBodyName == null) 1794 trackedBodyName = bodyName;
1790 {
1791 trackedBodyName = bodyName;
1792 }
1793 } 1795 }
1794 } 1796 }
1795 } 1797 }
1798 }
1796 1799
1797 SceneObjectPart trackedBody = m_parentGroup.Scene.GetSceneObjectPart(trackedBodyName); // FIXME: causes a sequential lookup 1800 SceneObjectPart trackedBody = m_parentGroup.Scene.GetSceneObjectPart(trackedBodyName); // FIXME: causes a sequential lookup
1798 Quaternion localRotation = Quaternion.Identity; 1801 Quaternion localRotation = Quaternion.Identity;
1799 if (trackedBody != null) 1802 if (trackedBody != null)
1800 { 1803 {
1801 localRotation = Quaternion.Inverse(trackedBody.RotationOffset) * this.RotationOffset; 1804 localRotation = Quaternion.Inverse(trackedBody.RotationOffset) * this.RotationOffset;
1802 } 1805 }
1803 else 1806 else
1804 { 1807 {
1805 // error, output it below 1808 // error, output it below
1806 } 1809 }
1807 1810
1808 PhysicsJoint joint; 1811 PhysicsJoint joint;
1809 1812
1810 joint = m_parentGroup.Scene.PhysicsScene.RequestJointCreation(Name, jointType, 1813 joint = m_parentGroup.Scene.PhysicsScene.RequestJointCreation(Name, jointType,
1811 AbsolutePosition, 1814 AbsolutePosition,
1812 this.RotationOffset, 1815 this.RotationOffset,
1813 Description, 1816 Description,
1814 bodyNames, 1817 bodyNames,
1815 trackedBodyName, 1818 trackedBodyName,
1816 localRotation); 1819 localRotation);
1817 1820
1818 if (trackedBody == null) 1821 if (trackedBody == null)
1819 { 1822 {
1820 ParentGroup.Scene.jointErrorMessage(joint, "warning: tracked body name not found! joint location will not be updated properly. joint: " + Name); 1823 ParentGroup.Scene.jointErrorMessage(joint, "warning: tracked body name not found! joint location will not be updated properly. joint: " + Name);
1821 } 1824 }
1825 }
1826 else
1827 {
1828 if (isNew)
1829 {
1830 // if the joint proxy is new, and it is not physical, do nothing. There is no joint in ODE to
1831 // delete, and if we try to delete it, due to asynchronous processing, the deletion request
1832 // will get processed later at an indeterminate time, which could cancel a later-arriving
1833 // joint creation request.
1822 } 1834 }
1823 else 1835 else
1824 { 1836 {
1825 if (isNew) 1837 // here we turn off the joint object, so remove the joint from the physics scene
1826 { 1838 m_parentGroup.Scene.PhysicsScene.RequestJointDeletion(Name); // FIXME: what if the name changed?
1827 // if the joint proxy is new, and it is not physical, do nothing. There is no joint in ODE to
1828 // delete, and if we try to delete it, due to asynchronous processing, the deletion request
1829 // will get processed later at an indeterminate time, which could cancel a later-arriving
1830 // joint creation request.
1831 }
1832 else
1833 {
1834 // here we turn off the joint object, so remove the joint from the physics scene
1835 m_parentGroup.Scene.PhysicsScene.RequestJointDeletion(Name); // FIXME: what if the name changed?
1836 1839
1837 // make sure client isn't interpolating the joint proxy object 1840 // make sure client isn't interpolating the joint proxy object
1838 Velocity = Vector3.Zero; 1841 Velocity = Vector3.Zero;
1839 AngularVelocity = Vector3.Zero; 1842 AngularVelocity = Vector3.Zero;
1840 Acceleration = Vector3.Zero; 1843 Acceleration = Vector3.Zero;
1841 }
1842 } 1844 }
1843 } 1845 }
1846 }
1847
1848 /// <summary>
1849 /// Do a physics propery update for this part.
1850 /// </summary>
1851 /// <param name="UsePhysics"></param>
1852 /// <param name="isNew"></param>
1853 public void DoPhysicsPropertyUpdate(bool UsePhysics, bool isNew)
1854 {
1855 if (IsJoint())
1856 {
1857 DoPhysicsPropertyUpdateForNinjaJoint(UsePhysics, isNew);
1858 }
1844 else 1859 else
1845 { 1860 {
1846 if (PhysActor != null) 1861 if (PhysActor != null)
@@ -1906,7 +1921,7 @@ namespace OpenSim.Region.Framework.Scenes
1906 1921
1907 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the 1922 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the
1908 // mesh data. 1923 // mesh data.
1909 if (((OpenMetaverse.SculptType)Shape.SculptType) == SculptType.Mesh) 1924 if (Shape.SculptEntry)
1910 CheckSculptAndLoad(); 1925 CheckSculptAndLoad();
1911 else 1926 else
1912 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); 1927 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
@@ -4821,7 +4836,6 @@ namespace OpenSim.Region.Framework.Scenes
4821 { 4836 {
4822 PhysActor.OnCollisionUpdate += PhysicsCollision; 4837 PhysActor.OnCollisionUpdate += PhysicsCollision;
4823 PhysActor.SubscribeEvents(1000); 4838 PhysActor.SubscribeEvents(1000);
4824
4825 } 4839 }
4826 } 4840 }
4827 else 4841 else
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 83b761c..d354c0a 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -89,6 +89,13 @@ namespace OpenSim.Region.Framework.Scenes
89 /// </summary> 89 /// </summary>
90 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); 90 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f);
91 91
92 /// <summary>
93 /// Movement updates for agents in neighboring regions are sent directly to clients.
94 /// This value only affects how often agent positions are sent to neighbor regions
95 /// for things such as distance-based update prioritization
96 /// </summary>
97 public static readonly float SIGNIFICANT_MOVEMENT = 2.0f;
98
92 public UUID currentParcelUUID = UUID.Zero; 99 public UUID currentParcelUUID = UUID.Zero;
93 100
94 private ISceneViewer m_sceneViewer; 101 private ISceneViewer m_sceneViewer;
@@ -116,7 +123,7 @@ namespace OpenSim.Region.Framework.Scenes
116 private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO; 123 private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO;
117 private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO; 124 private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO;
118 private bool MouseDown = false; 125 private bool MouseDown = false;
119 private SceneObjectGroup proxyObjectGroup; 126// private SceneObjectGroup proxyObjectGroup;
120 //private SceneObjectPart proxyObjectPart = null; 127 //private SceneObjectPart proxyObjectPart = null;
121 public Vector3 lastKnownAllowedPosition; 128 public Vector3 lastKnownAllowedPosition;
122 public bool sentMessageAboutRestrictedParcelFlyingDown; 129 public bool sentMessageAboutRestrictedParcelFlyingDown;
@@ -210,8 +217,8 @@ namespace OpenSim.Region.Framework.Scenes
210 private string m_nextSitAnimation = String.Empty; 217 private string m_nextSitAnimation = String.Empty;
211 218
212 //PauPaw:Proper PID Controler for autopilot************ 219 //PauPaw:Proper PID Controler for autopilot************
213 private bool m_moveToPositionInProgress; 220 public bool MovingToTarget { get; private set; }
214 private Vector3 m_moveToPositionTarget; 221 public Vector3 MoveToPositionTarget { get; private set; }
215 222
216 private bool m_followCamAuto; 223 private bool m_followCamAuto;
217 224
@@ -779,8 +786,7 @@ namespace OpenSim.Region.Framework.Scenes
779 m_controllingClient.OnStartAnim += HandleStartAnim; 786 m_controllingClient.OnStartAnim += HandleStartAnim;
780 m_controllingClient.OnStopAnim += HandleStopAnim; 787 m_controllingClient.OnStopAnim += HandleStopAnim;
781 m_controllingClient.OnForceReleaseControls += HandleForceReleaseControls; 788 m_controllingClient.OnForceReleaseControls += HandleForceReleaseControls;
782 m_controllingClient.OnAutoPilotGo += DoAutoPilot; 789 m_controllingClient.OnAutoPilotGo += MoveToTarget;
783 m_controllingClient.AddGenericPacketHandler("autopilot", DoMoveToPosition);
784 790
785 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); 791 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange);
786 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); 792 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement);
@@ -916,7 +922,7 @@ namespace OpenSim.Region.Framework.Scenes
916 { 922 {
917 m_log.ErrorFormat("[SCENE PRESENCE]: null appearance in MakeRoot in {0}", Scene.RegionInfo.RegionName); 923 m_log.ErrorFormat("[SCENE PRESENCE]: null appearance in MakeRoot in {0}", Scene.RegionInfo.RegionName);
918 // emergency; this really shouldn't happen 924 // emergency; this really shouldn't happen
919 m_appearance = new AvatarAppearance(UUID); 925 m_appearance = new AvatarAppearance();
920 } 926 }
921 927
922 AddToPhysicalScene(isFlying); 928 AddToPhysicalScene(isFlying);
@@ -1076,13 +1082,6 @@ namespace OpenSim.Region.Framework.Scenes
1076 SendTerseUpdateToAllClients(); 1082 SendTerseUpdateToAllClients();
1077 } 1083 }
1078 1084
1079 /// <summary>
1080 ///
1081 /// </summary>
1082 public void StopMovement()
1083 {
1084 }
1085
1086 public void StopFlying() 1085 public void StopFlying()
1087 { 1086 {
1088 ControllingClient.StopFlying(this); 1087 ControllingClient.StopFlying(this);
@@ -1378,15 +1377,15 @@ namespace OpenSim.Region.Framework.Scenes
1378 { 1377 {
1379 return; 1378 return;
1380 } 1379 }
1381
1382 bool update_movementflag = false;
1383 1380
1384 if (m_allowMovement && !SitGround) 1381 if (m_allowMovement && !SitGround)
1385 { 1382 {
1383 bool update_movementflag = false;
1384
1386 if (agentData.UseClientAgentPosition) 1385 if (agentData.UseClientAgentPosition)
1387 { 1386 {
1388 m_moveToPositionInProgress = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f; 1387 MovingToTarget = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f;
1389 m_moveToPositionTarget = agentData.ClientAgentPosition; 1388 MoveToPositionTarget = agentData.ClientAgentPosition;
1390 } 1389 }
1391 1390
1392 int i = 0; 1391 int i = 0;
@@ -1417,7 +1416,6 @@ namespace OpenSim.Region.Framework.Scenes
1417 if (m_parentID == 0) 1416 if (m_parentID == 0)
1418 { 1417 {
1419 bool bAllowUpdateMoveToPosition = false; 1418 bool bAllowUpdateMoveToPosition = false;
1420 bool bResetMoveToPosition = false;
1421 1419
1422 Vector3[] dirVectors; 1420 Vector3[] dirVectors;
1423 1421
@@ -1430,13 +1428,14 @@ namespace OpenSim.Region.Framework.Scenes
1430 1428
1431 // The fact that m_movementflag is a byte needs to be fixed 1429 // The fact that m_movementflag is a byte needs to be fixed
1432 // it really should be a uint 1430 // it really should be a uint
1431 // A DIR_CONTROL_FLAG occurs when the user is trying to move in a particular direction.
1433 uint nudgehack = 250; 1432 uint nudgehack = 250;
1434 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1433 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1435 { 1434 {
1436 if (((uint)flags & (uint)DCF) != 0) 1435 if (((uint)flags & (uint)DCF) != 0)
1437 { 1436 {
1438 bResetMoveToPosition = true;
1439 DCFlagKeyPressed = true; 1437 DCFlagKeyPressed = true;
1438
1440 try 1439 try
1441 { 1440 {
1442 agent_control_v3 += dirVectors[i]; 1441 agent_control_v3 += dirVectors[i];
@@ -1480,97 +1479,22 @@ namespace OpenSim.Region.Framework.Scenes
1480 bAllowUpdateMoveToPosition = true; 1479 bAllowUpdateMoveToPosition = true;
1481 } 1480 }
1482 } 1481 }
1483 i++;
1484 }
1485 1482
1486 //Paupaw:Do Proper PID for Autopilot here 1483 i++;
1487 if (bResetMoveToPosition)
1488 {
1489 m_moveToPositionTarget = Vector3.Zero;
1490 m_moveToPositionInProgress = false;
1491 update_movementflag = true;
1492 bAllowUpdateMoveToPosition = false;
1493 } 1484 }
1494 1485
1495 if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving)) 1486 if (MovingToTarget)
1496 { 1487 {
1497 //Check the error term of the current position in relation to the target position 1488 // If the user has pressed a key then we want to cancel any move to target.
1498 if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f) 1489 if (DCFlagKeyPressed)
1499 { 1490 {
1500 // we are close enough to the target 1491 ResetMoveToTarget();
1501 m_moveToPositionTarget = Vector3.Zero;
1502 m_moveToPositionInProgress = false;
1503 update_movementflag = true; 1492 update_movementflag = true;
1504 } 1493 }
1505 else 1494 else if (bAllowUpdateMoveToPosition)
1506 { 1495 {
1507 try 1496 if (HandleMoveToTargetUpdate(ref agent_control_v3, bodyRotation))
1508 { 1497 update_movementflag = true;
1509 // move avatar in 2D at one meter/second towards target, in avatar coordinate frame.
1510 // This movement vector gets added to the velocity through AddNewMovement().
1511 // Theoretically we might need a more complex PID approach here if other
1512 // unknown forces are acting on the avatar and we need to adaptively respond
1513 // to such forces, but the following simple approach seems to works fine.
1514 Vector3 LocalVectorToTarget3D =
1515 (m_moveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
1516 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords
1517 // Ignore z component of vector
1518 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1519 LocalVectorToTarget2D.Normalize();
1520 agent_control_v3 += LocalVectorToTarget2D;
1521
1522 // update avatar movement flags. the avatar coordinate system is as follows:
1523 //
1524 // +X (forward)
1525 //
1526 // ^
1527 // |
1528 // |
1529 // |
1530 // |
1531 // (left) +Y <--------o--------> -Y
1532 // avatar
1533 // |
1534 // |
1535 // |
1536 // |
1537 // v
1538 // -X
1539 //
1540
1541 // based on the above avatar coordinate system, classify the movement into
1542 // one of left/right/back/forward.
1543 if (LocalVectorToTarget2D.Y > 0)//MoveLeft
1544 {
1545 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
1546 //AgentControlFlags
1547 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
1548 update_movementflag = true;
1549 }
1550 else if (LocalVectorToTarget2D.Y < 0) //MoveRight
1551 {
1552 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
1553 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
1554 update_movementflag = true;
1555 }
1556 if (LocalVectorToTarget2D.X < 0) //MoveBack
1557 {
1558 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
1559 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
1560 update_movementflag = true;
1561 }
1562 else if (LocalVectorToTarget2D.X > 0) //Move Forward
1563 {
1564 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
1565 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
1566 update_movementflag = true;
1567 }
1568 }
1569 catch (Exception e)
1570 {
1571 //Avoid system crash, can be slower but...
1572 m_log.DebugFormat("Crash! {0}", e.ToString());
1573 }
1574 } 1498 }
1575 } 1499 }
1576 } 1500 }
@@ -1608,74 +1532,208 @@ namespace OpenSim.Region.Framework.Scenes
1608 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1532 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1609 1533
1610 AddNewMovement(agent_control_v3, q); 1534 AddNewMovement(agent_control_v3, q);
1611
1612
1613 } 1535 }
1614 }
1615 1536
1616 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1537 if (update_movementflag
1617 Animator.UpdateMovementAnimations(); 1538 && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0)
1539 && (m_parentID == 0)
1540 && !SitGround)
1541 Animator.UpdateMovementAnimations();
1542 }
1618 1543
1619 m_scene.EventManager.TriggerOnClientMovement(this); 1544 m_scene.EventManager.TriggerOnClientMovement(this);
1620 1545
1621 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 1546 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
1622 } 1547 }
1623 1548
1624 public void DoAutoPilot(uint not_used, Vector3 Pos, IClientAPI remote_client) 1549 /// <summary>
1550 /// Calculate an update to move the presence to the set target.
1551 /// </summary>
1552 /// <remarks>
1553 /// This doesn't actually perform the movement. Instead, it adds its vector to agent_control_v3.
1554 /// </remarks>
1555 /// <param value="agent_control_v3">Cumulative agent movement that this method will update.</param>
1556 /// <param value="bodyRotation">New body rotation of the avatar.</param>
1557 /// <returns>True if movement has been updated in some way. False otherwise.</returns>
1558 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3, Quaternion bodyRotation)
1625 { 1559 {
1626 m_autopilotMoving = true; 1560// m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name);
1627 m_autoPilotTarget = Pos;
1628 m_sitAtAutoTarget = false;
1629 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1630 //proxy.PCode = (byte)PCode.ParticleSystem;
1631 1561
1632 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1562 bool updated = false;
1633 proxyObjectGroup.AttachToScene(m_scene);
1634
1635 // Commented out this code since it could never have executed, but might still be informative.
1636// if (proxyObjectGroup != null)
1637// {
1638 proxyObjectGroup.SendGroupFullUpdate();
1639 remote_client.SendSitResponse(proxyObjectGroup.UUID, Vector3.Zero, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false);
1640 m_scene.DeleteSceneObject(proxyObjectGroup, false);
1641// }
1642// else
1643// {
1644// m_autopilotMoving = false;
1645// m_autoPilotTarget = Vector3.Zero;
1646// ControllingClient.SendAlertMessage("Autopilot cancelled");
1647// }
1648 }
1649 1563
1650 public void DoMoveToPosition(Object sender, string method, List<String> args) 1564// m_log.DebugFormat(
1651 { 1565// "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}",
1652 try 1566// allowUpdate, m_moveToPositionInProgress, m_autopilotMoving);
1567
1568 if (!m_autopilotMoving)
1653 { 1569 {
1654 float locx = 0f; 1570 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget);
1655 float locy = 0f; 1571// m_log.DebugFormat(
1656 float locz = 0f; 1572// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}",
1657 uint regionX = 0; 1573// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget);
1658 uint regionY = 0; 1574
1659 try 1575 // Check the error term of the current position in relation to the target position
1576 if (distanceToTarget <= 1)
1660 { 1577 {
1661 Utils.LongToUInts(Scene.RegionInfo.RegionHandle, out regionX, out regionY); 1578 // We are close enough to the target
1662 locx = Convert.ToSingle(args[0]) - (float)regionX; 1579 AbsolutePosition = MoveToPositionTarget;
1663 locy = Convert.ToSingle(args[1]) - (float)regionY; 1580 ResetMoveToTarget();
1664 locz = Convert.ToSingle(args[2]); 1581 updated = true;
1665 } 1582 }
1666 catch (InvalidCastException) 1583 else
1667 { 1584 {
1668 m_log.Error("[CLIENT]: Invalid autopilot request"); 1585 try
1669 return; 1586 {
1587 // move avatar in 3D at one meter/second towards target, in avatar coordinate frame.
1588 // This movement vector gets added to the velocity through AddNewMovement().
1589 // Theoretically we might need a more complex PID approach here if other
1590 // unknown forces are acting on the avatar and we need to adaptively respond
1591 // to such forces, but the following simple approach seems to works fine.
1592 Vector3 LocalVectorToTarget3D =
1593 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
1594 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords
1595 // Ignore z component of vector
1596// Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1597 LocalVectorToTarget3D.Normalize();
1598
1599 // update avatar movement flags. the avatar coordinate system is as follows:
1600 //
1601 // +X (forward)
1602 //
1603 // ^
1604 // |
1605 // |
1606 // |
1607 // |
1608 // (left) +Y <--------o--------> -Y
1609 // avatar
1610 // |
1611 // |
1612 // |
1613 // |
1614 // v
1615 // -X
1616 //
1617
1618 // based on the above avatar coordinate system, classify the movement into
1619 // one of left/right/back/forward.
1620 if (LocalVectorToTarget3D.X < 0) //MoveBack
1621 {
1622 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
1623 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
1624 updated = true;
1625 }
1626 else if (LocalVectorToTarget3D.X > 0) //Move Forward
1627 {
1628 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
1629 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
1630 updated = true;
1631 }
1632
1633 if (LocalVectorToTarget3D.Y > 0) //MoveLeft
1634 {
1635 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
1636 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
1637 updated = true;
1638 }
1639 else if (LocalVectorToTarget3D.Y < 0) //MoveRight
1640 {
1641 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
1642 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
1643 updated = true;
1644 }
1645
1646 if (LocalVectorToTarget3D.Z > 0) //Up
1647 {
1648 // Don't set these flags for up or down - doing so will make the avatar crouch or
1649 // keep trying to jump even if walking along level ground
1650 //m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP;
1651 //AgentControlFlags
1652 //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP;
1653 updated = true;
1654 }
1655 else if (LocalVectorToTarget3D.Z < 0) //Down
1656 {
1657 //m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN;
1658 //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN;
1659 updated = true;
1660 }
1661
1662// m_log.DebugFormat(
1663// "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}",
1664// LocalVectorToTarget3D, agent_control_v3, Name);
1665
1666 agent_control_v3 += LocalVectorToTarget3D;
1667 }
1668 catch (Exception e)
1669 {
1670 //Avoid system crash, can be slower but...
1671 m_log.DebugFormat("Crash! {0}", e.ToString());
1672 }
1670 } 1673 }
1671 m_moveToPositionInProgress = true;
1672 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1673 }
1674 catch (Exception ex)
1675 {
1676 //Why did I get this error?
1677 m_log.Error("[SCENEPRESENCE]: DoMoveToPosition" + ex);
1678 } 1674 }
1675
1676 return updated;
1677 }
1678
1679 /// <summary>
1680 /// Move to the given target over time.
1681 /// </summary>
1682 /// <param name="pos"></param>
1683 public void MoveToTarget(Vector3 pos)
1684 {
1685// m_log.DebugFormat(
1686// "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}",
1687// Name, pos, m_scene.RegionInfo.RegionName);
1688
1689 if (pos.X < 0 || pos.X >= Constants.RegionSize
1690 || pos.Y < 0 || pos.Y >= Constants.RegionSize
1691 || pos.Z < 0)
1692 return;
1693
1694// Vector3 heightAdjust = new Vector3(0, 0, Appearance.AvatarHeight / 2);
1695// pos += heightAdjust;
1696//
1697// // Anti duck-walking measure
1698// if (Math.Abs(pos.Z - AbsolutePosition.Z) < 0.2f)
1699// {
1700//// m_log.DebugFormat("[SCENE PRESENCE]: Adjusting MoveToPosition from {0} to {1}", pos, AbsolutePosition);
1701// pos.Z = AbsolutePosition.Z;
1702// }
1703
1704 float terrainHeight = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
1705 pos.Z = Math.Max(terrainHeight, pos.Z);
1706
1707 // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is
1708 // always slightly higher than the actual terrain height.
1709 // FIXME: This constrains NOC movements as well, so should be somewhere else.
1710 if (pos.Z - terrainHeight < 0.2)
1711 pos.Z = terrainHeight;
1712
1713 m_log.DebugFormat(
1714 "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}",
1715 Name, pos, terrainHeight, m_scene.RegionInfo.RegionName);
1716
1717 if (pos.Z > terrainHeight)
1718 PhysicsActor.Flying = true;
1719
1720 MovingToTarget = true;
1721 MoveToPositionTarget = pos;
1722
1723 Vector3 agent_control_v3 = new Vector3();
1724 HandleMoveToTargetUpdate(ref agent_control_v3, Rotation);
1725 AddNewMovement(agent_control_v3, Rotation);
1726 }
1727
1728 /// <summary>
1729 /// Reset the move to target.
1730 /// </summary>
1731 public void ResetMoveToTarget()
1732 {
1733 m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
1734
1735 MovingToTarget = false;
1736 MoveToPositionTarget = Vector3.Zero;
1679 } 1737 }
1680 1738
1681 private void CheckAtSitTarget() 1739 private void CheckAtSitTarget()
@@ -1832,7 +1890,7 @@ namespace OpenSim.Region.Framework.Scenes
1832 bool forceMouselook = false; 1890 bool forceMouselook = false;
1833 1891
1834 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1892 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1835 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1893 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1836 if (part != null) 1894 if (part != null)
1837 { 1895 {
1838 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1896 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
@@ -1908,14 +1966,23 @@ namespace OpenSim.Region.Framework.Scenes
1908 HandleAgentSit(remoteClient, UUID); 1966 HandleAgentSit(remoteClient, UUID);
1909 } 1967 }
1910 1968
1969 // public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset, string sitAnimation)
1911 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset) 1970 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset)
1912 { 1971 {
1913 if (m_parentID != 0) 1972 if (m_parentID != 0)
1914 { 1973 {
1915 StandUp(); 1974 StandUp();
1916 } 1975 }
1976
1977// if (!String.IsNullOrEmpty(sitAnimation))
1978// {
1979// m_nextSitAnimation = sitAnimation;
1980// }
1981// else
1982// {
1917 m_nextSitAnimation = "SIT"; 1983 m_nextSitAnimation = "SIT";
1918 1984// }
1985
1919 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1986 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1920 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1987 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1921 1988
@@ -1940,7 +2007,6 @@ namespace OpenSim.Region.Framework.Scenes
1940 } 2007 }
1941 else 2008 else
1942 { 2009 {
1943
1944 m_log.Warn("Sit requested on unknown object: " + targetID.ToString()); 2010 m_log.Warn("Sit requested on unknown object: " + targetID.ToString());
1945 } 2011 }
1946 2012
@@ -2138,44 +2204,7 @@ namespace OpenSim.Region.Framework.Scenes
2138 SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); 2204 SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity);
2139 } 2205 }
2140 */ 2206 */
2141 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset, string sitAnimation)
2142 {
2143 if (m_parentID != 0)
2144 {
2145 StandUp();
2146 }
2147 if (!String.IsNullOrEmpty(sitAnimation))
2148 {
2149 m_nextSitAnimation = sitAnimation;
2150 }
2151 else
2152 {
2153 m_nextSitAnimation = "SIT";
2154 }
2155
2156 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
2157 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
2158 if (part != null)
2159 {
2160 m_requestedSitTargetID = part.LocalId;
2161 //m_requestedSitOffset = offset;
2162 m_requestedSitTargetUUID = targetID;
2163 2207
2164 m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset);
2165
2166 if (m_scene.PhysicsScene.SupportsRayCast())
2167 {
2168 //SitRayCastAvatarPosition(part);
2169 //return;
2170 }
2171 }
2172 else
2173 {
2174 m_log.Warn("Sit requested on unknown object: " + targetID);
2175 }
2176
2177 SendSitResponse(remoteClient, targetID, offset, Quaternion.Identity);
2178 }
2179 2208
2180 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) 2209 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
2181 { 2210 {
@@ -2647,10 +2676,11 @@ namespace OpenSim.Region.Framework.Scenes
2647 /// <param name="avatar"></param> 2676 /// <param name="avatar"></param>
2648 public void SendAppearanceToAgent(ScenePresence avatar) 2677 public void SendAppearanceToAgent(ScenePresence avatar)
2649 { 2678 {
2650// m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); 2679// m_log.DebugFormat(
2680// "[SCENE PRESENCE] Send appearance from {0} {1} to {2} {3}", Name, m_uuid, avatar.Name, avatar.UUID);
2651 2681
2652 avatar.ControllingClient.SendAppearance( 2682 avatar.ControllingClient.SendAppearance(
2653 m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); 2683 UUID, m_appearance.VisualParams, m_appearance.Texture.GetBytes());
2654 } 2684 }
2655 2685
2656 // Because appearance setting is in a module, we actually need 2686 // Because appearance setting is in a module, we actually need
@@ -2659,7 +2689,11 @@ namespace OpenSim.Region.Framework.Scenes
2659 public AvatarAppearance Appearance 2689 public AvatarAppearance Appearance
2660 { 2690 {
2661 get { return m_appearance; } 2691 get { return m_appearance; }
2662 set { m_appearance = value; } 2692 set
2693 {
2694 m_appearance = value;
2695// m_log.DebugFormat("[SCENE PRESENCE]: Set appearance for {0} to {1}", Name, value);
2696 }
2663 } 2697 }
2664 2698
2665 #endregion 2699 #endregion
@@ -2671,15 +2705,10 @@ namespace OpenSim.Region.Framework.Scenes
2671 /// </summary> 2705 /// </summary>
2672 protected void CheckForSignificantMovement() 2706 protected void CheckForSignificantMovement()
2673 { 2707 {
2674 // Movement updates for agents in neighboring regions are sent directly to clients.
2675 // This value only affects how often agent positions are sent to neighbor regions
2676 // for things such as distance-based update prioritization
2677 const float SIGNIFICANT_MOVEMENT = 2.0f;
2678
2679 if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > SIGNIFICANT_MOVEMENT) 2708 if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > SIGNIFICANT_MOVEMENT)
2680 { 2709 {
2681 posLastSignificantMove = AbsolutePosition; 2710 posLastSignificantMove = AbsolutePosition;
2682 m_scene.EventManager.TriggerSignificantClientMovement(m_controllingClient); 2711 m_scene.EventManager.TriggerSignificantClientMovement(this);
2683 } 2712 }
2684 2713
2685 // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m 2714 // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m
diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs
index 393f42d..d34d8e5 100644
--- a/OpenSim/Region/Framework/Scenes/UndoState.cs
+++ b/OpenSim/Region/Framework/Scenes/UndoState.cs
@@ -35,7 +35,7 @@ namespace OpenSim.Region.Framework.Scenes
35{ 35{
36 public class UndoState 36 public class UndoState
37 { 37 {
38 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 38// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
39 39
40 public Vector3 Position = Vector3.Zero; 40 public Vector3 Position = Vector3.Zero;
41 public Vector3 Scale = Vector3.Zero; 41 public Vector3 Scale = Vector3.Zero;
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 88db20e..a0c1ab1 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -806,7 +806,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
806 public event ScriptReset OnScriptReset; 806 public event ScriptReset OnScriptReset;
807 public event GetScriptRunning OnGetScriptRunning; 807 public event GetScriptRunning OnGetScriptRunning;
808 public event SetScriptRunning OnSetScriptRunning; 808 public event SetScriptRunning OnSetScriptRunning;
809 public event UpdateVector OnAutoPilotGo; 809 public event Action<Vector3> OnAutoPilotGo;
810 public event TerrainUnacked OnUnackedTerrain; 810 public event TerrainUnacked OnUnackedTerrain;
811 public event ActivateGesture OnActivateGesture; 811 public event ActivateGesture OnActivateGesture;
812 public event DeactivateGesture OnDeactivateGesture; 812 public event DeactivateGesture OnDeactivateGesture;
@@ -1678,7 +1678,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
1678 { 1678 {
1679 } 1679 }
1680 1680
1681 public void SendTextBoxRequest(string message, int chatChannel, string objectname, string ownerFirstName, string ownerLastName, UUID objectId) 1681 public void SendTextBoxRequest(string message, int chatChannel, string objectname, UUID ownerID, string ownerFirstName, string ownerLastName, UUID objectId)
1682 { 1682 {
1683 } 1683 }
1684 1684
diff --git a/OpenSim/Region/OptionalModules/Framework/Monitoring/MonitorServicesModule.cs b/OpenSim/Region/OptionalModules/Framework/Monitoring/MonitorServicesModule.cs
index d49face..a25e034 100644
--- a/OpenSim/Region/OptionalModules/Framework/Monitoring/MonitorServicesModule.cs
+++ b/OpenSim/Region/OptionalModules/Framework/Monitoring/MonitorServicesModule.cs
@@ -47,7 +47,7 @@ namespace OpenSim.Region.OptionalModules.Framework.Monitoring
47 { 47 {
48 protected Scene m_scene; 48 protected Scene m_scene;
49 49
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 50// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 51
52 public string Name { get { return "Services Health Monitoring Module"; } } 52 public string Name { get { return "Services Health Monitoring Module"; } }
53 53
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index 15bc1b7..dfc624d 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -99,6 +99,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
99 { 99 {
100 100
101 } 101 }
102
102 public void SendSitResponse(UUID TargetID, Vector3 OffsetPos, Quaternion SitOrientation, bool autopilot, 103 public void SendSitResponse(UUID TargetID, Vector3 OffsetPos, Quaternion SitOrientation, bool autopilot,
103 Vector3 CameraAtOffset, Vector3 CameraEyeOffset, bool ForceMouseLook) 104 Vector3 CameraAtOffset, Vector3 CameraEyeOffset, bool ForceMouseLook)
104 { 105 {
@@ -327,7 +328,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
327 public event ScriptReset OnScriptReset; 328 public event ScriptReset OnScriptReset;
328 public event GetScriptRunning OnGetScriptRunning; 329 public event GetScriptRunning OnGetScriptRunning;
329 public event SetScriptRunning OnSetScriptRunning; 330 public event SetScriptRunning OnSetScriptRunning;
330 public event UpdateVector OnAutoPilotGo; 331 public event Action<Vector3> OnAutoPilotGo;
331 332
332 public event TerrainUnacked OnUnackedTerrain; 333 public event TerrainUnacked OnUnackedTerrain;
333 334
@@ -1157,7 +1158,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
1157 { 1158 {
1158 } 1159 }
1159 1160
1160 public void SendTextBoxRequest(string message, int chatChannel, string objectname, string ownerFirstName, string ownerLastName, UUID objectId) 1161 public void SendTextBoxRequest(string message, int chatChannel, string objectname, UUID ownerID, string ownerFirstName, string ownerLastName, UUID objectId)
1161 { 1162 {
1162 } 1163 }
1163 1164
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
index 3cdd06d..4f21d9d 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
@@ -44,14 +44,75 @@ namespace OpenSim.Region.OptionalModules.World.NPC
44 { 44 {
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 46
47 // private const bool m_enabled = false; 47 private Dictionary<UUID, NPCAvatar> m_avatars = new Dictionary<UUID, NPCAvatar>();
48 48 private Dictionary<UUID, AvatarAppearance> m_appearanceCache = new Dictionary<UUID, AvatarAppearance>();
49 private Dictionary<UUID,NPCAvatar> m_avatars = new Dictionary<UUID, NPCAvatar>();
50 private Dictionary<UUID,AvatarAppearance> m_appearanceCache = new Dictionary<UUID, AvatarAppearance>();
51 49
52 public void Initialise(Scene scene, IConfigSource source) 50 public void Initialise(Scene scene, IConfigSource source)
53 { 51 {
54 scene.RegisterModuleInterface<INPCModule>(this); 52 IConfig config = source.Configs["NPC"];
53
54 if (config != null && config.GetBoolean("Enabled", false))
55 {
56 scene.RegisterModuleInterface<INPCModule>(this);
57 scene.EventManager.OnSignificantClientMovement += HandleOnSignificantClientMovement;
58 }
59 }
60
61 public void HandleOnSignificantClientMovement(ScenePresence presence)
62 {
63 lock (m_avatars)
64 {
65 if (m_avatars.ContainsKey(presence.UUID) && presence.MovingToTarget)
66 {
67 double distanceToTarget = Util.GetDistanceTo(presence.AbsolutePosition, presence.MoveToPositionTarget);
68// m_log.DebugFormat(
69// "[NPC MODULE]: Abs pos of {0} is {1}, target {2}, distance {3}",
70// presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget, distanceToTarget);
71
72 // Check the error term of the current position in relation to the target position
73 if (distanceToTarget <= ScenePresence.SIGNIFICANT_MOVEMENT)
74 {
75 // We are close enough to the target
76 m_log.DebugFormat("[NPC MODULE]: Stopping movement of npc {0}", presence.Name);
77
78 if (presence.PhysicsActor.Flying)
79 {
80 Vector3 targetPos = presence.MoveToPositionTarget;
81 float terrainHeight = (float)presence.Scene.Heightmap[(int)targetPos.X, (int)targetPos.Y];
82 if (targetPos.Z - terrainHeight < 0.2)
83 {
84 presence.PhysicsActor.Flying = false;
85 }
86 }
87
88 presence.Velocity = Vector3.Zero;
89 presence.AbsolutePosition = presence.MoveToPositionTarget;
90 presence.ResetMoveToTarget();
91
92 // FIXME: This doesn't work
93 if (presence.PhysicsActor.Flying)
94 presence.Animator.TrySetMovementAnimation("HOVER");
95 else
96 presence.Animator.TrySetMovementAnimation("STAND");
97 }
98 else
99 {
100 m_log.DebugFormat(
101 "[NPC MODULE]: Updating npc {0} at {1} for next movement to {2}",
102 presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget);
103
104 Vector3 agent_control_v3 = new Vector3();
105 presence.HandleMoveToTargetUpdate(ref agent_control_v3, presence.Rotation);
106 presence.AddNewMovement(agent_control_v3, presence.Rotation);
107 }
108//
109//// presence.DoMoveToPositionUpdate((0, presence.MoveToPositionTarget, null);
110
111//
112//
113
114 }
115 }
55 } 116 }
56 117
57 private AvatarAppearance GetAppearance(UUID target, Scene scene) 118 private AvatarAppearance GetAppearance(UUID target, Scene scene)
@@ -59,14 +120,21 @@ namespace OpenSim.Region.OptionalModules.World.NPC
59 if (m_appearanceCache.ContainsKey(target)) 120 if (m_appearanceCache.ContainsKey(target))
60 return m_appearanceCache[target]; 121 return m_appearanceCache[target];
61 122
62 AvatarAppearance appearance = scene.AvatarService.GetAppearance(target); 123 ScenePresence originalPresence = scene.GetScenePresence(target);
63 if (appearance != null) 124
125 if (originalPresence != null)
64 { 126 {
65 m_appearanceCache.Add(target, appearance); 127 AvatarAppearance originalAppearance = originalPresence.Appearance;
66 return appearance; 128 m_appearanceCache.Add(target, originalAppearance);
129 return originalAppearance;
67 } 130 }
131 else
132 {
133 m_log.DebugFormat(
134 "[NPC MODULE]: Avatar {0} is not in the scene for us to grab baked textures from them. Using defaults.", target);
68 135
69 return new AvatarAppearance(); 136 return new AvatarAppearance();
137 }
70 } 138 }
71 139
72 public UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, UUID cloneAppearanceFrom) 140 public UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, UUID cloneAppearanceFrom)
@@ -88,6 +156,13 @@ namespace OpenSim.Region.OptionalModules.World.NPC
88 AvatarAppearance npcAppearance = new AvatarAppearance(originalAppearance, true); 156 AvatarAppearance npcAppearance = new AvatarAppearance(originalAppearance, true);
89 acd.Appearance = npcAppearance; 157 acd.Appearance = npcAppearance;
90 158
159// for (int i = 0; i < acd.Appearance.Texture.FaceTextures.Length; i++)
160// {
161// m_log.DebugFormat(
162// "[NPC MODULE]: NPC avatar {0} has texture id {1} : {2}",
163// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]);
164// }
165
91 scene.AuthenticateHandler.AddNewCircuit(npcAvatar.CircuitCode, acd); 166 scene.AuthenticateHandler.AddNewCircuit(npcAvatar.CircuitCode, acd);
92 scene.AddNewClient(npcAvatar); 167 scene.AddNewClient(npcAvatar);
93 168
@@ -118,7 +193,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
118 return npcAvatar.AgentId; 193 return npcAvatar.AgentId;
119 } 194 }
120 195
121 public void Autopilot(UUID agentID, Scene scene, Vector3 pos) 196 public void MoveToTarget(UUID agentID, Scene scene, Vector3 pos)
122 { 197 {
123 lock (m_avatars) 198 lock (m_avatars)
124 { 199 {
@@ -126,7 +201,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC
126 { 201 {
127 ScenePresence sp; 202 ScenePresence sp;
128 scene.TryGetScenePresence(agentID, out sp); 203 scene.TryGetScenePresence(agentID, out sp);
129 sp.DoAutoPilot(0, pos, m_avatars[agentID]); 204
205 m_log.DebugFormat(
206 "[NPC MODULE]: Moving {0} to {1} in {2}", sp.Name, pos, scene.RegionInfo.RegionName);
207
208 sp.MoveToTarget(pos);
130 } 209 }
131 } 210 }
132 } 211 }
diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
index 899e721..c9dddba 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
@@ -27,11 +27,13 @@
27 27
28using System; 28using System;
29using System.Reflection; 29using System.Reflection;
30using log4net;
30using Nini.Config; 31using Nini.Config;
31using NUnit.Framework; 32using NUnit.Framework;
32using OpenMetaverse; 33using OpenMetaverse;
33using OpenSim.Framework; 34using OpenSim.Framework;
34using OpenSim.Framework.Communications; 35using OpenSim.Framework.Communications;
36using OpenSim.Region.CoreModules.Avatar.AvatarFactory;
35using OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar; 37using OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar;
36using OpenSim.Region.Framework.Interfaces; 38using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
@@ -51,21 +53,104 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
51// log4net.Config.XmlConfigurator.Configure(); 53// log4net.Config.XmlConfigurator.Configure();
52 54
53 IConfigSource config = new IniConfigSource(); 55 IConfigSource config = new IniConfigSource();
56 config.AddConfig("NPC");
57 config.Configs["NPC"].Set("Enabled", "true");
54 58
55 config.AddConfig("Modules"); 59 AvatarFactoryModule afm = new AvatarFactoryModule();
56 config.Configs["Modules"].Set("AvatarServices", "LocalAvatarServicesConnector");
57 config.AddConfig("AvatarService");
58 config.Configs["AvatarService"].Set("LocalServiceModule", "OpenSim.Services.AvatarService.dll:AvatarService");
59 config.Configs["AvatarService"].Set("StorageProvider", "OpenSim.Data.Null.dll");
60
61 TestScene scene = SceneSetupHelpers.SetupScene(); 60 TestScene scene = SceneSetupHelpers.SetupScene();
62 SceneSetupHelpers.SetupSceneModules(scene, config, new NPCModule(), new LocalAvatarServicesConnector()); 61 SceneSetupHelpers.SetupSceneModules(scene, config, afm, new NPCModule());
62 TestClient originalClient = SceneSetupHelpers.AddClient(scene, TestHelper.ParseTail(0x1));
63// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId);
64
65 // 8 is the index of the first baked texture in AvatarAppearance
66 UUID originalFace8TextureId = TestHelper.ParseTail(0x10);
67 Primitive.TextureEntry originalTe = new Primitive.TextureEntry(UUID.Zero);
68 Primitive.TextureEntryFace originalTef = originalTe.CreateFace(8);
69 originalTef.TextureID = originalFace8TextureId;
70
71 // We also need to add the texture to the asset service, otherwise the AvatarFactoryModule will tell
72 // ScenePresence.SendInitialData() to reset our entire appearance.
73 scene.AssetService.Store(AssetHelpers.CreateAsset(originalFace8TextureId));
74
75 afm.SetAppearance(originalClient, originalTe, null);
63 76
64 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); 77 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
65 UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, UUID.Zero); 78 UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, originalClient.AgentId);
66 79
67 ScenePresence npc = scene.GetScenePresence(npcId); 80 ScenePresence npc = scene.GetScenePresence(npcId);
81
68 Assert.That(npc, Is.Not.Null); 82 Assert.That(npc, Is.Not.Null);
83 Assert.That(npc.Appearance.Texture.FaceTextures[8].TextureID, Is.EqualTo(originalFace8TextureId));
84 }
85
86 [Test]
87 public void TestMove()
88 {
89 TestHelper.InMethod();
90// log4net.Config.XmlConfigurator.Configure();
91
92 IConfigSource config = new IniConfigSource();
93
94 config.AddConfig("NPC");
95 config.Configs["NPC"].Set("Enabled", "true");
96
97 TestScene scene = SceneSetupHelpers.SetupScene();
98 SceneSetupHelpers.SetupSceneModules(scene, config, new NPCModule());
99 TestClient originalClient = SceneSetupHelpers.AddClient(scene, TestHelper.ParseTail(0x1));
100// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId);
101
102 Vector3 startPos = new Vector3(128, 128, 30);
103 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
104 UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, scene, originalClient.AgentId);
105
106 ScenePresence npc = scene.GetScenePresence(npcId);
107 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
108
109 // For now, we'll make the scene presence fly to simplify this test, but this needs to change.
110 npc.PhysicsActor.Flying = true;
111
112 scene.Update();
113 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
114
115 Vector3 targetPos = startPos + new Vector3(0, 0, 10);
116 npcModule.MoveToTarget(npc.UUID, scene, targetPos);
117
118 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
119
120 scene.Update();
121
122 // We should really check the exact figure.
123 Assert.That(npc.AbsolutePosition.X, Is.EqualTo(startPos.X));
124 Assert.That(npc.AbsolutePosition.Y, Is.EqualTo(startPos.Y));
125 Assert.That(npc.AbsolutePosition.Z, Is.GreaterThan(startPos.Z));
126 Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.Z));
127
128 for (int i = 0; i < 10; i++)
129 scene.Update();
130
131 double distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos);
132 Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on first move");
133 Assert.That(npc.AbsolutePosition, Is.EqualTo(targetPos));
134
135 // Try a second movement
136 startPos = npc.AbsolutePosition;
137 targetPos = startPos + new Vector3(10, 0, 0);
138 npcModule.MoveToTarget(npc.UUID, scene, targetPos);
139
140 scene.Update();
141
142 // We should really check the exact figure.
143 Assert.That(npc.AbsolutePosition.X, Is.GreaterThan(startPos.X));
144 Assert.That(npc.AbsolutePosition.X, Is.LessThan(targetPos.X));
145 Assert.That(npc.AbsolutePosition.Y, Is.EqualTo(startPos.Y));
146 Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
147
148 for (int i = 0; i < 10; i++)
149 scene.Update();
150
151 distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos);
152 Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on second move");
153 Assert.That(npc.AbsolutePosition, Is.EqualTo(targetPos));
69 } 154 }
70 } 155 }
71} \ No newline at end of file 156} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs
index 6c9d9ab..1ceed1a 100644
--- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs
+++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs
@@ -123,11 +123,15 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
123 actorPosition.X = ((int)Constants.RegionSize - 0.1f); 123 actorPosition.X = ((int)Constants.RegionSize - 0.1f);
124 } 124 }
125 125
126 float height = _heightMap[(int)actor.Position.Y * Constants.RegionSize + (int)actor.Position.X] + actor.Size.Z; 126 float terrainHeight = 0;
127 if (_heightMap != null)
128 terrainHeight = _heightMap[(int)actor.Position.Y * Constants.RegionSize + (int)actor.Position.X];
129
130 float height = terrainHeight + actor.Size.Z;
131
127 if (actor.Flying) 132 if (actor.Flying)
128 { 133 {
129 if (actor.Position.Z + (actor.Velocity.Z*timeStep) < 134 if (actor.Position.Z + (actor.Velocity.Z * timeStep) < terrainHeight + 2)
130 _heightMap[(int)actor.Position.Y * Constants.RegionSize + (int)actor.Position.X] + 2)
131 { 135 {
132 actorPosition.Z = height; 136 actorPosition.Z = height;
133 actorVelocity.Z = 0; 137 actorVelocity.Z = 0;
@@ -135,7 +139,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
135 } 139 }
136 else 140 else
137 { 141 {
138 actorPosition.Z += actor.Velocity.Z*timeStep; 142 actorPosition.Z += actor.Velocity.Z * timeStep;
139 actor.IsColliding = false; 143 actor.IsColliding = false;
140 } 144 }
141 } 145 }
diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
index 3870411..04efc1d 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
@@ -86,6 +86,10 @@ namespace OpenSim.Region.Physics.Manager
86 86
87 public abstract void RemoveAvatar(PhysicsActor actor); 87 public abstract void RemoveAvatar(PhysicsActor actor);
88 88
89 /// <summary>
90 /// Remove a prim from the physics scene.
91 /// </summary>
92 /// <param name="prim"></param>
89 public abstract void RemovePrim(PhysicsActor prim); 93 public abstract void RemovePrim(PhysicsActor prim);
90 94
91 public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, 95 public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index 5413aa8..e81b982 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -301,20 +301,22 @@ namespace OpenSim.Region.Physics.Meshing
301 } 301 }
302 } 302 }
303 303
304 /// <summary>
305 /// Create a physics mesh from data that comes with the prim. The actual data used depends on the prim type.
306 /// </summary>
307 /// <param name="primName"></param>
308 /// <param name="primShape"></param>
309 /// <param name="size"></param>
310 /// <param name="lod"></param>
311 /// <returns></returns>
304 private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod) 312 private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod)
305 { 313 {
306// m_log.DebugFormat( 314// m_log.DebugFormat(
307// "[MESH]: Creating physics proxy for {0}, shape {1}", 315// "[MESH]: Creating physics proxy for {0}, shape {1}",
308// primName, (OpenMetaverse.SculptType)primShape.SculptType); 316// primName, (OpenMetaverse.SculptType)primShape.SculptType);
309 317
310 PrimMesh primMesh; 318 List<Coord> coords;
311 PrimMesher.SculptMesh sculptMesh; 319 List<Face> faces;
312
313 List<Coord> coords = new List<Coord>();
314 List<Face> faces = new List<Face>();
315
316 Image idata = null;
317 string decodedSculptFileName = "";
318 320
319 if (primShape.SculptEntry) 321 if (primShape.SculptEntry)
320 { 322 {
@@ -323,337 +325,414 @@ namespace OpenSim.Region.Physics.Meshing
323 if (!useMeshiesPhysicsMesh) 325 if (!useMeshiesPhysicsMesh)
324 return null; 326 return null;
325 327
326 m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName); 328 if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, size, out coords, out faces))
329 return null;
330 }
331 else
332 {
333 if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, size, lod, out coords, out faces))
334 return null;
335 }
336 }
337 else
338 {
339 if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, out coords, out faces))
340 return null;
341 }
327 342
328 OSD meshOsd = null; 343 // Remove the reference to any JPEG2000 sculpt data so it can be GCed
344 primShape.SculptData = Utils.EmptyBytes;
329 345
330 if (primShape.SculptData.Length <= 0) 346 int numCoords = coords.Count;
331 { 347 int numFaces = faces.Count;
332 m_log.Error("[MESH]: asset data is zero length");
333 return null;
334 }
335 348
336 long start = 0; 349 // Create the list of vertices
337 using (MemoryStream data = new MemoryStream(primShape.SculptData)) 350 List<Vertex> vertices = new List<Vertex>();
338 { 351 for (int i = 0; i < numCoords; i++)
339 try 352 {
340 { 353 Coord c = coords[i];
341 OSD osd = OSDParser.DeserializeLLSDBinary(data); 354 vertices.Add(new Vertex(c.X, c.Y, c.Z));
342 if (osd is OSDMap) 355 }
343 meshOsd = (OSDMap)osd;
344 else
345 {
346 m_log.Warn("[Mesh}: unable to cast mesh asset to OSDMap");
347 return null;
348 }
349 }
350 catch (Exception e)
351 {
352 m_log.Error("[MESH]: Exception deserializing mesh asset header:" + e.ToString());
353 }
354 356
355 start = data.Position; 357 Mesh mesh = new Mesh();
356 } 358 // Add the corresponding triangles to the mesh
359 for (int i = 0; i < numFaces; i++)
360 {
361 Face f = faces[i];
362 mesh.Add(new Triangle(vertices[f.v1], vertices[f.v2], vertices[f.v3]));
363 }
364
365 return mesh;
366 }
357 367
358 if (meshOsd is OSDMap) 368 /// <summary>
369 /// Generate the co-ords and faces necessary to construct a mesh from the mesh data the accompanies a prim.
370 /// </summary>
371 /// <param name="primName"></param>
372 /// <param name="primShape"></param>
373 /// <param name="size"></param>
374 /// <param name="coords">Coords are added to this list by the method.</param>
375 /// <param name="faces">Faces are added to this list by the method.</param>
376 /// <returns>true if coords and faces were successfully generated, false if not</returns>
377 private bool GenerateCoordsAndFacesFromPrimMeshData(
378 string primName, PrimitiveBaseShape primShape, Vector3 size, out List<Coord> coords, out List<Face> faces)
379 {
380 m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName);
381
382 coords = new List<Coord>();
383 faces = new List<Face>();
384 OSD meshOsd = null;
385
386 if (primShape.SculptData.Length <= 0)
387 {
388 m_log.Error("[MESH]: asset data is zero length");
389 return false;
390 }
391
392 long start = 0;
393 using (MemoryStream data = new MemoryStream(primShape.SculptData))
394 {
395 try
396 {
397 OSD osd = OSDParser.DeserializeLLSDBinary(data);
398 if (osd is OSDMap)
399 meshOsd = (OSDMap)osd;
400 else
359 { 401 {
360 OSDMap physicsParms = null; 402 m_log.Warn("[Mesh}: unable to cast mesh asset to OSDMap");
361 OSDMap map = (OSDMap)meshOsd; 403 return false;
362 if (map.ContainsKey("physics_shape")) 404 }
363 physicsParms = (OSDMap)map["physics_shape"]; // old asset format 405 }
364 else if (map.ContainsKey("physics_mesh")) 406 catch (Exception e)
365 physicsParms = (OSDMap)map["physics_mesh"]; // new asset format 407 {
366 408 m_log.Error("[MESH]: Exception deserializing mesh asset header:" + e.ToString());
367 if (physicsParms == null) 409 }
368 { 410
369 m_log.Warn("[MESH]: no recognized physics mesh found in mesh asset"); 411 start = data.Position;
370 return null; 412 }
371 }
372 413
373 int physOffset = physicsParms["offset"].AsInteger() + (int)start; 414 if (meshOsd is OSDMap)
374 int physSize = physicsParms["size"].AsInteger(); 415 {
416 OSDMap physicsParms = null;
417 OSDMap map = (OSDMap)meshOsd;
418 if (map.ContainsKey("physics_shape"))
419 physicsParms = (OSDMap)map["physics_shape"]; // old asset format
420 else if (map.ContainsKey("physics_mesh"))
421 physicsParms = (OSDMap)map["physics_mesh"]; // new asset format
422
423 if (physicsParms == null)
424 {
425 m_log.Warn("[MESH]: no recognized physics mesh found in mesh asset");
426 return false;
427 }
375 428
376 if (physOffset < 0 || physSize == 0) 429 int physOffset = physicsParms["offset"].AsInteger() + (int)start;
377 return null; // no mesh data in asset 430 int physSize = physicsParms["size"].AsInteger();
378 431
379 OSD decodedMeshOsd = new OSD(); 432 if (physOffset < 0 || physSize == 0)
380 byte[] meshBytes = new byte[physSize]; 433 return false; // no mesh data in asset
381 System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize); 434
435 OSD decodedMeshOsd = new OSD();
436 byte[] meshBytes = new byte[physSize];
437 System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize);
382// byte[] decompressed = new byte[physSize * 5]; 438// byte[] decompressed = new byte[physSize * 5];
383 try 439 try
440 {
441 using (MemoryStream inMs = new MemoryStream(meshBytes))
442 {
443 using (MemoryStream outMs = new MemoryStream())
384 { 444 {
385 using (MemoryStream inMs = new MemoryStream(meshBytes)) 445 using (ZOutputStream zOut = new ZOutputStream(outMs))
386 { 446 {
387 using (MemoryStream outMs = new MemoryStream()) 447 byte[] readBuffer = new byte[2048];
448 int readLen = 0;
449 while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
388 { 450 {
389 using (ZOutputStream zOut = new ZOutputStream(outMs)) 451 zOut.Write(readBuffer, 0, readLen);
390 {
391 byte[] readBuffer = new byte[2048];
392 int readLen = 0;
393 while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
394 {
395 zOut.Write(readBuffer, 0, readLen);
396 }
397 zOut.Flush();
398 outMs.Seek(0, SeekOrigin.Begin);
399
400 byte[] decompressedBuf = outMs.GetBuffer();
401
402 decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
403 }
404 } 452 }
453 zOut.Flush();
454 outMs.Seek(0, SeekOrigin.Begin);
455
456 byte[] decompressedBuf = outMs.GetBuffer();
457
458 decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
405 } 459 }
406 } 460 }
407 catch (Exception e) 461 }
408 { 462 }
409 m_log.Error("[MESH]: exception decoding physical mesh: " + e.ToString()); 463 catch (Exception e)
410 return null; 464 {
411 } 465 m_log.Error("[MESH]: exception decoding physical mesh: " + e.ToString());
466 return false;
467 }
412 468
413 OSDArray decodedMeshOsdArray = null; 469 OSDArray decodedMeshOsdArray = null;
414 470
415 // physics_shape is an array of OSDMaps, one for each submesh 471 // physics_shape is an array of OSDMaps, one for each submesh
416 if (decodedMeshOsd is OSDArray) 472 if (decodedMeshOsd is OSDArray)
417 { 473 {
418// Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd)); 474// Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd));
419 475
420 decodedMeshOsdArray = (OSDArray)decodedMeshOsd; 476 decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
421 foreach (OSD subMeshOsd in decodedMeshOsdArray) 477 foreach (OSD subMeshOsd in decodedMeshOsdArray)
422 { 478 {
423 if (subMeshOsd is OSDMap) 479 if (subMeshOsd is OSDMap)
424 AddSubMesh(subMeshOsd as OSDMap, size, coords, faces); 480 AddSubMesh(subMeshOsd as OSDMap, size, coords, faces);
425 }
426 }
427 } 481 }
428 } 482 }
429 else 483 }
484
485 return true;
486 }
487
488 /// <summary>
489 /// Generate the co-ords and faces necessary to construct a mesh from the sculpt data the accompanies a prim.
490 /// </summary>
491 /// <param name="primName"></param>
492 /// <param name="primShape"></param>
493 /// <param name="size"></param>
494 /// <param name="lod"></param>
495 /// <param name="coords">Coords are added to this list by the method.</param>
496 /// <param name="faces">Faces are added to this list by the method.</param>
497 /// <returns>true if coords and faces were successfully generated, false if not</returns>
498 private bool GenerateCoordsAndFacesFromPrimSculptData(
499 string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, out List<Coord> coords, out List<Face> faces)
500 {
501 coords = new List<Coord>();
502 faces = new List<Face>();
503 PrimMesher.SculptMesh sculptMesh;
504 Image idata = null;
505 string decodedSculptFileName = "";
506
507 if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero)
508 {
509 decodedSculptFileName = System.IO.Path.Combine(decodedSculptMapPath, "smap_" + primShape.SculptTexture.ToString());
510 try
430 { 511 {
431 if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero) 512 if (File.Exists(decodedSculptFileName))
432 { 513 {
433 decodedSculptFileName = System.IO.Path.Combine(decodedSculptMapPath, "smap_" + primShape.SculptTexture.ToString()); 514 idata = Image.FromFile(decodedSculptFileName);
434 try
435 {
436 if (File.Exists(decodedSculptFileName))
437 {
438 idata = Image.FromFile(decodedSculptFileName);
439 }
440 }
441 catch (Exception e)
442 {
443 m_log.Error("[SCULPT]: unable to load cached sculpt map " + decodedSculptFileName + " " + e.Message);
444
445 }
446 //if (idata != null)
447 // m_log.Debug("[SCULPT]: loaded cached map asset for map ID: " + primShape.SculptTexture.ToString());
448 } 515 }
516 }
517 catch (Exception e)
518 {
519 m_log.Error("[SCULPT]: unable to load cached sculpt map " + decodedSculptFileName + " " + e.Message);
520
521 }
522 //if (idata != null)
523 // m_log.Debug("[SCULPT]: loaded cached map asset for map ID: " + primShape.SculptTexture.ToString());
524 }
525
526 if (idata == null)
527 {
528 if (primShape.SculptData == null || primShape.SculptData.Length == 0)
529 return false;
530
531 try
532 {
533 OpenMetaverse.Imaging.ManagedImage unusedData;
534 OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(primShape.SculptData, out unusedData, out idata);
449 535
450 if (idata == null) 536 if (idata == null)
451 { 537 {
452 if (primShape.SculptData == null || primShape.SculptData.Length == 0) 538 // In some cases it seems that the decode can return a null bitmap without throwing
453 return null; 539 // an exception
540 m_log.WarnFormat("[PHYSICS]: OpenJPEG decoded sculpt data for {0} to a null bitmap. Ignoring.", primName);
454 541
455 try 542 return false;
456 { 543 }
457 OpenMetaverse.Imaging.ManagedImage unusedData;
458 OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(primShape.SculptData, out unusedData, out idata);
459 unusedData = null;
460 544
461 //idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData); 545 unusedData = null;
462 546
463 if (cacheSculptMaps && idata != null) 547 //idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData);
464 {
465 try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); }
466 catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); }
467 }
468 }
469 catch (DllNotFoundException)
470 {
471 m_log.Error("[PHYSICS]: OpenJpeg is not installed correctly on this system. Physics Proxy generation failed. Often times this is because of an old version of GLIBC. You must have version 2.4 or above!");
472 return null;
473 }
474 catch (IndexOutOfRangeException)
475 {
476 m_log.Error("[PHYSICS]: OpenJpeg was unable to decode this. Physics Proxy generation failed");
477 return null;
478 }
479 catch (Exception ex)
480 {
481 m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " + ex.Message);
482 return null;
483 }
484 }
485 548
486 PrimMesher.SculptMesh.SculptType sculptType; 549 if (cacheSculptMaps)
487 switch ((OpenMetaverse.SculptType)primShape.SculptType)
488 { 550 {
489 case OpenMetaverse.SculptType.Cylinder: 551 try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); }
490 sculptType = PrimMesher.SculptMesh.SculptType.cylinder; 552 catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); }
491 break;
492 case OpenMetaverse.SculptType.Plane:
493 sculptType = PrimMesher.SculptMesh.SculptType.plane;
494 break;
495 case OpenMetaverse.SculptType.Torus:
496 sculptType = PrimMesher.SculptMesh.SculptType.torus;
497 break;
498 case OpenMetaverse.SculptType.Sphere:
499 sculptType = PrimMesher.SculptMesh.SculptType.sphere;
500 break;
501 default:
502 sculptType = PrimMesher.SculptMesh.SculptType.plane;
503 break;
504 } 553 }
554 }
555 catch (DllNotFoundException)
556 {
557 m_log.Error("[PHYSICS]: OpenJpeg is not installed correctly on this system. Physics Proxy generation failed. Often times this is because of an old version of GLIBC. You must have version 2.4 or above!");
558 return false;
559 }
560 catch (IndexOutOfRangeException)
561 {
562 m_log.Error("[PHYSICS]: OpenJpeg was unable to decode this. Physics Proxy generation failed");
563 return false;
564 }
565 catch (Exception ex)
566 {
567 m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " + ex.Message);
568 return false;
569 }
570 }
571
572 PrimMesher.SculptMesh.SculptType sculptType;
573 switch ((OpenMetaverse.SculptType)primShape.SculptType)
574 {
575 case OpenMetaverse.SculptType.Cylinder:
576 sculptType = PrimMesher.SculptMesh.SculptType.cylinder;
577 break;
578 case OpenMetaverse.SculptType.Plane:
579 sculptType = PrimMesher.SculptMesh.SculptType.plane;
580 break;
581 case OpenMetaverse.SculptType.Torus:
582 sculptType = PrimMesher.SculptMesh.SculptType.torus;
583 break;
584 case OpenMetaverse.SculptType.Sphere:
585 sculptType = PrimMesher.SculptMesh.SculptType.sphere;
586 break;
587 default:
588 sculptType = PrimMesher.SculptMesh.SculptType.plane;
589 break;
590 }
505 591
506 bool mirror = ((primShape.SculptType & 128) != 0); 592 bool mirror = ((primShape.SculptType & 128) != 0);
507 bool invert = ((primShape.SculptType & 64) != 0); 593 bool invert = ((primShape.SculptType & 64) != 0);
508 594
509 sculptMesh = new PrimMesher.SculptMesh((Bitmap)idata, sculptType, (int)lod, false, mirror, invert); 595 sculptMesh = new PrimMesher.SculptMesh((Bitmap)idata, sculptType, (int)lod, false, mirror, invert);
510
511 idata.Dispose();
512 596
513 sculptMesh.DumpRaw(baseDir, primName, "primMesh"); 597 idata.Dispose();
514 598
515 sculptMesh.Scale(size.X, size.Y, size.Z); 599 sculptMesh.DumpRaw(baseDir, primName, "primMesh");
516 600
517 coords = sculptMesh.coords; 601 sculptMesh.Scale(size.X, size.Y, size.Z);
518 faces = sculptMesh.faces; 602
519 } 603 coords = sculptMesh.coords;
604 faces = sculptMesh.faces;
605
606 return true;
607 }
608
609 /// <summary>
610 /// Generate the co-ords and faces necessary to construct a mesh from the shape data the accompanies a prim.
611 /// </summary>
612 /// <param name="primName"></param>
613 /// <param name="primShape"></param>
614 /// <param name="size"></param>
615 /// <param name="coords">Coords are added to this list by the method.</param>
616 /// <param name="faces">Faces are added to this list by the method.</param>
617 /// <returns>true if coords and faces were successfully generated, false if not</returns>
618 private bool GenerateCoordsAndFacesFromPrimShapeData(
619 string primName, PrimitiveBaseShape primShape, Vector3 size, out List<Coord> coords, out List<Face> faces)
620 {
621 PrimMesh primMesh;
622 coords = new List<Coord>();
623 faces = new List<Face>();
624
625 float pathShearX = primShape.PathShearX < 128 ? (float)primShape.PathShearX * 0.01f : (float)(primShape.PathShearX - 256) * 0.01f;
626 float pathShearY = primShape.PathShearY < 128 ? (float)primShape.PathShearY * 0.01f : (float)(primShape.PathShearY - 256) * 0.01f;
627 float pathBegin = (float)primShape.PathBegin * 2.0e-5f;
628 float pathEnd = 1.0f - (float)primShape.PathEnd * 2.0e-5f;
629 float pathScaleX = (float)(primShape.PathScaleX - 100) * 0.01f;
630 float pathScaleY = (float)(primShape.PathScaleY - 100) * 0.01f;
631
632 float profileBegin = (float)primShape.ProfileBegin * 2.0e-5f;
633 float profileEnd = 1.0f - (float)primShape.ProfileEnd * 2.0e-5f;
634 float profileHollow = (float)primShape.ProfileHollow * 2.0e-5f;
635 if (profileHollow > 0.95f)
636 profileHollow = 0.95f;
637
638 int sides = 4;
639 if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
640 sides = 3;
641 else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
642 sides = 24;
643 else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
644 { // half circle, prim is a sphere
645 sides = 24;
646
647 profileBegin = 0.5f * profileBegin + 0.5f;
648 profileEnd = 0.5f * profileEnd + 0.5f;
520 } 649 }
521 else
522 {
523 float pathShearX = primShape.PathShearX < 128 ? (float)primShape.PathShearX * 0.01f : (float)(primShape.PathShearX - 256) * 0.01f;
524 float pathShearY = primShape.PathShearY < 128 ? (float)primShape.PathShearY * 0.01f : (float)(primShape.PathShearY - 256) * 0.01f;
525 float pathBegin = (float)primShape.PathBegin * 2.0e-5f;
526 float pathEnd = 1.0f - (float)primShape.PathEnd * 2.0e-5f;
527 float pathScaleX = (float)(primShape.PathScaleX - 100) * 0.01f;
528 float pathScaleY = (float)(primShape.PathScaleY - 100) * 0.01f;
529
530 float profileBegin = (float)primShape.ProfileBegin * 2.0e-5f;
531 float profileEnd = 1.0f - (float)primShape.ProfileEnd * 2.0e-5f;
532 float profileHollow = (float)primShape.ProfileHollow * 2.0e-5f;
533 if (profileHollow > 0.95f)
534 profileHollow = 0.95f;
535
536 int sides = 4;
537 if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
538 sides = 3;
539 else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
540 sides = 24;
541 else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
542 { // half circle, prim is a sphere
543 sides = 24;
544
545 profileBegin = 0.5f * profileBegin + 0.5f;
546 profileEnd = 0.5f * profileEnd + 0.5f;
547 }
548 650
549 int hollowSides = sides; 651 int hollowSides = sides;
550 if (primShape.HollowShape == HollowShape.Circle) 652 if (primShape.HollowShape == HollowShape.Circle)
551 hollowSides = 24; 653 hollowSides = 24;
552 else if (primShape.HollowShape == HollowShape.Square) 654 else if (primShape.HollowShape == HollowShape.Square)
553 hollowSides = 4; 655 hollowSides = 4;
554 else if (primShape.HollowShape == HollowShape.Triangle) 656 else if (primShape.HollowShape == HollowShape.Triangle)
555 hollowSides = 3; 657 hollowSides = 3;
556 658
557 primMesh = new PrimMesh(sides, profileBegin, profileEnd, profileHollow, hollowSides); 659 primMesh = new PrimMesh(sides, profileBegin, profileEnd, profileHollow, hollowSides);
558 660
559 if (primMesh.errorMessage != null) 661 if (primMesh.errorMessage != null)
560 if (primMesh.errorMessage.Length > 0) 662 if (primMesh.errorMessage.Length > 0)
561 m_log.Error("[ERROR] " + primMesh.errorMessage); 663 m_log.Error("[ERROR] " + primMesh.errorMessage);
562 664
563 primMesh.topShearX = pathShearX; 665 primMesh.topShearX = pathShearX;
564 primMesh.topShearY = pathShearY; 666 primMesh.topShearY = pathShearY;
565 primMesh.pathCutBegin = pathBegin; 667 primMesh.pathCutBegin = pathBegin;
566 primMesh.pathCutEnd = pathEnd; 668 primMesh.pathCutEnd = pathEnd;
567 669
568 if (primShape.PathCurve == (byte)Extrusion.Straight || primShape.PathCurve == (byte) Extrusion.Flexible) 670 if (primShape.PathCurve == (byte)Extrusion.Straight || primShape.PathCurve == (byte) Extrusion.Flexible)
569 { 671 {
570 primMesh.twistBegin = primShape.PathTwistBegin * 18 / 10; 672 primMesh.twistBegin = primShape.PathTwistBegin * 18 / 10;
571 primMesh.twistEnd = primShape.PathTwist * 18 / 10; 673 primMesh.twistEnd = primShape.PathTwist * 18 / 10;
572 primMesh.taperX = pathScaleX; 674 primMesh.taperX = pathScaleX;
573 primMesh.taperY = pathScaleY; 675 primMesh.taperY = pathScaleY;
574 676
575 if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f) 677 if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f)
576 { 678 {
577 ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh); 679 ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh);
578 if (profileBegin < 0.0f) profileBegin = 0.0f; 680 if (profileBegin < 0.0f) profileBegin = 0.0f;
579 if (profileEnd > 1.0f) profileEnd = 1.0f; 681 if (profileEnd > 1.0f) profileEnd = 1.0f;
580 } 682 }
581#if SPAM 683#if SPAM
582 m_log.Debug("****** PrimMesh Parameters (Linear) ******\n" + primMesh.ParamsToDisplayString()); 684 m_log.Debug("****** PrimMesh Parameters (Linear) ******\n" + primMesh.ParamsToDisplayString());
583#endif 685#endif
584 try 686 try
585 { 687 {
586 primMesh.ExtrudeLinear(); 688 primMesh.ExtrudeLinear();
587 }
588 catch (Exception ex)
589 {
590 ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh);
591 return null;
592 }
593 } 689 }
594 else 690 catch (Exception ex)
595 { 691 {
596 primMesh.holeSizeX = (200 - primShape.PathScaleX) * 0.01f; 692 ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh);
597 primMesh.holeSizeY = (200 - primShape.PathScaleY) * 0.01f; 693 return false;
598 primMesh.radius = 0.01f * primShape.PathRadiusOffset; 694 }
599 primMesh.revolutions = 1.0f + 0.015f * primShape.PathRevolutions; 695 }
600 primMesh.skew = 0.01f * primShape.PathSkew; 696 else
601 primMesh.twistBegin = primShape.PathTwistBegin * 36 / 10; 697 {
602 primMesh.twistEnd = primShape.PathTwist * 36 / 10; 698 primMesh.holeSizeX = (200 - primShape.PathScaleX) * 0.01f;
603 primMesh.taperX = primShape.PathTaperX * 0.01f; 699 primMesh.holeSizeY = (200 - primShape.PathScaleY) * 0.01f;
604 primMesh.taperY = primShape.PathTaperY * 0.01f; 700 primMesh.radius = 0.01f * primShape.PathRadiusOffset;
605 701 primMesh.revolutions = 1.0f + 0.015f * primShape.PathRevolutions;
606 if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f) 702 primMesh.skew = 0.01f * primShape.PathSkew;
607 { 703 primMesh.twistBegin = primShape.PathTwistBegin * 36 / 10;
608 ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh); 704 primMesh.twistEnd = primShape.PathTwist * 36 / 10;
609 if (profileBegin < 0.0f) profileBegin = 0.0f; 705 primMesh.taperX = primShape.PathTaperX * 0.01f;
610 if (profileEnd > 1.0f) profileEnd = 1.0f; 706 primMesh.taperY = primShape.PathTaperY * 0.01f;
611 } 707
708 if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f)
709 {
710 ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh);
711 if (profileBegin < 0.0f) profileBegin = 0.0f;
712 if (profileEnd > 1.0f) profileEnd = 1.0f;
713 }
612#if SPAM 714#if SPAM
613 m_log.Debug("****** PrimMesh Parameters (Circular) ******\n" + primMesh.ParamsToDisplayString()); 715 m_log.Debug("****** PrimMesh Parameters (Circular) ******\n" + primMesh.ParamsToDisplayString());
614#endif 716#endif
615 try 717 try
616 { 718 {
617 primMesh.ExtrudeCircular(); 719 primMesh.ExtrudeCircular();
618 } 720 }
619 catch (Exception ex) 721 catch (Exception ex)
620 { 722 {
621 ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh); 723 ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh);
622 return null; 724 return false;
623 }
624 } 725 }
625
626 primMesh.DumpRaw(baseDir, primName, "primMesh");
627
628 primMesh.Scale(size.X, size.Y, size.Z);
629
630 coords = primMesh.coords;
631 faces = primMesh.faces;
632 } 726 }
633 727
634 // Remove the reference to any JPEG2000 sculpt data so it can be GCed 728 primMesh.DumpRaw(baseDir, primName, "primMesh");
635 primShape.SculptData = Utils.EmptyBytes;
636 729
637 int numCoords = coords.Count; 730 primMesh.Scale(size.X, size.Y, size.Z);
638 int numFaces = faces.Count;
639 731
640 // Create the list of vertices 732 coords = primMesh.coords;
641 List<Vertex> vertices = new List<Vertex>(); 733 faces = primMesh.faces;
642 for (int i = 0; i < numCoords; i++)
643 {
644 Coord c = coords[i];
645 vertices.Add(new Vertex(c.X, c.Y, c.Z));
646 }
647
648 Mesh mesh = new Mesh();
649 // Add the corresponding triangles to the mesh
650 for (int i = 0; i < numFaces; i++)
651 {
652 Face f = faces[i];
653 mesh.Add(new Triangle(vertices[f.v1], vertices[f.v2], vertices[f.v3]));
654 }
655 734
656 return mesh; 735 return true;
657 } 736 }
658 737
659 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) 738 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod)
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index 6b74e74..4f461ad 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -1220,18 +1220,23 @@ namespace OpenSim.Region.Physics.OdePlugin
1220 { 1220 {
1221 m_requestedUpdateFrequency = ms; 1221 m_requestedUpdateFrequency = ms;
1222 m_eventsubscription = ms; 1222 m_eventsubscription = ms;
1223 _parent_scene.addCollisionEventReporting(this); 1223 _parent_scene.AddCollisionEventReporting(this);
1224 } 1224 }
1225
1225 public override void UnSubscribeEvents() 1226 public override void UnSubscribeEvents()
1226 { 1227 {
1227 _parent_scene.remCollisionEventReporting(this); 1228 _parent_scene.RemoveCollisionEventReporting(this);
1228 m_requestedUpdateFrequency = 0; 1229 m_requestedUpdateFrequency = 0;
1229 m_eventsubscription = 0; 1230 m_eventsubscription = 0;
1230 } 1231 }
1232
1231 public void AddCollisionEvent(uint CollidedWith, ContactPoint contact) 1233 public void AddCollisionEvent(uint CollidedWith, ContactPoint contact)
1232 { 1234 {
1233 if (m_eventsubscription > 0) 1235 if (m_eventsubscription > 0)
1234 { 1236 {
1237// m_log.DebugFormat(
1238// "[PHYSICS]: Adding collision event for {0}, collidedWith {1}, contact {2}", "", CollidedWith, contact);
1239
1235 CollisionEventsThisFrame.addCollider(CollidedWith, contact); 1240 CollisionEventsThisFrame.addCollider(CollidedWith, contact);
1236 } 1241 }
1237 } 1242 }
@@ -1248,6 +1253,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1248 m_eventsubscription = 0; 1253 m_eventsubscription = 0;
1249 } 1254 }
1250 } 1255 }
1256
1251 public override bool SubscribedEvents() 1257 public override bool SubscribedEvents()
1252 { 1258 {
1253 if (m_eventsubscription > 0) 1259 if (m_eventsubscription > 0)
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index b3045bd..924d7c2 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -61,6 +61,22 @@ namespace OpenSim.Region.Physics.OdePlugin
61 { 61 {
62 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 62 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
63 63
64 private bool m_isphysical;
65
66 /// <summary>
67 /// Is this prim subject to physics? Even if not, it's still solid for collision purposes.
68 /// </summary>
69 public override bool IsPhysical
70 {
71 get { return m_isphysical; }
72 set
73 {
74 m_isphysical = value;
75 if (!m_isphysical) // Zero the remembered last velocity
76 m_lastVelocity = Vector3.Zero;
77 }
78 }
79
64 private Vector3 _position; 80 private Vector3 _position;
65 private Vector3 _velocity; 81 private Vector3 _velocity;
66 private Vector3 _torque; 82 private Vector3 _torque;
@@ -138,12 +154,15 @@ namespace OpenSim.Region.Physics.OdePlugin
138 private List<Vector3> m_forcelist = new List<Vector3>(); 154 private List<Vector3> m_forcelist = new List<Vector3>();
139 private List<Vector3> m_angularforcelist = new List<Vector3>(); 155 private List<Vector3> m_angularforcelist = new List<Vector3>();
140 156
141 private IMesh _mesh;
142 private PrimitiveBaseShape _pbs; 157 private PrimitiveBaseShape _pbs;
143 private OdeScene _parent_scene; 158 private OdeScene _parent_scene;
159
160 /// <summary>
161 /// The physics space which contains prim geometries
162 /// </summary>
144 public IntPtr m_targetSpace = IntPtr.Zero; 163 public IntPtr m_targetSpace = IntPtr.Zero;
164
145 public IntPtr prim_geom; 165 public IntPtr prim_geom;
146 public IntPtr prev_geom;
147 public IntPtr _triMeshData; 166 public IntPtr _triMeshData;
148 167
149 private IntPtr _linkJointGroup = IntPtr.Zero; 168 private IntPtr _linkJointGroup = IntPtr.Zero;
@@ -153,7 +172,6 @@ namespace OpenSim.Region.Physics.OdePlugin
153 private List<OdePrim> childrenPrim = new List<OdePrim>(); 172 private List<OdePrim> childrenPrim = new List<OdePrim>();
154 173
155 private bool iscolliding; 174 private bool iscolliding;
156 private bool m_isphysical;
157 private bool m_isSelected; 175 private bool m_isSelected;
158 176
159 internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively 177 internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively
@@ -188,7 +206,7 @@ namespace OpenSim.Region.Physics.OdePlugin
188 internal int m_material = (int)Material.Wood; 206 internal int m_material = (int)Material.Wood;
189 207
190 public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size, 208 public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size,
191 Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode) 209 Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode)
192 { 210 {
193 Name = primName; 211 Name = primName;
194 m_vehicle = new ODEDynamics(); 212 m_vehicle = new ODEDynamics();
@@ -208,9 +226,7 @@ namespace OpenSim.Region.Physics.OdePlugin
208 // m_tensor = parent_scene.bodyMotorJointMaxforceTensor; 226 // m_tensor = parent_scene.bodyMotorJointMaxforceTensor;
209 body_autodisable_frames = parent_scene.bodyFramesAutoDisable; 227 body_autodisable_frames = parent_scene.bodyFramesAutoDisable;
210 228
211
212 prim_geom = IntPtr.Zero; 229 prim_geom = IntPtr.Zero;
213 prev_geom = IntPtr.Zero;
214 230
215 if (!pos.IsFinite()) 231 if (!pos.IsFinite())
216 { 232 {
@@ -233,20 +249,21 @@ namespace OpenSim.Region.Physics.OdePlugin
233 249
234 _orientation = rotation; 250 _orientation = rotation;
235 m_taintrot = _orientation; 251 m_taintrot = _orientation;
236 _mesh = mesh;
237 _pbs = pbs; 252 _pbs = pbs;
238 253
239 _parent_scene = parent_scene; 254 _parent_scene = parent_scene;
240 m_targetSpace = (IntPtr)0; 255 m_targetSpace = (IntPtr)0;
241 256
242 if (pos.Z < 0) 257 if (pos.Z < 0)
243 m_isphysical = false; 258 {
259 IsPhysical = false;
260 }
244 else 261 else
245 { 262 {
246 m_isphysical = pisPhysical; 263 IsPhysical = pisPhysical;
247 // If we're physical, we need to be in the master space for now. 264 // If we're physical, we need to be in the master space for now.
248 // linksets *should* be in a space together.. but are not currently 265 // linksets *should* be in a space together.. but are not currently
249 if (m_isphysical) 266 if (IsPhysical)
250 m_targetSpace = _parent_scene.space; 267 m_targetSpace = _parent_scene.space;
251 } 268 }
252 269
@@ -289,7 +306,7 @@ namespace OpenSim.Region.Physics.OdePlugin
289 // through it while it's selected 306 // through it while it's selected
290 m_collisionscore = 0; 307 m_collisionscore = 0;
291 308
292 if ((m_isphysical && !_zeroFlag) || !value) 309 if ((IsPhysical && !_zeroFlag) || !value)
293 { 310 {
294 m_taintselected = value; 311 m_taintselected = value;
295 _parent_scene.AddPhysicsActorTaint(this); 312 _parent_scene.AddPhysicsActorTaint(this);
@@ -305,15 +322,21 @@ namespace OpenSim.Region.Physics.OdePlugin
305 } 322 }
306 } 323 }
307 324
325 /// <summary>
326 /// Set a new geometry for this prim.
327 /// </summary>
328 /// <param name="geom"></param>
308 public void SetGeom(IntPtr geom) 329 public void SetGeom(IntPtr geom)
309 { 330 {
310 prev_geom = prim_geom;
311 prim_geom = geom; 331 prim_geom = geom;
312//Console.WriteLine("SetGeom to " + prim_geom + " for " + Name); 332//Console.WriteLine("SetGeom to " + prim_geom + " for " + Name);
313 if (prim_geom != IntPtr.Zero) 333 if (prim_geom != IntPtr.Zero)
314 { 334 {
315 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 335 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
316 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 336 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
337
338 _parent_scene.geom_name_map[prim_geom] = Name;
339 _parent_scene.actor_name_map[prim_geom] = this;
317 } 340 }
318 341
319 if (childPrim) 342 if (childPrim)
@@ -332,7 +355,7 @@ namespace OpenSim.Region.Physics.OdePlugin
332 { 355 {
333 if (!childPrim) 356 if (!childPrim)
334 { 357 {
335 if (m_isphysical && Body != IntPtr.Zero) 358 if (IsPhysical && Body != IntPtr.Zero)
336 { 359 {
337 d.BodyEnable(Body); 360 d.BodyEnable(Body);
338 if (m_vehicle.Type != Vehicle.TYPE_NONE) 361 if (m_vehicle.Type != Vehicle.TYPE_NONE)
@@ -347,12 +370,15 @@ namespace OpenSim.Region.Physics.OdePlugin
347 { 370 {
348 m_disabled = true; 371 m_disabled = true;
349 372
350 if (m_isphysical && Body != IntPtr.Zero) 373 if (IsPhysical && Body != IntPtr.Zero)
351 { 374 {
352 d.BodyDisable(Body); 375 d.BodyDisable(Body);
353 } 376 }
354 } 377 }
355 378
379 /// <summary>
380 /// Make a prim subject to physics.
381 /// </summary>
356 public void enableBody() 382 public void enableBody()
357 { 383 {
358 // Don't enable this body if we're a child prim 384 // Don't enable this body if we're a child prim
@@ -728,6 +754,9 @@ namespace OpenSim.Region.Physics.OdePlugin
728 } 754 }
729 } 755 }
730 756
757 /// <summary>
758 /// Stop a prim from being subject to physics.
759 /// </summary>
731 public void disableBody() 760 public void disableBody()
732 { 761 {
733 //this kills the body so things like 'mesh' can re-create it. 762 //this kills the body so things like 'mesh' can re-create it.
@@ -778,6 +807,7 @@ namespace OpenSim.Region.Physics.OdePlugin
778 Body = IntPtr.Zero; 807 Body = IntPtr.Zero;
779 } 808 }
780 } 809 }
810
781 m_disabled = true; 811 m_disabled = true;
782 m_collisionscore = 0; 812 m_collisionscore = 0;
783 } 813 }
@@ -886,7 +916,7 @@ Console.WriteLine("ZProcessTaints for " + Name);
886 } 916 }
887 } 917 }
888 918
889 if (m_taintPhysics != m_isphysical && !(m_taintparent != _parent)) 919 if (m_taintPhysics != IsPhysical && !(m_taintparent != _parent))
890 changePhysicsStatus(timestep); 920 changePhysicsStatus(timestep);
891 921
892 if (!_size.ApproxEquals(m_taintsize, 0f)) 922 if (!_size.ApproxEquals(m_taintsize, 0f))
@@ -968,7 +998,7 @@ Console.WriteLine("ZProcessTaints for " + Name);
968 OdePrim obj = (OdePrim)m_taintparent; 998 OdePrim obj = (OdePrim)m_taintparent;
969 //obj.disableBody(); 999 //obj.disableBody();
970//Console.WriteLine("changelink calls ParentPrim"); 1000//Console.WriteLine("changelink calls ParentPrim");
971 obj.ParentPrim(this); 1001 obj.AddChildPrim(this);
972 1002
973 /* 1003 /*
974 if (obj.Body != (IntPtr)0 && Body != (IntPtr)0 && obj.Body != Body) 1004 if (obj.Body != (IntPtr)0 && Body != (IntPtr)0 && obj.Body != Body)
@@ -1005,14 +1035,16 @@ Console.WriteLine("ZProcessTaints for " + Name);
1005 } 1035 }
1006 1036
1007 _parent = m_taintparent; 1037 _parent = m_taintparent;
1008 m_taintPhysics = m_isphysical; 1038 m_taintPhysics = IsPhysical;
1009 } 1039 }
1010 1040
1011 // I'm the parent 1041 /// <summary>
1012 // prim is the child 1042 /// Add a child prim to this parent prim.
1013 public void ParentPrim(OdePrim prim) 1043 /// </summary>
1044 /// <param name="prim">Child prim</param>
1045 public void AddChildPrim(OdePrim prim)
1014 { 1046 {
1015//Console.WriteLine("ParentPrim " + Name); 1047//Console.WriteLine("AddChildPrim " + Name);
1016 if (this.m_localID != prim.m_localID) 1048 if (this.m_localID != prim.m_localID)
1017 { 1049 {
1018 if (Body == IntPtr.Zero) 1050 if (Body == IntPtr.Zero)
@@ -1035,7 +1067,6 @@ Console.WriteLine("ZProcessTaints for " + Name);
1035 d.MassSetZero(out m2); 1067 d.MassSetZero(out m2);
1036 d.MassSetBoxTotal(out m2, prim.CalculateMass(), prm._size.X, prm._size.Y, prm._size.Z); 1068 d.MassSetBoxTotal(out m2, prim.CalculateMass(), prm._size.X, prm._size.Y, prm._size.Z);
1037 1069
1038
1039 d.Quaternion quat = new d.Quaternion(); 1070 d.Quaternion quat = new d.Quaternion();
1040 quat.W = prm._orientation.W; 1071 quat.W = prm._orientation.W;
1041 quat.X = prm._orientation.X; 1072 quat.X = prm._orientation.X;
@@ -1105,6 +1136,7 @@ Console.WriteLine("ZProcessTaints for " + Name);
1105 prm.Body = Body; 1136 prm.Body = Body;
1106 _parent_scene.addActivePrim(prm); 1137 _parent_scene.addActivePrim(prm);
1107 } 1138 }
1139
1108 m_collisionCategories |= CollisionCategories.Body; 1140 m_collisionCategories |= CollisionCategories.Body;
1109 m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); 1141 m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
1110 1142
@@ -1113,7 +1145,6 @@ Console.WriteLine("ZProcessTaints for " + Name);
1113//Console.WriteLine(" Post GeomSetCategoryBits 2"); 1145//Console.WriteLine(" Post GeomSetCategoryBits 2");
1114 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 1146 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1115 1147
1116
1117 d.Quaternion quat2 = new d.Quaternion(); 1148 d.Quaternion quat2 = new d.Quaternion();
1118 quat2.W = _orientation.W; 1149 quat2.W = _orientation.W;
1119 quat2.X = _orientation.X; 1150 quat2.X = _orientation.X;
@@ -1135,7 +1166,6 @@ Console.WriteLine("ZProcessTaints for " + Name);
1135 d.BodySetAutoDisableFlag(Body, true); 1166 d.BodySetAutoDisableFlag(Body, true);
1136 d.BodySetAutoDisableSteps(Body, body_autodisable_frames); 1167 d.BodySetAutoDisableSteps(Body, body_autodisable_frames);
1137 1168
1138
1139 m_interpenetrationcount = 0; 1169 m_interpenetrationcount = 0;
1140 m_collisionscore = 0; 1170 m_collisionscore = 0;
1141 m_disabled = false; 1171 m_disabled = false;
@@ -1146,7 +1176,9 @@ Console.WriteLine("ZProcessTaints for " + Name);
1146 createAMotor(m_angularlock); 1176 createAMotor(m_angularlock);
1147 } 1177 }
1148 d.BodySetPosition(Body, Position.X, Position.Y, Position.Z); 1178 d.BodySetPosition(Body, Position.X, Position.Y, Position.Z);
1149 if (m_vehicle.Type != Vehicle.TYPE_NONE) m_vehicle.Enable(Body, _parent_scene); 1179 if (m_vehicle.Type != Vehicle.TYPE_NONE)
1180 m_vehicle.Enable(Body, _parent_scene);
1181
1150 _parent_scene.addActivePrim(this); 1182 _parent_scene.addActivePrim(this);
1151 } 1183 }
1152 } 1184 }
@@ -1156,7 +1188,7 @@ Console.WriteLine("ZProcessTaints for " + Name);
1156 1188
1157 private void ChildSetGeom(OdePrim odePrim) 1189 private void ChildSetGeom(OdePrim odePrim)
1158 { 1190 {
1159 //if (m_isphysical && Body != IntPtr.Zero) 1191 //if (IsPhysical && Body != IntPtr.Zero)
1160 lock (childrenPrim) 1192 lock (childrenPrim)
1161 { 1193 {
1162 foreach (OdePrim prm in childrenPrim) 1194 foreach (OdePrim prm in childrenPrim)
@@ -1172,7 +1204,6 @@ Console.WriteLine("ZProcessTaints for " + Name);
1172 } 1204 }
1173 disableBody(); 1205 disableBody();
1174 1206
1175
1176 if (Body != IntPtr.Zero) 1207 if (Body != IntPtr.Zero)
1177 { 1208 {
1178 _parent_scene.remActivePrim(this); 1209 _parent_scene.remActivePrim(this);
@@ -1183,10 +1214,9 @@ Console.WriteLine("ZProcessTaints for " + Name);
1183 foreach (OdePrim prm in childrenPrim) 1214 foreach (OdePrim prm in childrenPrim)
1184 { 1215 {
1185//Console.WriteLine("ChildSetGeom calls ParentPrim"); 1216//Console.WriteLine("ChildSetGeom calls ParentPrim");
1186 ParentPrim(prm); 1217 AddChildPrim(prm);
1187 } 1218 }
1188 } 1219 }
1189
1190 } 1220 }
1191 1221
1192 private void ChildDelink(OdePrim odePrim) 1222 private void ChildDelink(OdePrim odePrim)
@@ -1223,7 +1253,7 @@ Console.WriteLine("ZProcessTaints for " + Name);
1223 foreach (OdePrim prm in childrenPrim) 1253 foreach (OdePrim prm in childrenPrim)
1224 { 1254 {
1225//Console.WriteLine("ChildDelink calls ParentPrim"); 1255//Console.WriteLine("ChildDelink calls ParentPrim");
1226 ParentPrim(prm); 1256 AddChildPrim(prm);
1227 } 1257 }
1228 } 1258 }
1229 } 1259 }
@@ -1257,7 +1287,7 @@ Console.WriteLine("ZProcessTaints for " + Name);
1257 // first 50 again. then the last 50 are disabled. then the first 50, which were just woken 1287 // first 50 again. then the last 50 are disabled. then the first 50, which were just woken
1258 // up, start simulating again, which in turn wakes up the last 50. 1288 // up, start simulating again, which in turn wakes up the last 50.
1259 1289
1260 if (m_isphysical) 1290 if (IsPhysical)
1261 { 1291 {
1262 disableBodySoft(); 1292 disableBodySoft();
1263 } 1293 }
@@ -1268,7 +1298,7 @@ Console.WriteLine("ZProcessTaints for " + Name);
1268 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 1298 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1269 } 1299 }
1270 1300
1271 if (m_isphysical) 1301 if (IsPhysical)
1272 { 1302 {
1273 disableBodySoft(); 1303 disableBodySoft();
1274 } 1304 }
@@ -1277,7 +1307,7 @@ Console.WriteLine("ZProcessTaints for " + Name);
1277 { 1307 {
1278 m_collisionCategories = CollisionCategories.Geom; 1308 m_collisionCategories = CollisionCategories.Geom;
1279 1309
1280 if (m_isphysical) 1310 if (IsPhysical)
1281 m_collisionCategories |= CollisionCategories.Body; 1311 m_collisionCategories |= CollisionCategories.Body;
1282 1312
1283 m_collisionFlags = m_default_collisionFlags; 1313 m_collisionFlags = m_default_collisionFlags;
@@ -1292,7 +1322,8 @@ Console.WriteLine("ZProcessTaints for " + Name);
1292 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 1322 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1293 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 1323 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1294 } 1324 }
1295 if (m_isphysical) 1325
1326 if (IsPhysical)
1296 { 1327 {
1297 if (Body != IntPtr.Zero) 1328 if (Body != IntPtr.Zero)
1298 { 1329 {
@@ -1311,7 +1342,7 @@ Console.WriteLine("ZProcessTaints for " + Name);
1311 { 1342 {
1312 m_taintposition = _position; 1343 m_taintposition = _position;
1313 m_taintrot = _orientation; 1344 m_taintrot = _orientation;
1314 m_taintPhysics = m_isphysical; 1345 m_taintPhysics = IsPhysical;
1315 m_taintselected = m_isSelected; 1346 m_taintselected = m_isSelected;
1316 m_taintsize = _size; 1347 m_taintsize = _size;
1317 m_taintshape = false; 1348 m_taintshape = false;
@@ -1320,14 +1351,19 @@ Console.WriteLine("ZProcessTaints for " + Name);
1320 m_taintVelocity = Vector3.Zero; 1351 m_taintVelocity = Vector3.Zero;
1321 } 1352 }
1322 1353
1323 public void CreateGeom(IntPtr m_targetSpace, IMesh _mesh) 1354 /// <summary>
1355 /// Create a geometry for the given mesh in the given target space.
1356 /// </summary>
1357 /// <param name="m_targetSpace"></param>
1358 /// <param name="mesh">If null, then a mesh is used that is based on the profile shape data.</param>
1359 public void CreateGeom(IntPtr m_targetSpace, IMesh mesh)
1324 { 1360 {
1325#if SPAM 1361#if SPAM
1326Console.WriteLine("CreateGeom:"); 1362Console.WriteLine("CreateGeom:");
1327#endif 1363#endif
1328 if (_mesh != null) 1364 if (mesh != null)
1329 { 1365 {
1330 setMesh(_parent_scene, _mesh); 1366 setMesh(_parent_scene, mesh);
1331 } 1367 }
1332 else 1368 else
1333 { 1369 {
@@ -1400,6 +1436,39 @@ Console.WriteLine("CreateGeom:");
1400 } 1436 }
1401 } 1437 }
1402 1438
1439 /// <summary>
1440 /// Remove the existing geom from this prim.
1441 /// </summary>
1442 /// <param name="m_targetSpace"></param>
1443 /// <param name="mesh">If null, then a mesh is used that is based on the profile shape data.</param>
1444 /// <returns>true if the geom was successfully removed, false if it was already gone or the remove failed.</returns>
1445 public bool RemoveGeom()
1446 {
1447 if (prim_geom != IntPtr.Zero)
1448 {
1449 try
1450 {
1451 _parent_scene.geom_name_map.Remove(prim_geom);
1452 _parent_scene.actor_name_map.Remove(prim_geom);
1453 d.GeomDestroy(prim_geom);
1454 prim_geom = IntPtr.Zero;
1455 }
1456 catch (System.AccessViolationException)
1457 {
1458 prim_geom = IntPtr.Zero;
1459 m_log.ErrorFormat("[PHYSICS]: PrimGeom dead for {0}", Name);
1460
1461 return false;
1462 }
1463
1464 return true;
1465 }
1466 else
1467 {
1468 return false;
1469 }
1470 }
1471
1403 public void changeadd(float timestep) 1472 public void changeadd(float timestep)
1404 { 1473 {
1405 int[] iprimspaceArrItem = _parent_scene.calculateSpaceArrayItemFromPos(_position); 1474 int[] iprimspaceArrItem = _parent_scene.calculateSpaceArrayItemFromPos(_position);
@@ -1410,15 +1479,14 @@ Console.WriteLine("CreateGeom:");
1410 1479
1411 m_targetSpace = targetspace; 1480 m_targetSpace = targetspace;
1412 1481
1413 if (_mesh == null) 1482 IMesh mesh = null;
1483
1484 if (_parent_scene.needsMeshing(_pbs))
1414 { 1485 {
1415 if (_parent_scene.needsMeshing(_pbs)) 1486 // Don't need to re-enable body.. it's done in SetMesh
1416 { 1487 mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical);
1417 // Don't need to re-enable body.. it's done in SetMesh 1488 // createmesh returns null when it's a shape that isn't a cube.
1418 _mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical); 1489 // m_log.Debug(m_localID);
1419 // createmesh returns null when it's a shape that isn't a cube.
1420 // m_log.Debug(m_localID);
1421 }
1422 } 1490 }
1423 1491
1424 lock (_parent_scene.OdeLock) 1492 lock (_parent_scene.OdeLock)
@@ -1426,7 +1494,7 @@ Console.WriteLine("CreateGeom:");
1426#if SPAM 1494#if SPAM
1427Console.WriteLine("changeadd 1"); 1495Console.WriteLine("changeadd 1");
1428#endif 1496#endif
1429 CreateGeom(m_targetSpace, _mesh); 1497 CreateGeom(m_targetSpace, mesh);
1430 1498
1431 if (prim_geom != IntPtr.Zero) 1499 if (prim_geom != IntPtr.Zero)
1432 { 1500 {
@@ -1439,15 +1507,12 @@ Console.WriteLine("changeadd 1");
1439 d.GeomSetQuaternion(prim_geom, ref myrot); 1507 d.GeomSetQuaternion(prim_geom, ref myrot);
1440 } 1508 }
1441 1509
1442 if (m_isphysical && Body == IntPtr.Zero) 1510 if (IsPhysical && Body == IntPtr.Zero)
1443 { 1511 {
1444 enableBody(); 1512 enableBody();
1445 } 1513 }
1446 } 1514 }
1447 1515
1448 _parent_scene.geom_name_map[prim_geom] = this.Name;
1449 _parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this;
1450
1451 changeSelectedStatus(timestep); 1516 changeSelectedStatus(timestep);
1452 1517
1453 m_taintadd = false; 1518 m_taintadd = false;
@@ -1455,9 +1520,8 @@ Console.WriteLine("changeadd 1");
1455 1520
1456 public void changemove(float timestep) 1521 public void changemove(float timestep)
1457 { 1522 {
1458 if (m_isphysical) 1523 if (IsPhysical)
1459 { 1524 {
1460
1461 if (!m_disabled && !m_taintremove && !childPrim) 1525 if (!m_disabled && !m_taintremove && !childPrim)
1462 { 1526 {
1463 if (Body == IntPtr.Zero) 1527 if (Body == IntPtr.Zero)
@@ -1789,7 +1853,7 @@ Console.WriteLine(" JointCreateFixed");
1789 { 1853 {
1790 // KF: If this is a root prim do BodySet 1854 // KF: If this is a root prim do BodySet
1791 d.BodySetQuaternion(Body, ref myrot); 1855 d.BodySetQuaternion(Body, ref myrot);
1792 if (m_isphysical) 1856 if (IsPhysical)
1793 { 1857 {
1794 if (!m_angularlock.ApproxEquals(Vector3.One, 0f)) 1858 if (!m_angularlock.ApproxEquals(Vector3.One, 0f))
1795 createAMotor(m_angularlock); 1859 createAMotor(m_angularlock);
@@ -1826,7 +1890,7 @@ Console.WriteLine(" JointCreateFixed");
1826 1890
1827 public void changePhysicsStatus(float timestep) 1891 public void changePhysicsStatus(float timestep)
1828 { 1892 {
1829 if (m_isphysical == true) 1893 if (IsPhysical)
1830 { 1894 {
1831 if (Body == IntPtr.Zero) 1895 if (Body == IntPtr.Zero)
1832 { 1896 {
@@ -1846,25 +1910,12 @@ Console.WriteLine(" JointCreateFixed");
1846 { 1910 {
1847 if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim) 1911 if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim)
1848 { 1912 {
1849 1913 RemoveGeom();
1850 1914
1851 if (prim_geom != IntPtr.Zero)
1852 {
1853 try
1854 {
1855 d.GeomDestroy(prim_geom);
1856 prim_geom = IntPtr.Zero;
1857 _mesh = null;
1858 }
1859 catch (System.AccessViolationException)
1860 {
1861 prim_geom = IntPtr.Zero;
1862 m_log.ErrorFormat("[PHYSICS]: PrimGeom dead for {0}", Name);
1863 }
1864 }
1865//Console.WriteLine("changePhysicsStatus for " + Name); 1915//Console.WriteLine("changePhysicsStatus for " + Name);
1866 changeadd(2f); 1916 changeadd(2f);
1867 } 1917 }
1918
1868 if (childPrim) 1919 if (childPrim)
1869 { 1920 {
1870 if (_parent != null) 1921 if (_parent != null)
@@ -1883,7 +1934,7 @@ Console.WriteLine(" JointCreateFixed");
1883 changeSelectedStatus(timestep); 1934 changeSelectedStatus(timestep);
1884 1935
1885 resetCollisionAccounting(); 1936 resetCollisionAccounting();
1886 m_taintPhysics = m_isphysical; 1937 m_taintPhysics = IsPhysical;
1887 } 1938 }
1888 1939
1889 public void changesize(float timestamp) 1940 public void changesize(float timestamp)
@@ -1892,18 +1943,10 @@ Console.WriteLine(" JointCreateFixed");
1892 m_log.DebugFormat("[ODE PRIM]: Called changesize"); 1943 m_log.DebugFormat("[ODE PRIM]: Called changesize");
1893#endif 1944#endif
1894 1945
1895 string oldname = _parent_scene.geom_name_map[prim_geom];
1896
1897 if (_size.X <= 0) _size.X = 0.01f; 1946 if (_size.X <= 0) _size.X = 0.01f;
1898 if (_size.Y <= 0) _size.Y = 0.01f; 1947 if (_size.Y <= 0) _size.Y = 0.01f;
1899 if (_size.Z <= 0) _size.Z = 0.01f; 1948 if (_size.Z <= 0) _size.Z = 0.01f;
1900 1949
1901 // Cleanup of old prim geometry
1902 if (_mesh != null)
1903 {
1904 // TODO: Cleanup meshing here
1905 }
1906
1907 //kill body to rebuild 1950 //kill body to rebuild
1908 if (IsPhysical && Body != IntPtr.Zero) 1951 if (IsPhysical && Body != IntPtr.Zero)
1909 { 1952 {
@@ -1927,10 +1970,12 @@ Console.WriteLine(" JointCreateFixed");
1927 d.SpaceRemove(m_targetSpace, prim_geom); 1970 d.SpaceRemove(m_targetSpace, prim_geom);
1928 } 1971 }
1929 1972
1930 d.GeomDestroy(prim_geom); 1973 RemoveGeom();
1931 prim_geom = IntPtr.Zero; 1974
1932 // we don't need to do space calculation because the client sends a position update also. 1975 // we don't need to do space calculation because the client sends a position update also.
1933 1976
1977 IMesh mesh = null;
1978
1934 // Construction of new prim 1979 // Construction of new prim
1935 if (_parent_scene.needsMeshing(_pbs)) 1980 if (_parent_scene.needsMeshing(_pbs))
1936 { 1981 {
@@ -1940,27 +1985,11 @@ Console.WriteLine(" JointCreateFixed");
1940 meshlod = _parent_scene.MeshSculptphysicalLOD; 1985 meshlod = _parent_scene.MeshSculptphysicalLOD;
1941 // Don't need to re-enable body.. it's done in SetMesh 1986 // Don't need to re-enable body.. it's done in SetMesh
1942 1987
1943 IMesh mesh = null;
1944
1945 if (_parent_scene.needsMeshing(_pbs)) 1988 if (_parent_scene.needsMeshing(_pbs))
1946 mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); 1989 mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, meshlod, IsPhysical);
1947
1948#if SPAM
1949Console.WriteLine("changesize 1");
1950#endif
1951 CreateGeom(m_targetSpace, mesh);
1952 }
1953 else
1954 {
1955 _mesh = null;
1956
1957#if SPAM
1958Console.WriteLine("changesize 2");
1959#endif
1960
1961 CreateGeom(m_targetSpace, _mesh);
1962 } 1990 }
1963 1991
1992 CreateGeom(m_targetSpace, mesh);
1964 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); 1993 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
1965 d.Quaternion myrot = new d.Quaternion(); 1994 d.Quaternion myrot = new d.Quaternion();
1966 myrot.X = _orientation.X; 1995 myrot.X = _orientation.X;
@@ -1978,8 +2007,6 @@ Console.WriteLine("changesize 2");
1978 d.BodyEnable(Body); 2007 d.BodyEnable(Body);
1979 } 2008 }
1980 2009
1981 _parent_scene.geom_name_map[prim_geom] = oldname;
1982
1983 changeSelectedStatus(timestamp); 2010 changeSelectedStatus(timestamp);
1984 if (childPrim) 2011 if (childPrim)
1985 { 2012 {
@@ -2013,8 +2040,6 @@ Console.WriteLine("changesize 2");
2013 2040
2014 public void changeshape(float timestamp) 2041 public void changeshape(float timestamp)
2015 { 2042 {
2016 string oldname = _parent_scene.geom_name_map[prim_geom];
2017
2018 // Cleanup of old prim geometry and Bodies 2043 // Cleanup of old prim geometry and Bodies
2019 if (IsPhysical && Body != IntPtr.Zero) 2044 if (IsPhysical && Body != IntPtr.Zero)
2020 { 2045 {
@@ -2031,23 +2056,17 @@ Console.WriteLine("changesize 2");
2031 disableBody(); 2056 disableBody();
2032 } 2057 }
2033 } 2058 }
2034 try
2035 {
2036 d.GeomDestroy(prim_geom);
2037 }
2038 catch (System.AccessViolationException)
2039 {
2040 prim_geom = IntPtr.Zero;
2041 m_log.ErrorFormat("[PHYSICS]: PrimGeom dead for {0}", Name);
2042 }
2043 2059
2044 prim_geom = IntPtr.Zero; 2060 RemoveGeom();
2061
2045 // we don't need to do space calculation because the client sends a position update also. 2062 // we don't need to do space calculation because the client sends a position update also.
2046 if (_size.X <= 0) _size.X = 0.01f; 2063 if (_size.X <= 0) _size.X = 0.01f;
2047 if (_size.Y <= 0) _size.Y = 0.01f; 2064 if (_size.Y <= 0) _size.Y = 0.01f;
2048 if (_size.Z <= 0) _size.Z = 0.01f; 2065 if (_size.Z <= 0) _size.Z = 0.01f;
2049 // Construction of new prim 2066 // Construction of new prim
2050 2067
2068 IMesh mesh = null;
2069
2051 if (_parent_scene.needsMeshing(_pbs)) 2070 if (_parent_scene.needsMeshing(_pbs))
2052 { 2071 {
2053 // Don't need to re-enable body.. it's done in CreateMesh 2072 // Don't need to re-enable body.. it's done in CreateMesh
@@ -2057,22 +2076,10 @@ Console.WriteLine("changesize 2");
2057 meshlod = _parent_scene.MeshSculptphysicalLOD; 2076 meshlod = _parent_scene.MeshSculptphysicalLOD;
2058 2077
2059 // createmesh returns null when it doesn't mesh. 2078 // createmesh returns null when it doesn't mesh.
2060 IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); 2079 mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, meshlod, IsPhysical);
2061#if SPAM
2062Console.WriteLine("changeshape needed meshing");
2063#endif
2064 CreateGeom(m_targetSpace, mesh);
2065 }
2066 else
2067 {
2068 _mesh = null;
2069
2070#if SPAM
2071Console.WriteLine("changeshape not need meshing");
2072#endif
2073 CreateGeom(m_targetSpace, null);
2074 } 2080 }
2075 2081
2082 CreateGeom(m_targetSpace, mesh);
2076 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); 2083 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
2077 d.Quaternion myrot = new d.Quaternion(); 2084 d.Quaternion myrot = new d.Quaternion();
2078 //myrot.W = _orientation.w; 2085 //myrot.W = _orientation.w;
@@ -2093,7 +2100,6 @@ Console.WriteLine("changeshape not need meshing");
2093 d.BodyEnable(Body); 2100 d.BodyEnable(Body);
2094 } 2101 }
2095 } 2102 }
2096 _parent_scene.geom_name_map[prim_geom] = oldname;
2097 2103
2098 changeSelectedStatus(timestamp); 2104 changeSelectedStatus(timestamp);
2099 if (childPrim) 2105 if (childPrim)
@@ -2216,16 +2222,6 @@ Console.WriteLine("changeshape not need meshing");
2216 m_taintVelocity = Vector3.Zero; 2222 m_taintVelocity = Vector3.Zero;
2217 } 2223 }
2218 2224
2219 public override bool IsPhysical
2220 {
2221 get { return m_isphysical; }
2222 set {
2223 m_isphysical = value;
2224 if (!m_isphysical) // Zero the remembered last velocity
2225 m_lastVelocity = Vector3.Zero;
2226 }
2227 }
2228
2229 public void setPrimForRemoval() 2225 public void setPrimForRemoval()
2230 { 2226 {
2231 m_taintremove = true; 2227 m_taintremove = true;
@@ -2404,7 +2400,7 @@ Console.WriteLine("changeshape not need meshing");
2404 { 2400 {
2405 get 2401 get
2406 { 2402 {
2407 if (!m_isphysical || Body == IntPtr.Zero) 2403 if (!IsPhysical || Body == IntPtr.Zero)
2408 return Vector3.Zero; 2404 return Vector3.Zero;
2409 2405
2410 return _torque; 2406 return _torque;
@@ -2986,12 +2982,12 @@ Console.WriteLine("changeshape not need meshing");
2986 public override void SubscribeEvents(int ms) 2982 public override void SubscribeEvents(int ms)
2987 { 2983 {
2988 m_eventsubscription = ms; 2984 m_eventsubscription = ms;
2989 _parent_scene.addCollisionEventReporting(this); 2985 _parent_scene.AddCollisionEventReporting(this);
2990 } 2986 }
2991 2987
2992 public override void UnSubscribeEvents() 2988 public override void UnSubscribeEvents()
2993 { 2989 {
2994 _parent_scene.remCollisionEventReporting(this); 2990 _parent_scene.RemoveCollisionEventReporting(this);
2995 m_eventsubscription = 0; 2991 m_eventsubscription = 0;
2996 } 2992 }
2997 2993
@@ -2999,6 +2995,7 @@ Console.WriteLine("changeshape not need meshing");
2999 { 2995 {
3000 if (CollisionEventsThisFrame == null) 2996 if (CollisionEventsThisFrame == null)
3001 CollisionEventsThisFrame = new CollisionEventUpdate(); 2997 CollisionEventsThisFrame = new CollisionEventUpdate();
2998
3002 CollisionEventsThisFrame.addCollider(CollidedWith, contact); 2999 CollisionEventsThisFrame.addCollider(CollidedWith, contact);
3003 } 3000 }
3004 3001
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
index a307469..6e603e8 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
@@ -100,7 +100,7 @@ namespace OpenSim.Region.Physics.OdePlugin
100 Rubber = 6 100 Rubber = 6
101 } 101 }
102 102
103 public sealed class OdeScene : PhysicsScene 103 public class OdeScene : PhysicsScene
104 { 104 {
105 private readonly ILog m_log; 105 private readonly ILog m_log;
106 // private Dictionary<string, sCollisionData> m_storedCollisions = new Dictionary<string, sCollisionData>(); 106 // private Dictionary<string, sCollisionData> m_storedCollisions = new Dictionary<string, sCollisionData>();
@@ -198,7 +198,12 @@ namespace OpenSim.Region.Physics.OdePlugin
198 private readonly List<OdePrim> _taintedPrimL = new List<OdePrim>(); 198 private readonly List<OdePrim> _taintedPrimL = new List<OdePrim>();
199 private readonly HashSet<OdeCharacter> _taintedActors = new HashSet<OdeCharacter>(); 199 private readonly HashSet<OdeCharacter> _taintedActors = new HashSet<OdeCharacter>();
200 private readonly List<d.ContactGeom> _perloopContact = new List<d.ContactGeom>(); 200 private readonly List<d.ContactGeom> _perloopContact = new List<d.ContactGeom>();
201
202 /// <summary>
203 /// A list of actors that should receive collision events.
204 /// </summary>
201 private readonly List<PhysicsActor> _collisionEventPrim = new List<PhysicsActor>(); 205 private readonly List<PhysicsActor> _collisionEventPrim = new List<PhysicsActor>();
206
202 private readonly HashSet<OdeCharacter> _badCharacter = new HashSet<OdeCharacter>(); 207 private readonly HashSet<OdeCharacter> _badCharacter = new HashSet<OdeCharacter>();
203 public Dictionary<IntPtr, String> geom_name_map = new Dictionary<IntPtr, String>(); 208 public Dictionary<IntPtr, String> geom_name_map = new Dictionary<IntPtr, String>();
204 public Dictionary<IntPtr, PhysicsActor> actor_name_map = new Dictionary<IntPtr, PhysicsActor>(); 209 public Dictionary<IntPtr, PhysicsActor> actor_name_map = new Dictionary<IntPtr, PhysicsActor>();
@@ -299,7 +304,6 @@ namespace OpenSim.Region.Physics.OdePlugin
299 // Create the world and the first space 304 // Create the world and the first space
300 world = d.WorldCreate(); 305 world = d.WorldCreate();
301 space = d.HashSpaceCreate(IntPtr.Zero); 306 space = d.HashSpaceCreate(IntPtr.Zero);
302
303 307
304 contactgroup = d.JointGroupCreate(0); 308 contactgroup = d.JointGroupCreate(0);
305 //contactgroup 309 //contactgroup
@@ -952,7 +956,6 @@ namespace OpenSim.Region.Physics.OdePlugin
952 character.SetPidStatus(true); 956 character.SetPidStatus(true);
953 } 957 }
954 } 958 }
955
956 959
957 if (p1.PhysicsActorType == (int) ActorTypes.Agent) 960 if (p1.PhysicsActorType == (int) ActorTypes.Agent)
958 { 961 {
@@ -1053,9 +1056,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1053 { 1056 {
1054 joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]); 1057 joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]);
1055 m_global_contactcount++; 1058 m_global_contactcount++;
1056
1057 } 1059 }
1058
1059 } 1060 }
1060 else 1061 else
1061 { 1062 {
@@ -1078,7 +1079,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1078 { 1079 {
1079 joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]); 1080 joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]);
1080 m_global_contactcount++; 1081 m_global_contactcount++;
1081
1082 } 1082 }
1083 } 1083 }
1084 } 1084 }
@@ -1290,6 +1290,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1290 1290
1291 //returncollisions = true; 1291 //returncollisions = true;
1292 break; 1292 break;
1293
1293 case ActorTypes.Prim: 1294 case ActorTypes.Prim:
1294 if (p1 is OdePrim) 1295 if (p1 is OdePrim)
1295 { 1296 {
@@ -1317,6 +1318,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1317 1318
1318 cc2.AddCollisionEvent(obj2LocalID, contact); 1319 cc2.AddCollisionEvent(obj2LocalID, contact);
1319 break; 1320 break;
1321
1320 case ActorTypes.Prim: 1322 case ActorTypes.Prim:
1321 1323
1322 if (p2 is OdePrim) 1324 if (p2 is OdePrim)
@@ -1421,18 +1423,18 @@ namespace OpenSim.Region.Physics.OdePlugin
1421 1423
1422 public int TriCallback(IntPtr trimesh, IntPtr refObject, int triangleIndex) 1424 public int TriCallback(IntPtr trimesh, IntPtr refObject, int triangleIndex)
1423 { 1425 {
1424 String name1 = null; 1426// String name1 = null;
1425 String name2 = null; 1427// String name2 = null;
1426 1428//
1427 if (!geom_name_map.TryGetValue(trimesh, out name1)) 1429// if (!geom_name_map.TryGetValue(trimesh, out name1))
1428 { 1430// {
1429 name1 = "null"; 1431// name1 = "null";
1430 } 1432// }
1431 1433//
1432 if (!geom_name_map.TryGetValue(refObject, out name2)) 1434// if (!geom_name_map.TryGetValue(refObject, out name2))
1433 { 1435// {
1434 name2 = "null"; 1436// name2 = "null";
1435 } 1437// }
1436 1438
1437 // m_log.InfoFormat("TriCallback: A collision was detected between {1} and {2}. Index was {3}", 0, name1, name2, triangleIndex); 1439 // m_log.InfoFormat("TriCallback: A collision was detected between {1} and {2}. Index was {3}", 0, name1, name2, triangleIndex);
1438 1440
@@ -1604,7 +1606,11 @@ namespace OpenSim.Region.Physics.OdePlugin
1604 } 1606 }
1605// End recovered. Kitto Flora 1607// End recovered. Kitto Flora
1606 1608
1607 public void addCollisionEventReporting(PhysicsActor obj) 1609 /// <summary>
1610 /// Add actor to the list that should receive collision events in the simulate loop.
1611 /// </summary>
1612 /// <param name="obj"></param>
1613 public void AddCollisionEventReporting(PhysicsActor obj)
1608 { 1614 {
1609 lock (_collisionEventPrim) 1615 lock (_collisionEventPrim)
1610 { 1616 {
@@ -1613,7 +1619,11 @@ namespace OpenSim.Region.Physics.OdePlugin
1613 } 1619 }
1614 } 1620 }
1615 1621
1616 public void remCollisionEventReporting(PhysicsActor obj) 1622 /// <summary>
1623 /// Remove actor from the list that should receive collision events in the simulate loop.
1624 /// </summary>
1625 /// <param name="obj"></param>
1626 public void RemoveCollisionEventReporting(PhysicsActor obj)
1617 { 1627 {
1618 lock (_collisionEventPrim) 1628 lock (_collisionEventPrim)
1619 { 1629 {
@@ -1677,7 +1687,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1677 } 1687 }
1678 1688
1679 private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation, 1689 private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation,
1680 IMesh mesh, PrimitiveBaseShape pbs, bool isphysical, uint localID) 1690 PrimitiveBaseShape pbs, bool isphysical, uint localID)
1681 { 1691 {
1682 Vector3 pos = position; 1692 Vector3 pos = position;
1683 Vector3 siz = size; 1693 Vector3 siz = size;
@@ -1686,7 +1696,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1686 OdePrim newPrim; 1696 OdePrim newPrim;
1687 lock (OdeLock) 1697 lock (OdeLock)
1688 { 1698 {
1689 newPrim = new OdePrim(name, this, pos, siz, rot, mesh, pbs, isphysical, ode); 1699 newPrim = new OdePrim(name, this, pos, siz, rot, pbs, isphysical, ode);
1690 1700
1691 lock (_prims) 1701 lock (_prims)
1692 _prims.Add(newPrim); 1702 _prims.Add(newPrim);
@@ -1714,28 +1724,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1714 m_log.DebugFormat("[PHYSICS]: Adding physics actor to {0}", primName); 1724 m_log.DebugFormat("[PHYSICS]: Adding physics actor to {0}", primName);
1715#endif 1725#endif
1716 1726
1717 PhysicsActor result; 1727 return AddPrim(primName, position, size, rotation, pbs, isPhysical, localid);
1718 IMesh mesh = null;
1719
1720 // Don't create the mesh here - wait until the mesh data is loaded from the asset store.
1721// if (needsMeshing(pbs))
1722// {
1723// try
1724// {
1725// mesh = mesher.CreateMesh(primName, pbs, size, 32f, isPhysical);
1726// }
1727// catch(Exception e)
1728// {
1729// m_log.ErrorFormat("[PHYSICS]: Exception while meshing prim {0}.", primName);
1730// m_log.Debug(e.ToString());
1731// mesh = null;
1732// return null;
1733// }
1734// }
1735
1736 result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical, localid);
1737
1738 return result;
1739 } 1728 }
1740 1729
1741 public override float TimeDilation 1730 public override float TimeDilation
@@ -2105,6 +2094,8 @@ namespace OpenSim.Region.Physics.OdePlugin
2105 2094
2106 public override void RemovePrim(PhysicsActor prim) 2095 public override void RemovePrim(PhysicsActor prim)
2107 { 2096 {
2097 // As with all ODE physics operations, we don't remove the prim immediately but signal that it should be
2098 // removed in the next physics simulate pass.
2108 if (prim is OdePrim) 2099 if (prim is OdePrim)
2109 { 2100 {
2110 lock (OdeLock) 2101 lock (OdeLock)
@@ -2121,6 +2112,9 @@ namespace OpenSim.Region.Physics.OdePlugin
2121 /// <summary> 2112 /// <summary>
2122 /// This is called from within simulate but outside the locked portion 2113 /// This is called from within simulate but outside the locked portion
2123 /// We need to do our own locking here 2114 /// We need to do our own locking here
2115 /// (Note: As of 20110801 this no longer appears to be true - this is being called within lock (odeLock) in
2116 /// Simulate() -- justincc).
2117 ///
2124 /// Essentially, we need to remove the prim from our space segment, whatever segment it's in. 2118 /// Essentially, we need to remove the prim from our space segment, whatever segment it's in.
2125 /// 2119 ///
2126 /// If there are no more prim in the segment, we need to empty (spacedestroy)the segment and reclaim memory 2120 /// If there are no more prim in the segment, we need to empty (spacedestroy)the segment and reclaim memory
@@ -2132,7 +2126,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2132//Console.WriteLine("RemovePrimThreadLocked " + prim.m_primName); 2126//Console.WriteLine("RemovePrimThreadLocked " + prim.m_primName);
2133 lock (prim) 2127 lock (prim)
2134 { 2128 {
2135 remCollisionEventReporting(prim); 2129 RemoveCollisionEventReporting(prim);
2136 lock (ode) 2130 lock (ode)
2137 { 2131 {
2138 if (prim.prim_geom != IntPtr.Zero) 2132 if (prim.prim_geom != IntPtr.Zero)
@@ -2177,24 +2171,12 @@ namespace OpenSim.Region.Physics.OdePlugin
2177 //} 2171 //}
2178 //} 2172 //}
2179 //m_log.Warn(prim.prim_geom); 2173 //m_log.Warn(prim.prim_geom);
2180 try 2174
2181 { 2175 if (!prim.RemoveGeom())
2182 if (prim.prim_geom != IntPtr.Zero) 2176 m_log.Warn("[PHYSICS]: Unable to remove prim from physics scene");
2183 { 2177
2184 d.GeomDestroy(prim.prim_geom);
2185 prim.prim_geom = IntPtr.Zero;
2186 }
2187 else
2188 {
2189 m_log.Warn("[PHYSICS]: Unable to remove prim from physics scene");
2190 }
2191 }
2192 catch (AccessViolationException)
2193 {
2194 m_log.Info("[PHYSICS]: Couldn't remove prim from physics scene, it was already be removed.");
2195 }
2196 lock (_prims) 2178 lock (_prims)
2197 _prims.Remove(prim); 2179 _prims.Remove(prim);
2198 2180
2199 //If there are no more geometries in the sub-space, we don't need it in the main space anymore 2181 //If there are no more geometries in the sub-space, we don't need it in the main space anymore
2200 //if (d.SpaceGetNumGeoms(prim.m_targetSpace) == 0) 2182 //if (d.SpaceGetNumGeoms(prim.m_targetSpace) == 0)
@@ -2687,320 +2669,148 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
2687 //if (!ode.lockquery()) 2669 //if (!ode.lockquery())
2688 //{ 2670 //{
2689 // ode.dlock(world); 2671 // ode.dlock(world);
2690 try
2691 {
2692 // Insert, remove Characters
2693 bool processedtaints = false;
2694 2672
2695 lock (_taintedActors) 2673 try
2696 { 2674 {
2697 if (_taintedActors.Count > 0) 2675 // Insert, remove Characters
2698 { 2676 bool processedtaints = false;
2699 foreach (OdeCharacter character in _taintedActors)
2700 {
2701 character.ProcessTaints(timeStep);
2702 2677
2703 processedtaints = true; 2678 lock (_taintedActors)
2704 //character.m_collisionscore = 0; 2679 {
2705 } 2680 if (_taintedActors.Count > 0)
2681 {
2682 foreach (OdeCharacter character in _taintedActors)
2683 {
2684 character.ProcessTaints(timeStep);
2706 2685
2707 if (processedtaints) 2686 processedtaints = true;
2708 _taintedActors.Clear(); 2687 //character.m_collisionscore = 0;
2709 }
2710 } 2688 }
2711 2689
2712 // Modify other objects in the scene. 2690 if (processedtaints)
2713 processedtaints = false; 2691 _taintedActors.Clear();
2692 }
2693 }
2694
2695 // Modify other objects in the scene.
2696 processedtaints = false;
2714 2697
2715 lock (_taintedPrimLock) 2698 lock (_taintedPrimLock)
2699 {
2700 foreach (OdePrim prim in _taintedPrimL)
2701 {
2702 if (prim.m_taintremove)
2716 { 2703 {
2717 foreach (OdePrim prim in _taintedPrimL) 2704// Console.WriteLine("Simulate calls RemovePrimThreadLocked for {0}", prim.Name);
2718 { 2705 RemovePrimThreadLocked(prim);
2719 if (prim.m_taintremove) 2706 }
2720 { 2707 else
2721 //Console.WriteLine("Simulate calls RemovePrimThreadLocked"); 2708 {
2722 RemovePrimThreadLocked(prim); 2709// Console.WriteLine("Simulate calls ProcessTaints for {0}", prim.Name);
2723 } 2710 prim.ProcessTaints(timeStep);
2724 else 2711 }
2725 {
2726 //Console.WriteLine("Simulate calls ProcessTaints");
2727 prim.ProcessTaints(timeStep);
2728 }
2729 processedtaints = true;
2730 prim.m_collisionscore = 0;
2731
2732 // This loop can block up the Heartbeat for a very long time on large regions.
2733 // We need to let the Watchdog know that the Heartbeat is not dead
2734 // NOTE: This is currently commented out, but if things like OAR loading are
2735 // timing the heartbeat out we will need to uncomment it
2736 //Watchdog.UpdateThread();
2737 }
2738 2712
2739 if (SupportsNINJAJoints) 2713 processedtaints = true;
2740 { 2714 prim.m_collisionscore = 0;
2741 // Create pending joints, if possible
2742 2715
2743 // joints can only be processed after ALL bodies are processed (and exist in ODE), since creating 2716 // This loop can block up the Heartbeat for a very long time on large regions.
2744 // a joint requires specifying the body id of both involved bodies 2717 // We need to let the Watchdog know that the Heartbeat is not dead
2745 if (pendingJoints.Count > 0) 2718 // NOTE: This is currently commented out, but if things like OAR loading are
2746 { 2719 // timing the heartbeat out we will need to uncomment it
2747 List<PhysicsJoint> successfullyProcessedPendingJoints = new List<PhysicsJoint>(); 2720 //Watchdog.UpdateThread();
2748 //DoJointErrorMessage(joints_connecting_actor, "taint: " + pendingJoints.Count + " pending joints"); 2721 }
2749 foreach (PhysicsJoint joint in pendingJoints)
2750 {
2751 //DoJointErrorMessage(joint, "taint: time to create joint with parms: " + joint.RawParams);
2752 string[] jointParams = joint.RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries);
2753 List<IntPtr> jointBodies = new List<IntPtr>();
2754 bool allJointBodiesAreReady = true;
2755 foreach (string jointParam in jointParams)
2756 {
2757 if (jointParam == "NULL")
2758 {
2759 //DoJointErrorMessage(joint, "attaching NULL joint to world");
2760 jointBodies.Add(IntPtr.Zero);
2761 }
2762 else
2763 {
2764 //DoJointErrorMessage(joint, "looking for prim name: " + jointParam);
2765 bool foundPrim = false;
2766 lock (_prims)
2767 {
2768 foreach (OdePrim prim in _prims) // FIXME: inefficient
2769 {
2770 if (prim.SOPName == jointParam)
2771 {
2772 //DoJointErrorMessage(joint, "found for prim name: " + jointParam);
2773 if (prim.IsPhysical && prim.Body != IntPtr.Zero)
2774 {
2775 jointBodies.Add(prim.Body);
2776 foundPrim = true;
2777 break;
2778 }
2779 else
2780 {
2781 DoJointErrorMessage(joint, "prim name " + jointParam +
2782 " exists but is not (yet) physical; deferring joint creation. " +
2783 "IsPhysical property is " + prim.IsPhysical +
2784 " and body is " + prim.Body);
2785 foundPrim = false;
2786 break;
2787 }
2788 }
2789 }
2790 }
2791 if (foundPrim)
2792 {
2793 // all is fine
2794 }
2795 else
2796 {
2797 allJointBodiesAreReady = false;
2798 break;
2799 }
2800 }
2801 }
2802 if (allJointBodiesAreReady)
2803 {
2804 //DoJointErrorMessage(joint, "allJointBodiesAreReady for " + joint.ObjectNameInScene + " with parms " + joint.RawParams);
2805 if (jointBodies[0] == jointBodies[1])
2806 {
2807 DoJointErrorMessage(joint, "ERROR: joint cannot be created; the joint bodies are the same, body1==body2. Raw body is " + jointBodies[0] + ". raw parms: " + joint.RawParams);
2808 }
2809 else
2810 {
2811 switch (joint.Type)
2812 {
2813 case PhysicsJointType.Ball:
2814 {
2815 IntPtr odeJoint;
2816 //DoJointErrorMessage(joint, "ODE creating ball joint ");
2817 odeJoint = d.JointCreateBall(world, IntPtr.Zero);
2818 //DoJointErrorMessage(joint, "ODE attaching ball joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]);
2819 d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]);
2820 //DoJointErrorMessage(joint, "ODE setting ball anchor: " + odeJoint + " to vec:" + joint.Position);
2821 d.JointSetBallAnchor(odeJoint,
2822 joint.Position.X,
2823 joint.Position.Y,
2824 joint.Position.Z);
2825 //DoJointErrorMessage(joint, "ODE joint setting OK");
2826 //DoJointErrorMessage(joint, "The ball joint's bodies are here: b0: ");
2827 //DoJointErrorMessage(joint, "" + (jointBodies[0] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[0]) : "fixed environment"));
2828 //DoJointErrorMessage(joint, "The ball joint's bodies are here: b1: ");
2829 //DoJointErrorMessage(joint, "" + (jointBodies[1] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[1]) : "fixed environment"));
2830
2831 if (joint is OdePhysicsJoint)
2832 {
2833 ((OdePhysicsJoint)joint).jointID = odeJoint;
2834 }
2835 else
2836 {
2837 DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!");
2838 }
2839 }
2840 break;
2841 case PhysicsJointType.Hinge:
2842 {
2843 IntPtr odeJoint;
2844 //DoJointErrorMessage(joint, "ODE creating hinge joint ");
2845 odeJoint = d.JointCreateHinge(world, IntPtr.Zero);
2846 //DoJointErrorMessage(joint, "ODE attaching hinge joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]);
2847 d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]);
2848 //DoJointErrorMessage(joint, "ODE setting hinge anchor: " + odeJoint + " to vec:" + joint.Position);
2849 d.JointSetHingeAnchor(odeJoint,
2850 joint.Position.X,
2851 joint.Position.Y,
2852 joint.Position.Z);
2853 // We use the orientation of the x-axis of the joint's coordinate frame
2854 // as the axis for the hinge.
2855
2856 // Therefore, we must get the joint's coordinate frame based on the
2857 // joint.Rotation field, which originates from the orientation of the
2858 // joint's proxy object in the scene.
2859
2860 // The joint's coordinate frame is defined as the transformation matrix
2861 // that converts a vector from joint-local coordinates into world coordinates.
2862 // World coordinates are defined as the XYZ coordinate system of the sim,
2863 // as shown in the top status-bar of the viewer.
2864
2865 // Once we have the joint's coordinate frame, we extract its X axis (AtAxis)
2866 // and use that as the hinge axis.
2867
2868 //joint.Rotation.Normalize();
2869 Matrix4 proxyFrame = Matrix4.CreateFromQuaternion(joint.Rotation);
2870
2871 // Now extract the X axis of the joint's coordinate frame.
2872
2873 // Do not try to use proxyFrame.AtAxis or you will become mired in the
2874 // tar pit of transposed, inverted, and generally messed-up orientations.
2875 // (In other words, Matrix4.AtAxis() is borked.)
2876 // Vector3 jointAxis = proxyFrame.AtAxis; <--- this path leadeth to madness
2877
2878 // Instead, compute the X axis of the coordinate frame by transforming
2879 // the (1,0,0) vector. At least that works.
2880
2881 //m_log.Debug("PHY: making axis: complete matrix is " + proxyFrame);
2882 Vector3 jointAxis = Vector3.Transform(Vector3.UnitX, proxyFrame);
2883 //m_log.Debug("PHY: making axis: hinge joint axis is " + jointAxis);
2884 //DoJointErrorMessage(joint, "ODE setting hinge axis: " + odeJoint + " to vec:" + jointAxis);
2885 d.JointSetHingeAxis(odeJoint,
2886 jointAxis.X,
2887 jointAxis.Y,
2888 jointAxis.Z);
2889 //d.JointSetHingeParam(odeJoint, (int)dParam.CFM, 0.1f);
2890 if (joint is OdePhysicsJoint)
2891 {
2892 ((OdePhysicsJoint)joint).jointID = odeJoint;
2893 }
2894 else
2895 {
2896 DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!");
2897 }
2898 }
2899 break;
2900 }
2901 successfullyProcessedPendingJoints.Add(joint);
2902 }
2903 }
2904 else
2905 {
2906 DoJointErrorMessage(joint, "joint could not yet be created; still pending");
2907 }
2908 }
2909 foreach (PhysicsJoint successfullyProcessedJoint in successfullyProcessedPendingJoints)
2910 {
2911 //DoJointErrorMessage(successfullyProcessedJoint, "finalizing succesfully procsssed joint " + successfullyProcessedJoint.ObjectNameInScene + " parms " + successfullyProcessedJoint.RawParams);
2912 //DoJointErrorMessage(successfullyProcessedJoint, "removing from pending");
2913 InternalRemovePendingJoint(successfullyProcessedJoint);
2914 //DoJointErrorMessage(successfullyProcessedJoint, "adding to active");
2915 InternalAddActiveJoint(successfullyProcessedJoint);
2916 //DoJointErrorMessage(successfullyProcessedJoint, "done");
2917 }
2918 }
2919 }
2920 2722
2921 if (processedtaints) 2723 if (SupportsNINJAJoints)
2724 SimulatePendingNINJAJoints();
2725
2726 if (processedtaints)
2727 {
2922//Console.WriteLine("Simulate calls Clear of _taintedPrim list"); 2728//Console.WriteLine("Simulate calls Clear of _taintedPrim list");
2923 _taintedPrimH.Clear(); 2729 _taintedPrimH.Clear();
2924 _taintedPrimL.Clear(); 2730 _taintedPrimL.Clear();
2925 } 2731 }
2732 }
2926 2733
2927 // Move characters 2734 // Move characters
2928 lock (_characters) 2735 lock (_characters)
2736 {
2737 List<OdeCharacter> defects = new List<OdeCharacter>();
2738 foreach (OdeCharacter actor in _characters)
2739 {
2740 if (actor != null)
2741 actor.Move(timeStep, defects);
2742 }
2743 if (0 != defects.Count)
2744 {
2745 foreach (OdeCharacter defect in defects)
2929 { 2746 {
2930 List<OdeCharacter> defects = new List<OdeCharacter>(); 2747 RemoveCharacter(defect);
2931 foreach (OdeCharacter actor in _characters)
2932 {
2933 if (actor != null)
2934 actor.Move(timeStep, defects);
2935 }
2936 if (0 != defects.Count)
2937 {
2938 foreach (OdeCharacter defect in defects)
2939 {
2940 RemoveCharacter(defect);
2941 }
2942 }
2943 } 2748 }
2749 }
2750 }
2944 2751
2945 // Move other active objects 2752 // Move other active objects
2946 lock (_activeprims) 2753 lock (_activeprims)
2947 { 2754 {
2948 foreach (OdePrim prim in _activeprims) 2755 foreach (OdePrim prim in _activeprims)
2949 { 2756 {
2950 prim.m_collisionscore = 0; 2757 prim.m_collisionscore = 0;
2951 prim.Move(timeStep); 2758 prim.Move(timeStep);
2952 } 2759 }
2953 } 2760 }
2761
2762 //if ((framecount % m_randomizeWater) == 0)
2763 // randomizeWater(waterlevel);
2954 2764
2955 //if ((framecount % m_randomizeWater) == 0) 2765 //int RayCastTimeMS = m_rayCastManager.ProcessQueuedRequests();
2956 // randomizeWater(waterlevel); 2766 m_rayCastManager.ProcessQueuedRequests();
2957 2767
2958 //int RayCastTimeMS = m_rayCastManager.ProcessQueuedRequests(); 2768 collision_optimized(timeStep);
2959 m_rayCastManager.ProcessQueuedRequests();
2960 2769
2961 collision_optimized(timeStep); 2770 lock (_collisionEventPrim)
2771 {
2772 foreach (PhysicsActor obj in _collisionEventPrim)
2773 {
2774 if (obj == null)
2775 continue;
2962 2776
2963 lock (_collisionEventPrim) 2777// m_log.DebugFormat("[PHYSICS]: Assessing {0} for collision events", obj.SOPName);
2778
2779 switch ((ActorTypes)obj.PhysicsActorType)
2964 { 2780 {
2965 foreach (PhysicsActor obj in _collisionEventPrim) 2781 case ActorTypes.Agent:
2966 { 2782 OdeCharacter cobj = (OdeCharacter)obj;
2967 if (obj == null) 2783 cobj.AddCollisionFrameTime(100);
2968 continue; 2784 cobj.SendCollisions();
2785 break;
2969 2786
2970 switch ((ActorTypes)obj.PhysicsActorType) 2787 case ActorTypes.Prim:
2971 { 2788 OdePrim pobj = (OdePrim)obj;
2972 case ActorTypes.Agent: 2789 pobj.SendCollisions();
2973 OdeCharacter cobj = (OdeCharacter)obj; 2790 break;
2974 cobj.AddCollisionFrameTime(100);
2975 cobj.SendCollisions();
2976 break;
2977 case ActorTypes.Prim:
2978 OdePrim pobj = (OdePrim)obj;
2979 pobj.SendCollisions();
2980 break;
2981 }
2982 }
2983 } 2791 }
2792 }
2793 }
2984 2794
2985 //if (m_global_contactcount > 5) 2795 //if (m_global_contactcount > 5)
2986 //{ 2796 //{
2987 // m_log.DebugFormat("[PHYSICS]: Contacts:{0}", m_global_contactcount); 2797 // m_log.DebugFormat("[PHYSICS]: Contacts:{0}", m_global_contactcount);
2988 //} 2798 //}
2989 2799
2990 m_global_contactcount = 0; 2800 m_global_contactcount = 0;
2991 2801
2992 d.WorldQuickStep(world, ODE_STEPSIZE); 2802 d.WorldQuickStep(world, ODE_STEPSIZE);
2993 d.JointGroupEmpty(contactgroup); 2803 d.JointGroupEmpty(contactgroup);
2994 //ode.dunlock(world); 2804 //ode.dunlock(world);
2995 } 2805 }
2996 catch (Exception e) 2806 catch (Exception e)
2997 { 2807 {
2998 m_log.ErrorFormat("[PHYSICS]: {0}, {1}, {2}", e.Message, e.TargetSite, e); 2808 m_log.ErrorFormat("[PHYSICS]: {0}, {1}, {2}", e.Message, e.TargetSite, e);
2999 ode.dunlock(world); 2809 ode.dunlock(world);
3000 } 2810 }
3001 2811
3002 step_time -= ODE_STEPSIZE; 2812 step_time -= ODE_STEPSIZE;
3003 i++; 2813 i++;
3004 //} 2814 //}
3005 //else 2815 //else
3006 //{ 2816 //{
@@ -3017,6 +2827,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
3017 { 2827 {
3018 if (actor.bad) 2828 if (actor.bad)
3019 m_log.WarnFormat("[PHYSICS]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid); 2829 m_log.WarnFormat("[PHYSICS]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid);
2830
3020 actor.UpdatePositionAndVelocity(); 2831 actor.UpdatePositionAndVelocity();
3021 } 2832 }
3022 } 2833 }
@@ -3030,6 +2841,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
3030 { 2841 {
3031 RemoveCharacter(chr); 2842 RemoveCharacter(chr);
3032 } 2843 }
2844
3033 _badCharacter.Clear(); 2845 _badCharacter.Clear();
3034 } 2846 }
3035 } 2847 }
@@ -3045,30 +2857,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
3045 actor.UpdatePositionAndVelocity(); 2857 actor.UpdatePositionAndVelocity();
3046 2858
3047 if (SupportsNINJAJoints) 2859 if (SupportsNINJAJoints)
3048 { 2860 SimulateActorPendingJoints(actor);
3049 // If an actor moved, move its joint proxy objects as well.
3050 // There seems to be an event PhysicsActor.OnPositionUpdate that could be used
3051 // for this purpose but it is never called! So we just do the joint
3052 // movement code here.
3053
3054 if (actor.SOPName != null &&
3055 joints_connecting_actor.ContainsKey(actor.SOPName) &&
3056 joints_connecting_actor[actor.SOPName] != null &&
3057 joints_connecting_actor[actor.SOPName].Count > 0)
3058 {
3059 foreach (PhysicsJoint affectedJoint in joints_connecting_actor[actor.SOPName])
3060 {
3061 if (affectedJoint.IsInPhysicsEngine)
3062 {
3063 DoJointMoved(affectedJoint);
3064 }
3065 else
3066 {
3067 DoJointErrorMessage(affectedJoint, "a body connected to a joint was moved, but the joint doesn't exist yet! this will lead to joint error. joint was: " + affectedJoint.ObjectNameInScene + " parms:" + affectedJoint.RawParams);
3068 }
3069 }
3070 }
3071 }
3072 } 2861 }
3073 } 2862 }
3074 } 2863 }
@@ -3079,7 +2868,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
3079 // Finished with all sim stepping. If requested, dump world state to file for debugging. 2868 // Finished with all sim stepping. If requested, dump world state to file for debugging.
3080 // TODO: This call to the export function is already inside lock (OdeLock) - but is an extra lock needed? 2869 // TODO: This call to the export function is already inside lock (OdeLock) - but is an extra lock needed?
3081 // TODO: This overwrites all dump files in-place. Should this be a growing logfile, or separate snapshots? 2870 // TODO: This overwrites all dump files in-place. Should this be a growing logfile, or separate snapshots?
3082 if (physics_logging && (physics_logging_interval>0) && (framecount % physics_logging_interval == 0)) 2871 if (physics_logging && (physics_logging_interval > 0) && (framecount % physics_logging_interval == 0))
3083 { 2872 {
3084 string fname = "state-" + world.ToString() + ".DIF"; // give each physics world a separate filename 2873 string fname = "state-" + world.ToString() + ".DIF"; // give each physics world a separate filename
3085 string prefix = "world" + world.ToString(); // prefix for variable names in exported .DIF file 2874 string prefix = "world" + world.ToString(); // prefix for variable names in exported .DIF file
@@ -3091,8 +2880,10 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
3091 fwriter.WriteLine(header); 2880 fwriter.WriteLine(header);
3092 fwriter.Close(); 2881 fwriter.Close();
3093 } 2882 }
2883
3094 d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix); 2884 d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix);
3095 } 2885 }
2886
3096 latertickcount = Util.EnvironmentTickCount() - tickCountFrameRun; 2887 latertickcount = Util.EnvironmentTickCount() - tickCountFrameRun;
3097 2888
3098 // OpenSimulator above does 10 fps. 10 fps = means that the main thread loop and physics 2889 // OpenSimulator above does 10 fps. 10 fps = means that the main thread loop and physics
@@ -3101,7 +2892,9 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
3101 // If Physics stalls, it takes longer which makes the tick count ms larger. 2892 // If Physics stalls, it takes longer which makes the tick count ms larger.
3102 2893
3103 if (latertickcount < 100) 2894 if (latertickcount < 100)
2895 {
3104 m_timeDilation = 1.0f; 2896 m_timeDilation = 1.0f;
2897 }
3105 else 2898 else
3106 { 2899 {
3107 m_timeDilation = 100f / latertickcount; 2900 m_timeDilation = 100f / latertickcount;
@@ -3114,6 +2907,229 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
3114 return fps; 2907 return fps;
3115 } 2908 }
3116 2909
2910 /// <summary>
2911 /// Simulate pending NINJA joints.
2912 /// </summary>
2913 /// <remarks>
2914 /// Called by the main Simulate() loop if NINJA joints are active. Should not be called from anywhere else.
2915 /// </remarks>
2916 protected void SimulatePendingNINJAJoints()
2917 {
2918 // Create pending joints, if possible
2919
2920 // joints can only be processed after ALL bodies are processed (and exist in ODE), since creating
2921 // a joint requires specifying the body id of both involved bodies
2922 if (pendingJoints.Count > 0)
2923 {
2924 List<PhysicsJoint> successfullyProcessedPendingJoints = new List<PhysicsJoint>();
2925 //DoJointErrorMessage(joints_connecting_actor, "taint: " + pendingJoints.Count + " pending joints");
2926 foreach (PhysicsJoint joint in pendingJoints)
2927 {
2928 //DoJointErrorMessage(joint, "taint: time to create joint with parms: " + joint.RawParams);
2929 string[] jointParams = joint.RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries);
2930 List<IntPtr> jointBodies = new List<IntPtr>();
2931 bool allJointBodiesAreReady = true;
2932 foreach (string jointParam in jointParams)
2933 {
2934 if (jointParam == "NULL")
2935 {
2936 //DoJointErrorMessage(joint, "attaching NULL joint to world");
2937 jointBodies.Add(IntPtr.Zero);
2938 }
2939 else
2940 {
2941 //DoJointErrorMessage(joint, "looking for prim name: " + jointParam);
2942 bool foundPrim = false;
2943 lock (_prims)
2944 {
2945 foreach (OdePrim prim in _prims) // FIXME: inefficient
2946 {
2947 if (prim.SOPName == jointParam)
2948 {
2949 //DoJointErrorMessage(joint, "found for prim name: " + jointParam);
2950 if (prim.IsPhysical && prim.Body != IntPtr.Zero)
2951 {
2952 jointBodies.Add(prim.Body);
2953 foundPrim = true;
2954 break;
2955 }
2956 else
2957 {
2958 DoJointErrorMessage(joint, "prim name " + jointParam +
2959 " exists but is not (yet) physical; deferring joint creation. " +
2960 "IsPhysical property is " + prim.IsPhysical +
2961 " and body is " + prim.Body);
2962 foundPrim = false;
2963 break;
2964 }
2965 }
2966 }
2967 }
2968 if (foundPrim)
2969 {
2970 // all is fine
2971 }
2972 else
2973 {
2974 allJointBodiesAreReady = false;
2975 break;
2976 }
2977 }
2978 }
2979
2980 if (allJointBodiesAreReady)
2981 {
2982 //DoJointErrorMessage(joint, "allJointBodiesAreReady for " + joint.ObjectNameInScene + " with parms " + joint.RawParams);
2983 if (jointBodies[0] == jointBodies[1])
2984 {
2985 DoJointErrorMessage(joint, "ERROR: joint cannot be created; the joint bodies are the same, body1==body2. Raw body is " + jointBodies[0] + ". raw parms: " + joint.RawParams);
2986 }
2987 else
2988 {
2989 switch (joint.Type)
2990 {
2991 case PhysicsJointType.Ball:
2992 {
2993 IntPtr odeJoint;
2994 //DoJointErrorMessage(joint, "ODE creating ball joint ");
2995 odeJoint = d.JointCreateBall(world, IntPtr.Zero);
2996 //DoJointErrorMessage(joint, "ODE attaching ball joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]);
2997 d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]);
2998 //DoJointErrorMessage(joint, "ODE setting ball anchor: " + odeJoint + " to vec:" + joint.Position);
2999 d.JointSetBallAnchor(odeJoint,
3000 joint.Position.X,
3001 joint.Position.Y,
3002 joint.Position.Z);
3003 //DoJointErrorMessage(joint, "ODE joint setting OK");
3004 //DoJointErrorMessage(joint, "The ball joint's bodies are here: b0: ");
3005 //DoJointErrorMessage(joint, "" + (jointBodies[0] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[0]) : "fixed environment"));
3006 //DoJointErrorMessage(joint, "The ball joint's bodies are here: b1: ");
3007 //DoJointErrorMessage(joint, "" + (jointBodies[1] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[1]) : "fixed environment"));
3008
3009 if (joint is OdePhysicsJoint)
3010 {
3011 ((OdePhysicsJoint)joint).jointID = odeJoint;
3012 }
3013 else
3014 {
3015 DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!");
3016 }
3017 }
3018 break;
3019 case PhysicsJointType.Hinge:
3020 {
3021 IntPtr odeJoint;
3022 //DoJointErrorMessage(joint, "ODE creating hinge joint ");
3023 odeJoint = d.JointCreateHinge(world, IntPtr.Zero);
3024 //DoJointErrorMessage(joint, "ODE attaching hinge joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]);
3025 d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]);
3026 //DoJointErrorMessage(joint, "ODE setting hinge anchor: " + odeJoint + " to vec:" + joint.Position);
3027 d.JointSetHingeAnchor(odeJoint,
3028 joint.Position.X,
3029 joint.Position.Y,
3030 joint.Position.Z);
3031 // We use the orientation of the x-axis of the joint's coordinate frame
3032 // as the axis for the hinge.
3033
3034 // Therefore, we must get the joint's coordinate frame based on the
3035 // joint.Rotation field, which originates from the orientation of the
3036 // joint's proxy object in the scene.
3037
3038 // The joint's coordinate frame is defined as the transformation matrix
3039 // that converts a vector from joint-local coordinates into world coordinates.
3040 // World coordinates are defined as the XYZ coordinate system of the sim,
3041 // as shown in the top status-bar of the viewer.
3042
3043 // Once we have the joint's coordinate frame, we extract its X axis (AtAxis)
3044 // and use that as the hinge axis.
3045
3046 //joint.Rotation.Normalize();
3047 Matrix4 proxyFrame = Matrix4.CreateFromQuaternion(joint.Rotation);
3048
3049 // Now extract the X axis of the joint's coordinate frame.
3050
3051 // Do not try to use proxyFrame.AtAxis or you will become mired in the
3052 // tar pit of transposed, inverted, and generally messed-up orientations.
3053 // (In other words, Matrix4.AtAxis() is borked.)
3054 // Vector3 jointAxis = proxyFrame.AtAxis; <--- this path leadeth to madness
3055
3056 // Instead, compute the X axis of the coordinate frame by transforming
3057 // the (1,0,0) vector. At least that works.
3058
3059 //m_log.Debug("PHY: making axis: complete matrix is " + proxyFrame);
3060 Vector3 jointAxis = Vector3.Transform(Vector3.UnitX, proxyFrame);
3061 //m_log.Debug("PHY: making axis: hinge joint axis is " + jointAxis);
3062 //DoJointErrorMessage(joint, "ODE setting hinge axis: " + odeJoint + " to vec:" + jointAxis);
3063 d.JointSetHingeAxis(odeJoint,
3064 jointAxis.X,
3065 jointAxis.Y,
3066 jointAxis.Z);
3067 //d.JointSetHingeParam(odeJoint, (int)dParam.CFM, 0.1f);
3068 if (joint is OdePhysicsJoint)
3069 {
3070 ((OdePhysicsJoint)joint).jointID = odeJoint;
3071 }
3072 else
3073 {
3074 DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!");
3075 }
3076 }
3077 break;
3078 }
3079 successfullyProcessedPendingJoints.Add(joint);
3080 }
3081 }
3082 else
3083 {
3084 DoJointErrorMessage(joint, "joint could not yet be created; still pending");
3085 }
3086 }
3087
3088 foreach (PhysicsJoint successfullyProcessedJoint in successfullyProcessedPendingJoints)
3089 {
3090 //DoJointErrorMessage(successfullyProcessedJoint, "finalizing succesfully procsssed joint " + successfullyProcessedJoint.ObjectNameInScene + " parms " + successfullyProcessedJoint.RawParams);
3091 //DoJointErrorMessage(successfullyProcessedJoint, "removing from pending");
3092 InternalRemovePendingJoint(successfullyProcessedJoint);
3093 //DoJointErrorMessage(successfullyProcessedJoint, "adding to active");
3094 InternalAddActiveJoint(successfullyProcessedJoint);
3095 //DoJointErrorMessage(successfullyProcessedJoint, "done");
3096 }
3097 }
3098 }
3099
3100 /// <summary>
3101 /// Simulate the joint proxies of a NINJA actor.
3102 /// </summary>
3103 /// <remarks>
3104 /// Called as part of the Simulate() loop if NINJA physics is active. Must only be called from there.
3105 /// </remarks>
3106 /// <param name="actor"></param>
3107 protected void SimulateActorPendingJoints(OdePrim actor)
3108 {
3109 // If an actor moved, move its joint proxy objects as well.
3110 // There seems to be an event PhysicsActor.OnPositionUpdate that could be used
3111 // for this purpose but it is never called! So we just do the joint
3112 // movement code here.
3113
3114 if (actor.SOPName != null &&
3115 joints_connecting_actor.ContainsKey(actor.SOPName) &&
3116 joints_connecting_actor[actor.SOPName] != null &&
3117 joints_connecting_actor[actor.SOPName].Count > 0)
3118 {
3119 foreach (PhysicsJoint affectedJoint in joints_connecting_actor[actor.SOPName])
3120 {
3121 if (affectedJoint.IsInPhysicsEngine)
3122 {
3123 DoJointMoved(affectedJoint);
3124 }
3125 else
3126 {
3127 DoJointErrorMessage(affectedJoint, "a body connected to a joint was moved, but the joint doesn't exist yet! this will lead to joint error. joint was: " + affectedJoint.ObjectNameInScene + " parms:" + affectedJoint.RawParams);
3128 }
3129 }
3130 }
3131 }
3132
3117 public override void GetResults() 3133 public override void GetResults()
3118 { 3134 {
3119 } 3135 }
@@ -3459,24 +3475,21 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
3459 float hfmin = 2000; 3475 float hfmin = 2000;
3460 float hfmax = -2000; 3476 float hfmax = -2000;
3461 3477
3462 for (int x = 0; x < heightmapWidthSamples; x++) 3478 for (int x = 0; x < heightmapWidthSamples; x++)
3479 {
3480 for (int y = 0; y < heightmapHeightSamples; y++)
3463 { 3481 {
3464 for (int y = 0; y < heightmapHeightSamples; y++) 3482 int xx = Util.Clip(x - 1, 0, regionsize - 1);
3465 { 3483 int yy = Util.Clip(y - 1, 0, regionsize - 1);
3466 int xx = Util.Clip(x - 1, 0, regionsize - 1); 3484
3467 int yy = Util.Clip(y - 1, 0, regionsize - 1); 3485
3468 3486 float val= heightMap[yy * (int)Constants.RegionSize + xx];
3469 3487 _heightmap[x * ((int)Constants.RegionSize + 2) + y] = val;
3470 float val= heightMap[yy * (int)Constants.RegionSize + xx]; 3488
3471 _heightmap[x * ((int)Constants.RegionSize + 2) + y] = val; 3489 hfmin = (val < hfmin) ? val : hfmin;
3472 3490 hfmax = (val > hfmax) ? val : hfmax;
3473 hfmin = (val < hfmin) ? val : hfmin;
3474 hfmax = (val > hfmax) ? val : hfmax;
3475 }
3476 } 3491 }
3477 3492 }
3478
3479
3480 3493
3481 lock (OdeLock) 3494 lock (OdeLock)
3482 { 3495 {
@@ -3531,7 +3544,6 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
3531 } 3544 }
3532 RegionTerrain.Add(pOffset, GroundGeom, GroundGeom); 3545 RegionTerrain.Add(pOffset, GroundGeom, GroundGeom);
3533 TerrainHeightFieldHeights.Add(GroundGeom,_heightmap); 3546 TerrainHeightFieldHeights.Add(GroundGeom,_heightmap);
3534
3535 } 3547 }
3536 } 3548 }
3537 3549
@@ -3694,6 +3706,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
3694 //d.CloseODE(); 3706 //d.CloseODE();
3695 } 3707 }
3696 } 3708 }
3709
3697 public override Dictionary<uint, float> GetTopColliders() 3710 public override Dictionary<uint, float> GetTopColliders()
3698 { 3711 {
3699 Dictionary<uint, float> returncolliders = new Dictionary<uint, float>(); 3712 Dictionary<uint, float> returncolliders = new Dictionary<uint, float>();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index b710229..8093502 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -2110,7 +2110,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2110 if (module != null) 2110 if (module != null)
2111 { 2111 {
2112 Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z); 2112 Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z);
2113 module.Autopilot(new UUID(npc.m_string), World, pos); 2113 module.MoveToTarget(new UUID(npc.m_string), World, pos);
2114 } 2114 }
2115 } 2115 }
2116 2116