diff options
Diffstat (limited to '')
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 | ||
40 | namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization | 40 | namespace 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 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Reflection; | ||
31 | using log4net; | ||
30 | using OpenMetaverse; | 32 | using OpenMetaverse; |
31 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
32 | using OpenSim.Region.Framework.Interfaces; | 34 | using 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 | ||
28 | using System; | 28 | using System; |
29 | using System.Reflection; | 29 | using System.Reflection; |
30 | using log4net; | ||
30 | using Nini.Config; | 31 | using Nini.Config; |
31 | using NUnit.Framework; | 32 | using NUnit.Framework; |
32 | using OpenMetaverse; | 33 | using OpenMetaverse; |
33 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
34 | using OpenSim.Framework.Communications; | 35 | using OpenSim.Framework.Communications; |
36 | using OpenSim.Region.CoreModules.Avatar.AvatarFactory; | ||
35 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar; | 37 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar; |
36 | using OpenSim.Region.Framework.Interfaces; | 38 | using OpenSim.Region.Framework.Interfaces; |
37 | using OpenSim.Region.Framework.Scenes; | 39 | using 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 |
1326 | Console.WriteLine("CreateGeom:"); | 1362 | Console.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 |
1427 | Console.WriteLine("changeadd 1"); | 1495 | Console.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 | ||
1949 | Console.WriteLine("changesize 1"); | ||
1950 | #endif | ||
1951 | CreateGeom(m_targetSpace, mesh); | ||
1952 | } | ||
1953 | else | ||
1954 | { | ||
1955 | _mesh = null; | ||
1956 | |||
1957 | #if SPAM | ||
1958 | Console.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 | ||
2062 | Console.WriteLine("changeshape needed meshing"); | ||
2063 | #endif | ||
2064 | CreateGeom(m_targetSpace, mesh); | ||
2065 | } | ||
2066 | else | ||
2067 | { | ||
2068 | _mesh = null; | ||
2069 | |||
2070 | #if SPAM | ||
2071 | Console.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 | ||