aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/Application/OpenSim.cs25
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs13
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs64
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs169
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs12
-rw-r--r--OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs239
-rw-r--r--OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs126
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs63
-rw-r--r--OpenSim/Region/CoreModules/World/Sound/SoundModule.cs8
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs61
-rw-r--r--OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs16
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs5
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs41
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs11
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs60
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs109
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs19
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs36
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs4
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs6
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs21
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs228
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs29
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs110
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs78
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs1261
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs14
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs61
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs13
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs60
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs7
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs28
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs77
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/EventManager.cs24
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs57
46 files changed, 1956 insertions, 1232 deletions
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index 6255515..9c7598a 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -35,6 +35,7 @@ using System.Text;
35using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers; 36using System.Timers;
37using log4net; 37using log4net;
38using NDesk.Options;
38using Nini.Config; 39using Nini.Config;
39using OpenMetaverse; 40using OpenMetaverse;
40using OpenSim.Framework; 41using OpenSim.Framework;
@@ -310,8 +311,11 @@ namespace OpenSim
310 "Change the scale of a named prim", HandleEditScale); 311 "Change the scale of a named prim", HandleEditScale);
311 312
312 m_console.Commands.AddCommand("Users", false, "kick user", 313 m_console.Commands.AddCommand("Users", false, "kick user",
313 "kick user <first> <last> [message]", 314 "kick user <first> <last> [--force] [message]",
314 "Kick a user off the simulator", KickUserCommand); 315 "Kick a user off the simulator",
316 "The --force option will kick the user without any checks to see whether it's already in the process of closing\n"
317 + "Only use this option if you are sure the avatar is inactive and a normal kick user operation does not removed them",
318 KickUserCommand);
315 319
316 m_console.Commands.AddCommand("Users", false, "show users", 320 m_console.Commands.AddCommand("Users", false, "show users",
317 "show users [full]", 321 "show users [full]",
@@ -416,6 +420,7 @@ namespace OpenSim
416 { 420 {
417 RunCommandScript(m_shutdownCommandsFile); 421 RunCommandScript(m_shutdownCommandsFile);
418 } 422 }
423
419 base.ShutdownSpecific(); 424 base.ShutdownSpecific();
420 } 425 }
421 426
@@ -453,11 +458,17 @@ namespace OpenSim
453 /// <param name="cmdparams">name of avatar to kick</param> 458 /// <param name="cmdparams">name of avatar to kick</param>
454 private void KickUserCommand(string module, string[] cmdparams) 459 private void KickUserCommand(string module, string[] cmdparams)
455 { 460 {
456 if (cmdparams.Length < 4) 461 bool force = false;
462
463 OptionSet options = new OptionSet().Add("f|force", delegate (string v) { force = v != null; });
464
465 List<string> mainParams = options.Parse(cmdparams);
466
467 if (mainParams.Count < 4)
457 return; 468 return;
458 469
459 string alert = null; 470 string alert = null;
460 if (cmdparams.Length > 4) 471 if (mainParams.Count > 4)
461 alert = String.Format("\n{0}\n", String.Join(" ", cmdparams, 4, cmdparams.Length - 4)); 472 alert = String.Format("\n{0}\n", String.Join(" ", cmdparams, 4, cmdparams.Length - 4));
462 473
463 IList agents = SceneManager.GetCurrentSceneAvatars(); 474 IList agents = SceneManager.GetCurrentSceneAvatars();
@@ -466,8 +477,8 @@ namespace OpenSim
466 { 477 {
467 RegionInfo regionInfo = presence.Scene.RegionInfo; 478 RegionInfo regionInfo = presence.Scene.RegionInfo;
468 479
469 if (presence.Firstname.ToLower().Contains(cmdparams[2].ToLower()) && 480 if (presence.Firstname.ToLower().Contains(mainParams[2].ToLower()) &&
470 presence.Lastname.ToLower().Contains(cmdparams[3].ToLower())) 481 presence.Lastname.ToLower().Contains(mainParams[3].ToLower()))
471 { 482 {
472 MainConsole.Instance.Output( 483 MainConsole.Instance.Output(
473 String.Format( 484 String.Format(
@@ -480,7 +491,7 @@ namespace OpenSim
480 else 491 else
481 presence.ControllingClient.Kick("\nYou have been logged out by an administrator.\n"); 492 presence.ControllingClient.Kick("\nYou have been logged out by an administrator.\n");
482 493
483 presence.Scene.IncomingCloseAgent(presence.UUID); 494 presence.Scene.IncomingCloseAgent(presence.UUID, force);
484 } 495 }
485 } 496 }
486 497
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
index cd70410..d604cf6 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
@@ -94,7 +94,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
94 UUID spId = TestHelpers.ParseTail(0x1); 94 UUID spId = TestHelpers.ParseTail(0x1);
95 95
96 SceneHelpers.AddScenePresence(m_scene, spId); 96 SceneHelpers.AddScenePresence(m_scene, spId);
97 m_scene.IncomingCloseAgent(spId); 97 m_scene.IncomingCloseAgent(spId, false);
98 98
99 // TODO: Add more assertions for the other aspects of event queues 99 // TODO: Add more assertions for the other aspects of event queues
100 Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0)); 100 Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0));
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index ddd8f18..2dcc9cb 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -509,19 +509,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
509 /// </summary> 509 /// </summary>
510 public void Close() 510 public void Close()
511 { 511 {
512 Close(true); 512 Close(true, false);
513 } 513 }
514 514
515 /// <summary> 515 public void Close(bool sendStop, bool force)
516 /// Shut down the client view
517 /// </summary>
518 public void Close(bool sendStop)
519 { 516 {
520 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g. 517 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g.
521 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection. 518 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection.
522 lock (CloseSyncLock) 519 lock (CloseSyncLock)
523 { 520 {
524 if (!IsActive) 521 // We still perform a force close inside the sync lock since this is intended to attempt close where
522 // there is some unidentified connection problem, not where we have issues due to deadlock
523 if (!IsActive && !force)
525 return; 524 return;
526 525
527 IsActive = false; 526 IsActive = false;
@@ -12140,7 +12139,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12140 { 12139 {
12141 Kick(reason); 12140 Kick(reason);
12142 Thread.Sleep(1000); 12141 Thread.Sleep(1000);
12143 Close(); 12142 Disconnect();
12144 } 12143 }
12145 12144
12146 public void Disconnect() 12145 public void Disconnect()
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index d6513c5..60ab70e 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -1523,7 +1523,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1523 if (!client.IsLoggingOut) 1523 if (!client.IsLoggingOut)
1524 { 1524 {
1525 client.IsLoggingOut = true; 1525 client.IsLoggingOut = true;
1526 client.Close(false); 1526 client.Close(false, false);
1527 } 1527 }
1528 } 1528 }
1529 } 1529 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index d9a619d..48f3a23 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -461,7 +461,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
461 461
462 SceneObjectGroup rezzedAtt = presence.GetAttachments()[0]; 462 SceneObjectGroup rezzedAtt = presence.GetAttachments()[0];
463 463
464 scene.IncomingCloseAgent(presence.UUID); 464 scene.IncomingCloseAgent(presence.UUID, false);
465 465
466 // Check that we can't retrieve this attachment from the scene. 466 // Check that we can't retrieve this attachment from the scene.
467 Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null); 467 Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null);
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
index b112b6d..12a05b3 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
@@ -350,38 +350,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
350 Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL1.PrincipalID)); 350 Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL1.PrincipalID));
351 } 351 }
352 352
353 /// <summary> 353// /// <summary>
354 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where 354// /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
355 /// an account exists with the same name as the creator, though not the same id. 355// /// an account exists with the same name as the creator, though not the same id.
356 /// </summary> 356// /// </summary>
357 [Test] 357// [Test]
358 public void TestLoadIarV0_1SameNameCreator() 358// public void TestLoadIarV0_1SameNameCreator()
359 { 359// {
360 TestHelpers.InMethod(); 360// TestHelpers.InMethod();
361// log4net.Config.XmlConfigurator.Configure(); 361// TestHelpers.EnableLogging();
362 362//
363 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood"); 363// UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood");
364 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire"); 364// UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire");
365 365//
366 m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream); 366// m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream);
367 InventoryItemBase foundItem1 367// InventoryItemBase foundItem1
368 = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); 368// = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name);
369 369//
370 Assert.That( 370// Assert.That(
371 foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()), 371// foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()),
372 "Loaded item non-uuid creator doesn't match original"); 372// "Loaded item non-uuid creator doesn't match original");
373 Assert.That( 373// Assert.That(
374 foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID), 374// foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID),
375 "Loaded item uuid creator doesn't match original"); 375// "Loaded item uuid creator doesn't match original");
376 Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID), 376// Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID),
377 "Loaded item owner doesn't match inventory reciever"); 377// "Loaded item owner doesn't match inventory reciever");
378 378//
379 AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString()); 379// AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString());
380 string xmlData = Utils.BytesToString(asset1.Data); 380// string xmlData = Utils.BytesToString(asset1.Data);
381 SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); 381// SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
382 382//
383 Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID)); 383// Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID));
384 } 384// }
385 385
386 /// <summary> 386 /// <summary>
387 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where 387 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 9ffb851..538dd5f 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -644,7 +644,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
644 // an agent cannot teleport back to this region if it has teleported away. 644 // an agent cannot teleport back to this region if it has teleported away.
645 Thread.Sleep(2000); 645 Thread.Sleep(2000);
646 646
647 sp.Scene.IncomingCloseAgent(sp.UUID); 647 sp.Scene.IncomingCloseAgent(sp.UUID, false);
648 } 648 }
649 else 649 else
650 { 650 {
diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
index 18bd018..13b7498 100644
--- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
@@ -49,6 +49,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
49 public const int DISP_EXPIRE = 1; 49 public const int DISP_EXPIRE = 1;
50 public const int DISP_TEMP = 2; 50 public const int DISP_TEMP = 2;
51 51
52 /// <summary>
53 /// If true then where possible dynamic textures are reused.
54 /// </summary>
55 public bool ReuseTextures { get; set; }
56
52 private Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>(); 57 private Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>();
53 58
54 private Dictionary<string, IDynamicTextureRender> RenderPlugins = 59 private Dictionary<string, IDynamicTextureRender> RenderPlugins =
@@ -56,6 +61,15 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
56 61
57 private Dictionary<UUID, DynamicTextureUpdater> Updaters = new Dictionary<UUID, DynamicTextureUpdater>(); 62 private Dictionary<UUID, DynamicTextureUpdater> Updaters = new Dictionary<UUID, DynamicTextureUpdater>();
58 63
64 /// <summary>
65 /// Record dynamic textures that we can reuse for a given data and parameter combination rather than
66 /// regenerate.
67 /// </summary>
68 /// <remarks>
69 /// Key is string.Format("{0}{1}", data
70 /// </remarks>
71 private Cache m_reuseableDynamicTextures;
72
59 #region IDynamicTextureManager Members 73 #region IDynamicTextureManager Members
60 74
61 public void RegisterRender(string handleType, IDynamicTextureRender render) 75 public void RegisterRender(string handleType, IDynamicTextureRender render)
@@ -71,7 +85,8 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
71 /// </summary> 85 /// </summary>
72 /// <param name="id"></param> 86 /// <param name="id"></param>
73 /// <param name="data"></param> 87 /// <param name="data"></param>
74 public void ReturnData(UUID id, byte[] data) 88 /// <param name="isReuseable">True if the data generated can be reused for subsequent identical requests</param>
89 public void ReturnData(UUID id, byte[] data, bool isReuseable)
75 { 90 {
76 DynamicTextureUpdater updater = null; 91 DynamicTextureUpdater updater = null;
77 92
@@ -88,7 +103,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
88 if (RegisteredScenes.ContainsKey(updater.SimUUID)) 103 if (RegisteredScenes.ContainsKey(updater.SimUUID))
89 { 104 {
90 Scene scene = RegisteredScenes[updater.SimUUID]; 105 Scene scene = RegisteredScenes[updater.SimUUID];
91 updater.DataReceived(data, scene); 106 UUID newTextureID = updater.DataReceived(data, scene);
107
108 if (ReuseTextures && isReuseable && !updater.BlendWithOldTexture)
109 m_reuseableDynamicTextures.Store(
110 GenerateReusableTextureKey(updater.BodyData, updater.Params), newTextureID);
92 } 111 }
93 } 112 }
94 113
@@ -169,6 +188,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
169 { 188 {
170 if (RenderPlugins.ContainsKey(contentType)) 189 if (RenderPlugins.ContainsKey(contentType))
171 { 190 {
191 // If we want to reuse dynamic textures then we have to ignore any request from the caller to expire
192 // them.
193 if (ReuseTextures)
194 disp = disp & ~DISP_EXPIRE;
195
172 DynamicTextureUpdater updater = new DynamicTextureUpdater(); 196 DynamicTextureUpdater updater = new DynamicTextureUpdater();
173 updater.SimUUID = simID; 197 updater.SimUUID = simID;
174 updater.PrimID = primID; 198 updater.PrimID = primID;
@@ -183,21 +207,49 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
183 updater.Url = "Local image"; 207 updater.Url = "Local image";
184 updater.Disp = disp; 208 updater.Disp = disp;
185 209
186 lock (Updaters) 210 object reusableTextureUUID = null;
211
212 if (ReuseTextures)
213 reusableTextureUUID
214 = m_reuseableDynamicTextures.Get(GenerateReusableTextureKey(data, extraParams));
215
216 // We cannot reuse a dynamic texture if the data is going to be blended with something already there.
217 if (reusableTextureUUID == null || updater.BlendWithOldTexture)
187 { 218 {
188 if (!Updaters.ContainsKey(updater.UpdaterID)) 219 lock (Updaters)
189 { 220 {
190 Updaters.Add(updater.UpdaterID, updater); 221 if (!Updaters.ContainsKey(updater.UpdaterID))
222 {
223 Updaters.Add(updater.UpdaterID, updater);
224 }
225 }
226
227 RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams);
228 }
229 else
230 {
231 // No need to add to updaters as the texture is always the same. Not that this functionality
232 // apppears to be implemented anyway.
233 if (RegisteredScenes.ContainsKey(updater.SimUUID))
234 {
235 SceneObjectPart part = RegisteredScenes[updater.SimUUID].GetSceneObjectPart(updater.PrimID);
236
237 if (part != null)
238 updater.UpdatePart(part, (UUID)reusableTextureUUID);
191 } 239 }
192 } 240 }
193 241
194 RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams);
195 return updater.UpdaterID; 242 return updater.UpdaterID;
196 } 243 }
197 244
198 return UUID.Zero; 245 return UUID.Zero;
199 } 246 }
200 247
248 private string GenerateReusableTextureKey(string data, string extraParams)
249 {
250 return string.Format("{0}{1}", data, extraParams);
251 }
252
201 public void GetDrawStringSize(string contentType, string text, string fontName, int fontSize, 253 public void GetDrawStringSize(string contentType, string text, string fontName, int fontSize,
202 out double xSize, out double ySize) 254 out double xSize, out double ySize)
203 { 255 {
@@ -224,6 +276,12 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
224 276
225 public void PostInitialise() 277 public void PostInitialise()
226 { 278 {
279// ReuseTextures = true;
280 if (ReuseTextures)
281 {
282 m_reuseableDynamicTextures = new Cache(CacheMedium.Memory, CacheStrategy.Conservative);
283 m_reuseableDynamicTextures.DefaultTTL = new TimeSpan(24, 0, 0);
284 }
227 } 285 }
228 286
229 public void Close() 287 public void Close()
@@ -269,9 +327,60 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
269 } 327 }
270 328
271 /// <summary> 329 /// <summary>
330 /// Update the given part with the new texture.
331 /// </summary>
332 /// <returns>
333 /// The old texture UUID.
334 /// </returns>
335 public UUID UpdatePart(SceneObjectPart part, UUID textureID)
336 {
337 UUID oldID;
338
339 lock (part)
340 {
341 // mostly keep the values from before
342 Primitive.TextureEntry tmptex = part.Shape.Textures;
343
344 // FIXME: Need to return the appropriate ID if only a single face is replaced.
345 oldID = tmptex.DefaultTexture.TextureID;
346
347 if (Face == ALL_SIDES)
348 {
349 oldID = tmptex.DefaultTexture.TextureID;
350 tmptex.DefaultTexture.TextureID = textureID;
351 }
352 else
353 {
354 try
355 {
356 Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face);
357 texface.TextureID = textureID;
358 tmptex.FaceTextures[Face] = texface;
359 }
360 catch (Exception)
361 {
362 tmptex.DefaultTexture.TextureID = textureID;
363 }
364 }
365
366 // I'm pretty sure we always want to force this to true
367 // I'm pretty sure noone whats to set fullbright true if it wasn't true before.
368 // tmptex.DefaultTexture.Fullbright = true;
369
370 part.UpdateTextureEntry(tmptex.GetBytes());
371 }
372
373 return oldID;
374 }
375
376 /// <summary>
272 /// Called once new texture data has been received for this updater. 377 /// Called once new texture data has been received for this updater.
273 /// </summary> 378 /// </summary>
274 public void DataReceived(byte[] data, Scene scene) 379 /// <param name="data"></param>
380 /// <param name="scene"></param>
381 /// <param name="isReuseable">True if the data given is reuseable.</param>
382 /// <returns>The asset UUID given to the incoming data.</returns>
383 public UUID DataReceived(byte[] data, Scene scene)
275 { 384 {
276 SceneObjectPart part = scene.GetSceneObjectPart(PrimID); 385 SceneObjectPart part = scene.GetSceneObjectPart(PrimID);
277 386
@@ -281,7 +390,8 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
281 String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url); 390 String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url);
282 scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say, 391 scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say,
283 0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false); 392 0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false);
284 return; 393
394 return UUID.Zero;
285 } 395 }
286 396
287 byte[] assetData = null; 397 byte[] assetData = null;
@@ -323,52 +433,23 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
323 cacheLayerDecode = null; 433 cacheLayerDecode = null;
324 } 434 }
325 435
326 UUID oldID = UUID.Zero; 436 UUID oldID = UpdatePart(part, asset.FullID);
327
328 lock (part)
329 {
330 // mostly keep the values from before
331 Primitive.TextureEntry tmptex = part.Shape.Textures;
332
333 // remove the old asset from the cache
334 oldID = tmptex.DefaultTexture.TextureID;
335
336 if (Face == ALL_SIDES)
337 {
338 tmptex.DefaultTexture.TextureID = asset.FullID;
339 }
340 else
341 {
342 try
343 {
344 Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face);
345 texface.TextureID = asset.FullID;
346 tmptex.FaceTextures[Face] = texface;
347 }
348 catch (Exception)
349 {
350 tmptex.DefaultTexture.TextureID = asset.FullID;
351 }
352 }
353
354 // I'm pretty sure we always want to force this to true
355 // I'm pretty sure noone whats to set fullbright true if it wasn't true before.
356 // tmptex.DefaultTexture.Fullbright = true;
357
358 part.UpdateTextureEntry(tmptex.GetBytes());
359 }
360 437
361 if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0)) 438 if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0))
362 { 439 {
363 if (oldAsset == null) oldAsset = scene.AssetService.Get(oldID.ToString()); 440 if (oldAsset == null)
441 oldAsset = scene.AssetService.Get(oldID.ToString());
442
364 if (oldAsset != null) 443 if (oldAsset != null)
365 { 444 {
366 if (oldAsset.Temporary == true) 445 if (oldAsset.Temporary)
367 { 446 {
368 scene.AssetService.Delete(oldID.ToString()); 447 scene.AssetService.Delete(oldID.ToString());
369 } 448 }
370 } 449 }
371 } 450 }
451
452 return asset.FullID;
372 } 453 }
373 454
374 private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha) 455 private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha)
diff --git a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
index 6f83948..2b3a0f2 100644
--- a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
@@ -67,12 +67,18 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
67 return true; 67 return true;
68 } 68 }
69 69
70// public bool AlwaysIdenticalConversion(string bodyData, string extraParams)
71// {
72// // We don't support conversion of body data.
73// return false;
74// }
75
70 public byte[] ConvertUrl(string url, string extraParams) 76 public byte[] ConvertUrl(string url, string extraParams)
71 { 77 {
72 return null; 78 return null;
73 } 79 }
74 80
75 public byte[] ConvertStream(Stream data, string extraParams) 81 public byte[] ConvertData(string bodyData, string extraParams)
76 { 82 {
77 return null; 83 return null;
78 } 84 }
@@ -236,9 +242,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
236 stream.Close(); 242 stream.Close();
237 } 243 }
238 } 244 }
245
239 m_log.DebugFormat("[LOADIMAGEURLMODULE] Returning {0} bytes of image data for request {1}", 246 m_log.DebugFormat("[LOADIMAGEURLMODULE] Returning {0} bytes of image data for request {1}",
240 imageJ2000.Length, state.RequestID); 247 imageJ2000.Length, state.RequestID);
241 m_textureManager.ReturnData(state.RequestID, imageJ2000); 248
249 m_textureManager.ReturnData(state.RequestID, imageJ2000, false);
242 } 250 }
243 251
244 #region Nested type: RequestState 252 #region Nested type: RequestState
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
index 9787c8c..b50c0bd 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
@@ -45,31 +45,250 @@ using OpenSim.Tests.Common.Mock;
45namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests 45namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
46{ 46{
47 [TestFixture] 47 [TestFixture]
48 public class VectorRenderModuleTests 48 public class VectorRenderModuleTests : OpenSimTestCase
49 { 49 {
50 Scene m_scene;
51 DynamicTextureModule m_dtm;
52 VectorRenderModule m_vrm;
53
54 private void SetupScene(bool reuseTextures)
55 {
56 m_scene = new SceneHelpers().SetupScene();
57
58 m_dtm = new DynamicTextureModule();
59 m_dtm.ReuseTextures = reuseTextures;
60
61 m_vrm = new VectorRenderModule();
62
63 SceneHelpers.SetupSceneModules(m_scene, m_dtm, m_vrm);
64 }
65
50 [Test] 66 [Test]
51 public void TestDraw() 67 public void TestDraw()
52 { 68 {
53 TestHelpers.InMethod(); 69 TestHelpers.InMethod();
54 70
55 Scene scene = new SceneHelpers().SetupScene(); 71 SetupScene(false);
56 DynamicTextureModule dtm = new DynamicTextureModule(); 72 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
57 VectorRenderModule vrm = new VectorRenderModule();
58 SceneHelpers.SetupSceneModules(scene, dtm, vrm);
59
60 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene);
61 UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; 73 UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
62 74
63 dtm.AddDynamicTextureData( 75 m_dtm.AddDynamicTextureData(
64 scene.RegionInfo.RegionID, 76 m_scene.RegionInfo.RegionID,
65 so.UUID, 77 so.UUID,
66 vrm.GetContentType(), 78 m_vrm.GetContentType(),
67 "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;", 79 "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;",
68 "", 80 "",
69 0); 81 0);
70 82
83 Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
84 }
85
86 [Test]
87 public void TestRepeatSameDraw()
88 {
89 TestHelpers.InMethod();
90
91 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
92
93 SetupScene(false);
94 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
95
96 m_dtm.AddDynamicTextureData(
97 m_scene.RegionInfo.RegionID,
98 so.UUID,
99 m_vrm.GetContentType(),
100 dtText,
101 "",
102 0);
103
104 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
105
106 m_dtm.AddDynamicTextureData(
107 m_scene.RegionInfo.RegionID,
108 so.UUID,
109 m_vrm.GetContentType(),
110 dtText,
111 "",
112 0);
113
114 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
115 }
116
117 [Test]
118 public void TestRepeatSameDrawDifferentExtraParams()
119 {
120 TestHelpers.InMethod();
121
122 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
123
124 SetupScene(false);
125 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
126
127 m_dtm.AddDynamicTextureData(
128 m_scene.RegionInfo.RegionID,
129 so.UUID,
130 m_vrm.GetContentType(),
131 dtText,
132 "",
133 0);
134
135 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
136
137 m_dtm.AddDynamicTextureData(
138 m_scene.RegionInfo.RegionID,
139 so.UUID,
140 m_vrm.GetContentType(),
141 dtText,
142 "alpha:250",
143 0);
144
145 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
146 }
147
148 [Test]
149 public void TestRepeatSameDrawContainingImage()
150 {
151 TestHelpers.InMethod();
152
153 string dtText
154 = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://localhost/shouldnotexist.png";
155
156 SetupScene(false);
157 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
158
159 m_dtm.AddDynamicTextureData(
160 m_scene.RegionInfo.RegionID,
161 so.UUID,
162 m_vrm.GetContentType(),
163 dtText,
164 "",
165 0);
166
167 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
168
169 m_dtm.AddDynamicTextureData(
170 m_scene.RegionInfo.RegionID,
171 so.UUID,
172 m_vrm.GetContentType(),
173 dtText,
174 "",
175 0);
176
177 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
178 }
179
180 [Test]
181 public void TestDrawReusingTexture()
182 {
183 TestHelpers.InMethod();
184
185 SetupScene(true);
186 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
187 UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
188
189 m_dtm.AddDynamicTextureData(
190 m_scene.RegionInfo.RegionID,
191 so.UUID,
192 m_vrm.GetContentType(),
193 "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;",
194 "",
195 0);
71 196
72 Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); 197 Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
73 } 198 }
199
200 [Test]
201 public void TestRepeatSameDrawReusingTexture()
202 {
203 TestHelpers.InMethod();
204
205 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
206
207 SetupScene(true);
208 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
209
210 m_dtm.AddDynamicTextureData(
211 m_scene.RegionInfo.RegionID,
212 so.UUID,
213 m_vrm.GetContentType(),
214 dtText,
215 "",
216 0);
217
218 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
219
220 m_dtm.AddDynamicTextureData(
221 m_scene.RegionInfo.RegionID,
222 so.UUID,
223 m_vrm.GetContentType(),
224 dtText,
225 "",
226 0);
227
228 Assert.That(firstDynamicTextureID, Is.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
229 }
230
231 [Test]
232 public void TestRepeatSameDrawDifferentExtraParamsReusingTexture()
233 {
234 TestHelpers.InMethod();
235
236 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
237
238 SetupScene(true);
239 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
240
241 m_dtm.AddDynamicTextureData(
242 m_scene.RegionInfo.RegionID,
243 so.UUID,
244 m_vrm.GetContentType(),
245 dtText,
246 "",
247 0);
248
249 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
250
251 m_dtm.AddDynamicTextureData(
252 m_scene.RegionInfo.RegionID,
253 so.UUID,
254 m_vrm.GetContentType(),
255 dtText,
256 "alpha:250",
257 0);
258
259 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
260 }
261
262 [Test]
263 public void TestRepeatSameDrawContainingImageReusingTexture()
264 {
265 TestHelpers.InMethod();
266
267 string dtText
268 = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://localhost/shouldnotexist.png";
269
270 SetupScene(true);
271 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
272
273 m_dtm.AddDynamicTextureData(
274 m_scene.RegionInfo.RegionID,
275 so.UUID,
276 m_vrm.GetContentType(),
277 dtText,
278 "",
279 0);
280
281 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
282
283 m_dtm.AddDynamicTextureData(
284 m_scene.RegionInfo.RegionID,
285 so.UUID,
286 m_vrm.GetContentType(),
287 dtText,
288 "",
289 0);
290
291 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
292 }
74 } 293 }
75} \ No newline at end of file 294} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
index 8b2f2f8..f687646 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
@@ -30,6 +30,7 @@ using System.Drawing;
30using System.Drawing.Imaging; 30using System.Drawing.Imaging;
31using System.Globalization; 31using System.Globalization;
32using System.IO; 32using System.IO;
33using System.Linq;
33using System.Net; 34using System.Net;
34using Nini.Config; 35using Nini.Config;
35using OpenMetaverse; 36using OpenMetaverse;
@@ -47,7 +48,6 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
47 { 48 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49 50
50 private string m_name = "VectorRenderModule";
51 private Scene m_scene; 51 private Scene m_scene;
52 private IDynamicTextureManager m_textureManager; 52 private IDynamicTextureManager m_textureManager;
53 private Graphics m_graph; 53 private Graphics m_graph;
@@ -61,12 +61,12 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
61 61
62 public string GetContentType() 62 public string GetContentType()
63 { 63 {
64 return ("vector"); 64 return "vector";
65 } 65 }
66 66
67 public string GetName() 67 public string GetName()
68 { 68 {
69 return m_name; 69 return Name;
70 } 70 }
71 71
72 public bool SupportsAsynchronous() 72 public bool SupportsAsynchronous()
@@ -74,14 +74,26 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
74 return true; 74 return true;
75 } 75 }
76 76
77// public bool AlwaysIdenticalConversion(string bodyData, string extraParams)
78// {
79// string[] lines = GetLines(bodyData);
80// return lines.Any((str, r) => str.StartsWith("Image"));
81// }
82
77 public byte[] ConvertUrl(string url, string extraParams) 83 public byte[] ConvertUrl(string url, string extraParams)
78 { 84 {
79 return null; 85 return null;
80 } 86 }
81 87
82 public byte[] ConvertStream(Stream data, string extraParams) 88 public byte[] ConvertData(string bodyData, string extraParams)
83 { 89 {
84 return null; 90 bool reuseable;
91 return Draw(bodyData, extraParams, out reuseable);
92 }
93
94 private byte[] ConvertData(string bodyData, string extraParams, out bool reuseable)
95 {
96 return Draw(bodyData, extraParams, out reuseable);
85 } 97 }
86 98
87 public bool AsyncConvertUrl(UUID id, string url, string extraParams) 99 public bool AsyncConvertUrl(UUID id, string url, string extraParams)
@@ -91,7 +103,12 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
91 103
92 public bool AsyncConvertData(UUID id, string bodyData, string extraParams) 104 public bool AsyncConvertData(UUID id, string bodyData, string extraParams)
93 { 105 {
94 Draw(bodyData, id, extraParams); 106 // XXX: This isn't actually being done asynchronously!
107 bool reuseable;
108 byte[] data = ConvertData(bodyData, extraParams, out reuseable);
109
110 m_textureManager.ReturnData(id, data, reuseable);
111
95 return true; 112 return true;
96 } 113 }
97 114
@@ -152,7 +169,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
152 169
153 public string Name 170 public string Name
154 { 171 {
155 get { return m_name; } 172 get { return "VectorRenderModule"; }
156 } 173 }
157 174
158 public bool IsSharedModule 175 public bool IsSharedModule
@@ -162,7 +179,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
162 179
163 #endregion 180 #endregion
164 181
165 private void Draw(string data, UUID id, string extraParams) 182 private byte[] Draw(string data, string extraParams, out bool reuseable)
166 { 183 {
167 // We need to cater for old scripts that didnt use extraParams neatly, they use either an integer size which represents both width and height, or setalpha 184 // We need to cater for old scripts that didnt use extraParams neatly, they use either an integer size which represents both width and height, or setalpha
168 // we will now support multiple comma seperated params in the form width:256,height:512,alpha:255 185 // we will now support multiple comma seperated params in the form width:256,height:512,alpha:255
@@ -308,36 +325,44 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
308 325
309 try 326 try
310 { 327 {
311 if (alpha == 256) 328 // XXX: In testing, it appears that if multiple threads dispose of separate GDI+ objects simultaneously,
312 bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb); 329 // the native malloc heap can become corrupted, possibly due to a double free(). This may be due to
313 else 330 // bugs in the underlying libcairo used by mono's libgdiplus.dll on Linux/OSX. These problems were
314 bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb); 331 // seen with both libcario 1.10.2-6.1ubuntu3 and 1.8.10-2ubuntu1. They go away if disposal is perfomed
315 332 // under lock.
316 graph = Graphics.FromImage(bitmap); 333 lock (this)
317
318 // this is really just to save people filling the
319 // background color in their scripts, only do when fully opaque
320 if (alpha >= 255)
321 { 334 {
322 using (SolidBrush bgFillBrush = new SolidBrush(bgColor)) 335 if (alpha == 256)
336 bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);
337 else
338 bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
339
340 graph = Graphics.FromImage(bitmap);
341
342 // this is really just to save people filling the
343 // background color in their scripts, only do when fully opaque
344 if (alpha >= 255)
323 { 345 {
324 graph.FillRectangle(bgFillBrush, 0, 0, width, height); 346 using (SolidBrush bgFillBrush = new SolidBrush(bgColor))
347 {
348 graph.FillRectangle(bgFillBrush, 0, 0, width, height);
349 }
325 } 350 }
326 } 351
327 352 for (int w = 0; w < bitmap.Width; w++)
328 for (int w = 0; w < bitmap.Width; w++)
329 {
330 if (alpha <= 255)
331 { 353 {
332 for (int h = 0; h < bitmap.Height; h++) 354 if (alpha <= 255)
333 { 355 {
334 bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h))); 356 for (int h = 0; h < bitmap.Height; h++)
357 {
358 bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h)));
359 }
335 } 360 }
336 } 361 }
362
363 GDIDraw(data, graph, altDataDelim, out reuseable);
337 } 364 }
338 365
339 GDIDraw(data, graph, altDataDelim);
340
341 byte[] imageJ2000 = new byte[0]; 366 byte[] imageJ2000 = new byte[0];
342 367
343 try 368 try
@@ -351,15 +376,23 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
351 e.Message, e.StackTrace); 376 e.Message, e.StackTrace);
352 } 377 }
353 378
354 m_textureManager.ReturnData(id, imageJ2000); 379 return imageJ2000;
355 } 380 }
356 finally 381 finally
357 { 382 {
358 if (graph != null) 383 // XXX: In testing, it appears that if multiple threads dispose of separate GDI+ objects simultaneously,
359 graph.Dispose(); 384 // the native malloc heap can become corrupted, possibly due to a double free(). This may be due to
360 385 // bugs in the underlying libcairo used by mono's libgdiplus.dll on Linux/OSX. These problems were
361 if (bitmap != null) 386 // seen with both libcario 1.10.2-6.1ubuntu3 and 1.8.10-2ubuntu1. They go away if disposal is perfomed
362 bitmap.Dispose(); 387 // under lock.
388 lock (this)
389 {
390 if (graph != null)
391 graph.Dispose();
392
393 if (bitmap != null)
394 bitmap.Dispose();
395 }
363 } 396 }
364 } 397 }
365 398
@@ -418,8 +451,21 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
418 } 451 }
419*/ 452*/
420 453
421 private void GDIDraw(string data, Graphics graph, char dataDelim) 454 /// <summary>
455 /// Split input data into discrete command lines.
456 /// </summary>
457 /// <returns></returns>
458 /// <param name='data'></param>
459 /// <param name='dataDelim'></param>
460 private string[] GetLines(string data, char dataDelim)
461 {
462 char[] lineDelimiter = { dataDelim };
463 return data.Split(lineDelimiter);
464 }
465
466 private void GDIDraw(string data, Graphics graph, char dataDelim, out bool reuseable)
422 { 467 {
468 reuseable = true;
423 Point startPoint = new Point(0, 0); 469 Point startPoint = new Point(0, 0);
424 Point endPoint = new Point(0, 0); 470 Point endPoint = new Point(0, 0);
425 Pen drawPen = null; 471 Pen drawPen = null;
@@ -434,11 +480,9 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
434 myFont = new Font(fontName, fontSize); 480 myFont = new Font(fontName, fontSize);
435 myBrush = new SolidBrush(Color.Black); 481 myBrush = new SolidBrush(Color.Black);
436 482
437 char[] lineDelimiter = {dataDelim};
438 char[] partsDelimiter = {','}; 483 char[] partsDelimiter = {','};
439 string[] lines = data.Split(lineDelimiter);
440 484
441 foreach (string line in lines) 485 foreach (string line in GetLines(data, dataDelim))
442 { 486 {
443 string nextLine = line.Trim(); 487 string nextLine = line.Trim();
444 //replace with switch, or even better, do some proper parsing 488 //replace with switch, or even better, do some proper parsing
@@ -469,6 +513,10 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
469 } 513 }
470 else if (nextLine.StartsWith("Image")) 514 else if (nextLine.StartsWith("Image"))
471 { 515 {
516 // We cannot reuse any generated texture involving fetching an image via HTTP since that image
517 // can change.
518 reuseable = false;
519
472 float x = 0; 520 float x = 0;
473 float y = 0; 521 float y = 0;
474 GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y); 522 GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y);
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
index 6eb99ea..8ed1833 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
@@ -313,7 +313,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
313 313
314 if (m_scenes.ContainsKey(destination.RegionID)) 314 if (m_scenes.ContainsKey(destination.RegionID))
315 { 315 {
316 Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id); }); 316// m_log.DebugFormat(
317// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
318// s.RegionInfo.RegionName, destination.RegionHandle);
319
320 Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id, false); });
317 return true; 321 return true;
318 } 322 }
319 //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent"); 323 //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent");
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index 619550c..142567b 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -97,6 +97,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver
97 } 97 }
98 } 98 }
99 99
100 /// <summary>
101 /// Used to cache lookups for valid groups.
102 /// </summary>
103 private IDictionary<UUID, bool> m_validGroupUuids = new Dictionary<UUID, bool>();
104
105 private IGroupsModule m_groupsModule;
106
100 public ArchiveReadRequest(Scene scene, string loadPath, bool merge, bool skipAssets, Guid requestId) 107 public ArchiveReadRequest(Scene scene, string loadPath, bool merge, bool skipAssets, Guid requestId)
101 { 108 {
102 m_scene = scene; 109 m_scene = scene;
@@ -120,6 +127,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
120 127
121 // Zero can never be a valid user id 128 // Zero can never be a valid user id
122 m_validUserUuids[UUID.Zero] = false; 129 m_validUserUuids[UUID.Zero] = false;
130
131 m_groupsModule = m_scene.RequestModuleInterface<IGroupsModule>();
123 } 132 }
124 133
125 public ArchiveReadRequest(Scene scene, Stream loadStream, bool merge, bool skipAssets, Guid requestId) 134 public ArchiveReadRequest(Scene scene, Stream loadStream, bool merge, bool skipAssets, Guid requestId)
@@ -132,6 +141,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
132 141
133 // Zero can never be a valid user id 142 // Zero can never be a valid user id
134 m_validUserUuids[UUID.Zero] = false; 143 m_validUserUuids[UUID.Zero] = false;
144
145 m_groupsModule = m_scene.RequestModuleInterface<IGroupsModule>();
135 } 146 }
136 147
137 /// <summary> 148 /// <summary>
@@ -302,6 +313,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
302 if (!ResolveUserUuid(part.LastOwnerID)) 313 if (!ResolveUserUuid(part.LastOwnerID))
303 part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 314 part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
304 315
316 if (!ResolveGroupUuid(part.GroupID))
317 part.GroupID = UUID.Zero;
318
305 // And zap any troublesome sit target information 319 // And zap any troublesome sit target information
306// part.SitTargetOrientation = new Quaternion(0, 0, 0, 1); 320// part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
307// part.SitTargetPosition = new Vector3(0, 0, 0); 321// part.SitTargetPosition = new Vector3(0, 0, 0);
@@ -335,13 +349,18 @@ namespace OpenSim.Region.CoreModules.World.Archiver
335 { 349 {
336 kvp.Value.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 350 kvp.Value.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
337 } 351 }
352
338 if (kvp.Value.CreatorData == null || kvp.Value.CreatorData == string.Empty) 353 if (kvp.Value.CreatorData == null || kvp.Value.CreatorData == string.Empty)
339 { 354 {
340 if (!ResolveUserUuid(kvp.Value.CreatorID)) 355 if (!ResolveUserUuid(kvp.Value.CreatorID))
341 kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; 356 kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner;
342 } 357 }
358
343 if (UserManager != null) 359 if (UserManager != null)
344 UserManager.AddUser(kvp.Value.CreatorID, kvp.Value.CreatorData); 360 UserManager.AddUser(kvp.Value.CreatorID, kvp.Value.CreatorData);
361
362 if (!ResolveGroupUuid(kvp.Value.GroupID))
363 kvp.Value.GroupID = UUID.Zero;
345 } 364 }
346 part.TaskInventory.LockItemsForRead(false); 365 part.TaskInventory.LockItemsForRead(false);
347 } 366 }
@@ -382,9 +401,27 @@ namespace OpenSim.Region.CoreModules.World.Archiver
382 foreach (string serialisedParcel in serialisedParcels) 401 foreach (string serialisedParcel in serialisedParcels)
383 { 402 {
384 LandData parcel = LandDataSerializer.Deserialize(serialisedParcel); 403 LandData parcel = LandDataSerializer.Deserialize(serialisedParcel);
404
405 // Validate User and Group UUID's
406
385 if (!ResolveUserUuid(parcel.OwnerID)) 407 if (!ResolveUserUuid(parcel.OwnerID))
386 parcel.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 408 parcel.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
387 409
410 if (!ResolveGroupUuid(parcel.GroupID))
411 {
412 parcel.GroupID = UUID.Zero;
413 parcel.IsGroupOwned = false;
414 }
415
416 List<LandAccessEntry> accessList = new List<LandAccessEntry>();
417 foreach (LandAccessEntry entry in parcel.ParcelAccessList)
418 {
419 if (ResolveUserUuid(entry.AgentID))
420 accessList.Add(entry);
421 // else, drop this access rule
422 }
423 parcel.ParcelAccessList = accessList;
424
388// m_log.DebugFormat( 425// m_log.DebugFormat(
389// "[ARCHIVER]: Adding parcel {0}, local id {1}, area {2}", 426// "[ARCHIVER]: Adding parcel {0}, local id {1}, area {2}",
390// parcel.Name, parcel.LocalID, parcel.Area); 427// parcel.Name, parcel.LocalID, parcel.Area);
@@ -419,6 +456,30 @@ namespace OpenSim.Region.CoreModules.World.Archiver
419 } 456 }
420 457
421 /// <summary> 458 /// <summary>
459 /// Look up the given group id to check whether it's one that is valid for this grid.
460 /// </summary>
461 /// <param name="uuid"></param>
462 /// <returns></returns>
463 private bool ResolveGroupUuid(UUID uuid)
464 {
465 if (uuid == UUID.Zero)
466 return true; // this means the object has no group
467
468 if (!m_validGroupUuids.ContainsKey(uuid))
469 {
470 bool exists;
471
472 if (m_groupsModule == null)
473 exists = false;
474 else
475 exists = (m_groupsModule.GetGroupRecord(uuid) != null);
476
477 m_validGroupUuids.Add(uuid, exists);
478 }
479
480 return m_validGroupUuids[uuid];
481 }
482
422 /// Load an asset 483 /// Load an asset
423 /// </summary> 484 /// </summary>
424 /// <param name="assetFilename"></param> 485 /// <param name="assetFilename"></param>
diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
index 14c1a39..a2f0950 100644
--- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
+++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
@@ -85,13 +85,15 @@ namespace OpenSim.Region.CoreModules.World.Sound
85 dis = 0; 85 dis = 0;
86 } 86 }
87 87
88 float thisSpGain;
89
88 // Scale by distance 90 // Scale by distance
89 if (radius == 0) 91 if (radius == 0)
90 gain = (float)((double)gain * ((100.0 - dis) / 100.0)); 92 thisSpGain = (float)((double)gain * ((100.0 - dis) / 100.0));
91 else 93 else
92 gain = (float)((double)gain * ((radius - dis) / radius)); 94 thisSpGain = (float)((double)gain * ((radius - dis) / radius));
93 95
94 sp.ControllingClient.SendPlayAttachedSound(soundID, objectID, ownerID, (float)gain, flags); 96 sp.ControllingClient.SendPlayAttachedSound(soundID, objectID, ownerID, thisSpGain, flags);
95 }); 97 });
96 } 98 }
97 99
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
index 402b9fb..d99567c 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
@@ -414,6 +414,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
414 private void LoadPlugins() 414 private void LoadPlugins()
415 { 415 {
416 m_plugineffects = new Dictionary<string, ITerrainEffect>(); 416 m_plugineffects = new Dictionary<string, ITerrainEffect>();
417 LoadPlugins(Assembly.GetCallingAssembly());
417 string plugineffectsPath = "Terrain"; 418 string plugineffectsPath = "Terrain";
418 419
419 // Load the files in the Terrain/ dir 420 // Load the files in the Terrain/ dir
@@ -427,34 +428,39 @@ namespace OpenSim.Region.CoreModules.World.Terrain
427 try 428 try
428 { 429 {
429 Assembly library = Assembly.LoadFrom(file); 430 Assembly library = Assembly.LoadFrom(file);
430 foreach (Type pluginType in library.GetTypes()) 431 LoadPlugins(library);
431 { 432 }
432 try 433 catch (BadImageFormatException)
433 { 434 {
434 if (pluginType.IsAbstract || pluginType.IsNotPublic) 435 }
435 continue; 436 }
437 }
436 438
437 string typeName = pluginType.Name; 439 private void LoadPlugins(Assembly library)
440 {
441 foreach (Type pluginType in library.GetTypes())
442 {
443 try
444 {
445 if (pluginType.IsAbstract || pluginType.IsNotPublic)
446 continue;
438 447
439 if (pluginType.GetInterface("ITerrainEffect", false) != null) 448 string typeName = pluginType.Name;
440 {
441 ITerrainEffect terEffect = (ITerrainEffect) Activator.CreateInstance(library.GetType(pluginType.ToString()));
442 449
443 InstallPlugin(typeName, terEffect); 450 if (pluginType.GetInterface("ITerrainEffect", false) != null)
444 } 451 {
445 else if (pluginType.GetInterface("ITerrainLoader", false) != null) 452 ITerrainEffect terEffect = (ITerrainEffect)Activator.CreateInstance(library.GetType(pluginType.ToString()));
446 { 453
447 ITerrainLoader terLoader = (ITerrainLoader) Activator.CreateInstance(library.GetType(pluginType.ToString())); 454 InstallPlugin(typeName, terEffect);
448 m_loaders[terLoader.FileExtension] = terLoader; 455 }
449 m_log.Info("L ... " + typeName); 456 else if (pluginType.GetInterface("ITerrainLoader", false) != null)
450 } 457 {
451 } 458 ITerrainLoader terLoader = (ITerrainLoader)Activator.CreateInstance(library.GetType(pluginType.ToString()));
452 catch (AmbiguousMatchException) 459 m_loaders[terLoader.FileExtension] = terLoader;
453 { 460 m_log.Info("L ... " + typeName);
454 }
455 } 461 }
456 } 462 }
457 catch (BadImageFormatException) 463 catch (AmbiguousMatchException)
458 { 464 {
459 } 465 }
460 } 466 }
@@ -1178,7 +1184,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1178 1184
1179 private void InterfaceRunPluginEffect(Object[] args) 1185 private void InterfaceRunPluginEffect(Object[] args)
1180 { 1186 {
1181 if ((string) args[0] == "list") 1187 string firstArg = (string)args[0];
1188 if (firstArg == "list")
1182 { 1189 {
1183 m_log.Info("List of loaded plugins"); 1190 m_log.Info("List of loaded plugins");
1184 foreach (KeyValuePair<string, ITerrainEffect> kvp in m_plugineffects) 1191 foreach (KeyValuePair<string, ITerrainEffect> kvp in m_plugineffects)
@@ -1187,14 +1194,14 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1187 } 1194 }
1188 return; 1195 return;
1189 } 1196 }
1190 if ((string) args[0] == "reload") 1197 if (firstArg == "reload")
1191 { 1198 {
1192 LoadPlugins(); 1199 LoadPlugins();
1193 return; 1200 return;
1194 } 1201 }
1195 if (m_plugineffects.ContainsKey((string) args[0])) 1202 if (m_plugineffects.ContainsKey(firstArg))
1196 { 1203 {
1197 m_plugineffects[(string) args[0]].RunEffect(m_channel); 1204 m_plugineffects[firstArg].RunEffect(m_channel);
1198 CheckForTerrainUpdates(); 1205 CheckForTerrainUpdates();
1199 } 1206 }
1200 else 1207 else
diff --git a/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs b/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs
index 8954513..1a3bcbb 100644
--- a/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs
+++ b/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs
@@ -33,7 +33,7 @@ namespace OpenSim.Region.Framework.Interfaces
33 public interface IDynamicTextureManager 33 public interface IDynamicTextureManager
34 { 34 {
35 void RegisterRender(string handleType, IDynamicTextureRender render); 35 void RegisterRender(string handleType, IDynamicTextureRender render);
36 void ReturnData(UUID id, byte[] data); 36 void ReturnData(UUID id, byte[] data, bool isReuseable);
37 37
38 UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams, 38 UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams,
39 int updateTimer); 39 int updateTimer);
@@ -113,8 +113,20 @@ namespace OpenSim.Region.Framework.Interfaces
113 string GetName(); 113 string GetName();
114 string GetContentType(); 114 string GetContentType();
115 bool SupportsAsynchronous(); 115 bool SupportsAsynchronous();
116
117// /// <summary>
118// /// Return true if converting the input body and extra params data will always result in the same byte[] array
119// /// </summary>
120// /// <remarks>
121// /// This method allows the caller to use a previously generated asset if it has one.
122// /// </remarks>
123// /// <returns></returns>
124// /// <param name='bodyData'></param>
125// /// <param name='extraParams'></param>
126// bool AlwaysIdenticalConversion(string bodyData, string extraParams);
127
116 byte[] ConvertUrl(string url, string extraParams); 128 byte[] ConvertUrl(string url, string extraParams);
117 byte[] ConvertStream(Stream data, string extraParams); 129 byte[] ConvertData(string bodyData, string extraParams);
118 bool AsyncConvertUrl(UUID id, string url, string extraParams); 130 bool AsyncConvertUrl(UUID id, string url, string extraParams);
119 bool AsyncConvertData(UUID id, string bodyData, string extraParams); 131 bool AsyncConvertData(UUID id, string bodyData, string extraParams);
120 void GetDrawStringSize(string text, string fontName, int fontSize, 132 void GetDrawStringSize(string text, string fontName, int fontSize,
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 1309623..863aa49 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -93,7 +93,7 @@ namespace OpenSim.Region.Framework.Scenes
93 /// </summary> 93 /// </summary>
94 public void StartScripts() 94 public void StartScripts()
95 { 95 {
96 m_log.InfoFormat("[SCENE]: Starting scripts in {0}, please wait.", RegionInfo.RegionName); 96// m_log.InfoFormat("[SCENE]: Starting scripts in {0}, please wait.", RegionInfo.RegionName);
97 97
98 IScriptModule[] engines = RequestModuleInterfaces<IScriptModule>(); 98 IScriptModule[] engines = RequestModuleInterfaces<IScriptModule>();
99 99
@@ -1986,6 +1986,9 @@ namespace OpenSim.Region.Framework.Scenes
1986 // If child prims have invalid perms, fix them 1986 // If child prims have invalid perms, fix them
1987 grp.AdjustChildPrimPermissions(); 1987 grp.AdjustChildPrimPermissions();
1988 1988
1989 // If child prims have invalid perms, fix them
1990 grp.AdjustChildPrimPermissions();
1991
1989 if (remoteClient == null) 1992 if (remoteClient == null)
1990 { 1993 {
1991 // Autoreturn has a null client. Nothing else does. So 1994 // Autoreturn has a null client. Nothing else does. So
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
index e970543..16c0d25 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -543,7 +543,7 @@ namespace OpenSim.Region.Framework.Scenes
543 if (!InventoryService.AddFolder(folder)) 543 if (!InventoryService.AddFolder(folder))
544 { 544 {
545 m_log.WarnFormat( 545 m_log.WarnFormat(
546 "[AGENT INVENTORY]: Failed to move create folder for user {0} {1}", 546 "[AGENT INVENTORY]: Failed to create folder for user {0} {1}",
547 remoteClient.Name, remoteClient.AgentId); 547 remoteClient.Name, remoteClient.AgentId);
548 } 548 }
549 } 549 }
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 0237021..8fb6c3b 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -103,8 +103,26 @@ namespace OpenSim.Region.Framework.Scenes
103 /// </summary> 103 /// </summary>
104 public bool CollidablePrims { get; private set; } 104 public bool CollidablePrims { get; private set; }
105 105
106 /// <summary>
107 /// Minimum value of the size of a non-physical prim in each axis
108 /// </summary>
109 public float m_minNonphys = 0.01f;
110
111 /// <summary>
112 /// Maximum value of the size of a non-physical prim in each axis
113 /// </summary>
106 public float m_maxNonphys = 256; 114 public float m_maxNonphys = 256;
115
116 /// <summary>
117 /// Minimum value of the size of a physical prim in each axis
118 /// </summary>
119 public float m_minPhys = 0.01f;
120
121 /// <summary>
122 /// Maximum value of the size of a physical prim in each axis
123 /// </summary>
107 public float m_maxPhys = 10; 124 public float m_maxPhys = 10;
125
108 public bool m_clampPrimSize; 126 public bool m_clampPrimSize;
109 public bool m_trustBinaries; 127 public bool m_trustBinaries;
110 public bool m_allowScriptCrossings; 128 public bool m_allowScriptCrossings;
@@ -746,12 +764,24 @@ namespace OpenSim.Region.Framework.Scenes
746 PhysicalPrims = startupConfig.GetBoolean("physical_prim", true); 764 PhysicalPrims = startupConfig.GetBoolean("physical_prim", true);
747 CollidablePrims = startupConfig.GetBoolean("collidable_prim", true); 765 CollidablePrims = startupConfig.GetBoolean("collidable_prim", true);
748 766
767 m_minNonphys = startupConfig.GetFloat("NonphysicalPrimMin", m_minNonphys);
768 if (RegionInfo.NonphysPrimMin > 0)
769 {
770 m_minNonphys = RegionInfo.NonphysPrimMin;
771 }
772
749 m_maxNonphys = startupConfig.GetFloat("NonphysicalPrimMax", m_maxNonphys); 773 m_maxNonphys = startupConfig.GetFloat("NonphysicalPrimMax", m_maxNonphys);
750 if (RegionInfo.NonphysPrimMax > 0) 774 if (RegionInfo.NonphysPrimMax > 0)
751 { 775 {
752 m_maxNonphys = RegionInfo.NonphysPrimMax; 776 m_maxNonphys = RegionInfo.NonphysPrimMax;
753 } 777 }
754 778
779 m_minPhys = startupConfig.GetFloat("PhysicalPrimMin", m_minPhys);
780 if (RegionInfo.PhysPrimMin > 0)
781 {
782 m_minPhys = RegionInfo.PhysPrimMin;
783 }
784
755 m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys); 785 m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys);
756 786
757 if (RegionInfo.PhysPrimMax > 0) 787 if (RegionInfo.PhysPrimMax > 0)
@@ -3713,7 +3743,7 @@ namespace OpenSim.Region.Framework.Scenes
3713 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", 3743 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
3714 sp.Name, sp.UUID, RegionInfo.RegionName); 3744 sp.Name, sp.UUID, RegionInfo.RegionName);
3715 3745
3716 sp.ControllingClient.Close(); 3746 sp.ControllingClient.Close(true, true);
3717 sp = null; 3747 sp = null;
3718 } 3748 }
3719 3749
@@ -4316,15 +4346,18 @@ namespace OpenSim.Region.Framework.Scenes
4316 /// Tell a single agent to disconnect from the region. 4346 /// Tell a single agent to disconnect from the region.
4317 /// </summary> 4347 /// </summary>
4318 /// <param name="agentID"></param> 4348 /// <param name="agentID"></param>
4319 /// <param name="childOnly"></param> 4349 /// <param name="force">
4320 public bool IncomingCloseAgent(UUID agentID, bool childOnly) 4350 /// Force the agent to close even if it might be in the middle of some other operation. You do not want to
4351 /// force unless you are absolutely sure that the agent is dead and a normal close is not working.
4352 /// </param>
4353 public bool IncomingCloseAgent(UUID agentID, bool force)
4321 { 4354 {
4322 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); 4355 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
4323 4356
4324 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); 4357 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
4325 if (presence != null) 4358 if (presence != null)
4326 { 4359 {
4327 presence.ControllingClient.Close(); 4360 presence.ControllingClient.Close(true, force);
4328 return true; 4361 return true;
4329 } 4362 }
4330 4363
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index e29b2c1..c4b7b27 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -342,7 +342,7 @@ namespace OpenSim.Region.Framework.Scenes
342 public bool AddNewSceneObject( 342 public bool AddNewSceneObject(
343 SceneObjectGroup sceneObject, bool attachToBackup, Vector3? pos, Quaternion? rot, Vector3 vel) 343 SceneObjectGroup sceneObject, bool attachToBackup, Vector3? pos, Quaternion? rot, Vector3 vel)
344 { 344 {
345 AddNewSceneObject(sceneObject, true, false); 345 AddNewSceneObject(sceneObject, attachToBackup, false);
346 346
347 if (pos != null) 347 if (pos != null)
348 sceneObject.AbsolutePosition = (Vector3)pos; 348 sceneObject.AbsolutePosition = (Vector3)pos;
@@ -421,12 +421,9 @@ namespace OpenSim.Region.Framework.Scenes
421 { 421 {
422 Vector3 scale = part.Shape.Scale; 422 Vector3 scale = part.Shape.Scale;
423 423
424 if (scale.X > m_parentScene.m_maxNonphys) 424 scale.X = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.X));
425 scale.X = m_parentScene.m_maxNonphys; 425 scale.Y = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.Y));
426 if (scale.Y > m_parentScene.m_maxNonphys) 426 scale.Z = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.Z));
427 scale.Y = m_parentScene.m_maxNonphys;
428 if (scale.Z > m_parentScene.m_maxNonphys)
429 scale.Z = m_parentScene.m_maxNonphys;
430 427
431 part.Shape.Scale = scale; 428 part.Shape.Scale = scale;
432 } 429 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index df4bd0d..0448c25 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -3460,17 +3460,17 @@ namespace OpenSim.Region.Framework.Scenes
3460 /// <param name="scale"></param> 3460 /// <param name="scale"></param>
3461 public void GroupResize(Vector3 scale) 3461 public void GroupResize(Vector3 scale)
3462 { 3462 {
3463 scale.X = Math.Min(scale.X, Scene.m_maxNonphys); 3463 scale.X = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.X));
3464 scale.Y = Math.Min(scale.Y, Scene.m_maxNonphys); 3464 scale.Y = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Y));
3465 scale.Z = Math.Min(scale.Z, Scene.m_maxNonphys); 3465 scale.Z = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Z));
3466 3466
3467 PhysicsActor pa = m_rootPart.PhysActor; 3467 PhysicsActor pa = m_rootPart.PhysActor;
3468 3468
3469 if (pa != null && pa.IsPhysical) 3469 if (pa != null && pa.IsPhysical)
3470 { 3470 {
3471 scale.X = Math.Min(scale.X, Scene.m_maxPhys); 3471 scale.X = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.X));
3472 scale.Y = Math.Min(scale.Y, Scene.m_maxPhys); 3472 scale.Y = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Y));
3473 scale.Z = Math.Min(scale.Z, Scene.m_maxPhys); 3473 scale.Z = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Z));
3474 } 3474 }
3475 3475
3476 float x = (scale.X / RootPart.Scale.X); 3476 float x = (scale.X / RootPart.Scale.X);
@@ -3501,6 +3501,14 @@ namespace OpenSim.Region.Framework.Scenes
3501 y *= a; 3501 y *= a;
3502 z *= a; 3502 z *= a;
3503 } 3503 }
3504 else if (oldSize.X * x < m_scene.m_minPhys)
3505 {
3506 f = m_scene.m_minPhys / oldSize.X;
3507 a = f / x;
3508 x *= a;
3509 y *= a;
3510 z *= a;
3511 }
3504 3512
3505 if (oldSize.Y * y > m_scene.m_maxPhys) 3513 if (oldSize.Y * y > m_scene.m_maxPhys)
3506 { 3514 {
@@ -3510,6 +3518,14 @@ namespace OpenSim.Region.Framework.Scenes
3510 y *= a; 3518 y *= a;
3511 z *= a; 3519 z *= a;
3512 } 3520 }
3521 else if (oldSize.Y * y < m_scene.m_minPhys)
3522 {
3523 f = m_scene.m_minPhys / oldSize.Y;
3524 a = f / y;
3525 x *= a;
3526 y *= a;
3527 z *= a;
3528 }
3513 3529
3514 if (oldSize.Z * z > m_scene.m_maxPhys) 3530 if (oldSize.Z * z > m_scene.m_maxPhys)
3515 { 3531 {
@@ -3519,6 +3535,14 @@ namespace OpenSim.Region.Framework.Scenes
3519 y *= a; 3535 y *= a;
3520 z *= a; 3536 z *= a;
3521 } 3537 }
3538 else if (oldSize.Z * z < m_scene.m_minPhys)
3539 {
3540 f = m_scene.m_minPhys / oldSize.Z;
3541 a = f / z;
3542 x *= a;
3543 y *= a;
3544 z *= a;
3545 }
3522 } 3546 }
3523 else 3547 else
3524 { 3548 {
@@ -3530,6 +3554,14 @@ namespace OpenSim.Region.Framework.Scenes
3530 y *= a; 3554 y *= a;
3531 z *= a; 3555 z *= a;
3532 } 3556 }
3557 else if (oldSize.X * x < m_scene.m_minNonphys)
3558 {
3559 f = m_scene.m_minNonphys / oldSize.X;
3560 a = f / x;
3561 x *= a;
3562 y *= a;
3563 z *= a;
3564 }
3533 3565
3534 if (oldSize.Y * y > m_scene.m_maxNonphys) 3566 if (oldSize.Y * y > m_scene.m_maxNonphys)
3535 { 3567 {
@@ -3539,6 +3571,14 @@ namespace OpenSim.Region.Framework.Scenes
3539 y *= a; 3571 y *= a;
3540 z *= a; 3572 z *= a;
3541 } 3573 }
3574 else if (oldSize.Y * y < m_scene.m_minNonphys)
3575 {
3576 f = m_scene.m_minNonphys / oldSize.Y;
3577 a = f / y;
3578 x *= a;
3579 y *= a;
3580 z *= a;
3581 }
3542 3582
3543 if (oldSize.Z * z > m_scene.m_maxNonphys) 3583 if (oldSize.Z * z > m_scene.m_maxNonphys)
3544 { 3584 {
@@ -3548,6 +3588,14 @@ namespace OpenSim.Region.Framework.Scenes
3548 y *= a; 3588 y *= a;
3549 z *= a; 3589 z *= a;
3550 } 3590 }
3591 else if (oldSize.Z * z < m_scene.m_minNonphys)
3592 {
3593 f = m_scene.m_minNonphys / oldSize.Z;
3594 a = f / z;
3595 x *= a;
3596 y *= a;
3597 z *= a;
3598 }
3551 } 3599 }
3552 } 3600 }
3553 } 3601 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 4788a24..8e419f9 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -790,7 +790,7 @@ namespace OpenSim.Region.Framework.Scenes
790 } 790 }
791 catch (Exception e) 791 catch (Exception e)
792 { 792 {
793 m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message); 793 m_log.ErrorFormat("[SCENEOBJECTPART]: GROUP POSITION. {0}", e);
794 } 794 }
795 } 795 }
796 } 796 }
@@ -2972,17 +2972,16 @@ namespace OpenSim.Region.Framework.Scenes
2972 /// <param name="scale"></param> 2972 /// <param name="scale"></param>
2973 public void Resize(Vector3 scale) 2973 public void Resize(Vector3 scale)
2974 { 2974 {
2975 scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxNonphys); 2975 scale.X = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.X));
2976 scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxNonphys); 2976 scale.Y = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Y));
2977 scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxNonphys); 2977 scale.Z = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Z));
2978 2978
2979 PhysicsActor pa = PhysActor; 2979 PhysicsActor pa = PhysActor;
2980
2981 if (pa != null && pa.IsPhysical) 2980 if (pa != null && pa.IsPhysical)
2982 { 2981 {
2983 scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxPhys); 2982 scale.X = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.X));
2984 scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxPhys); 2983 scale.Y = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Y));
2985 scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxPhys); 2984 scale.Z = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Z));
2986 } 2985 }
2987 2986
2988// m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale); 2987// m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale);
@@ -3567,23 +3566,32 @@ namespace OpenSim.Region.Framework.Scenes
3567 } 3566 }
3568 3567
3569 /// <summary> 3568 /// <summary>
3570 /// Set the color of prim faces 3569 /// Set the color & alpha of prim faces
3571 /// </summary> 3570 /// </summary>
3572 /// <param name="color"></param>
3573 /// <param name="face"></param> 3571 /// <param name="face"></param>
3574 public void SetFaceColor(Vector3 color, int face) 3572 /// <param name="color"></param>
3573 /// <param name="alpha"></param>
3574 public void SetFaceColorAlpha(int face, Vector3 color, double ?alpha)
3575 { 3575 {
3576 Vector3 clippedColor = Util.Clip(color, 0.0f, 1.0f);
3577 float clippedAlpha = alpha.HasValue ?
3578 Util.Clip((float)alpha.Value, 0.0f, 1.0f) : 0;
3579
3576 // The only way to get a deep copy/ If we don't do this, we can 3580 // The only way to get a deep copy/ If we don't do this, we can
3577 // mever detect color changes further down. 3581 // never detect color changes further down.
3578 Byte[] buf = Shape.Textures.GetBytes(); 3582 Byte[] buf = Shape.Textures.GetBytes();
3579 Primitive.TextureEntry tex = new Primitive.TextureEntry(buf, 0, buf.Length); 3583 Primitive.TextureEntry tex = new Primitive.TextureEntry(buf, 0, buf.Length);
3580 Color4 texcolor; 3584 Color4 texcolor;
3581 if (face >= 0 && face < GetNumberOfSides()) 3585 if (face >= 0 && face < GetNumberOfSides())
3582 { 3586 {
3583 texcolor = tex.CreateFace((uint)face).RGBA; 3587 texcolor = tex.CreateFace((uint)face).RGBA;
3584 texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); 3588 texcolor.R = clippedColor.X;
3585 texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); 3589 texcolor.G = clippedColor.Y;
3586 texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); 3590 texcolor.B = clippedColor.Z;
3591 if (alpha.HasValue)
3592 {
3593 texcolor.A = clippedAlpha;
3594 }
3587 tex.FaceTextures[face].RGBA = texcolor; 3595 tex.FaceTextures[face].RGBA = texcolor;
3588 UpdateTextureEntry(tex.GetBytes()); 3596 UpdateTextureEntry(tex.GetBytes());
3589 return; 3597 return;
@@ -3595,15 +3603,23 @@ namespace OpenSim.Region.Framework.Scenes
3595 if (tex.FaceTextures[i] != null) 3603 if (tex.FaceTextures[i] != null)
3596 { 3604 {
3597 texcolor = tex.FaceTextures[i].RGBA; 3605 texcolor = tex.FaceTextures[i].RGBA;
3598 texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); 3606 texcolor.R = clippedColor.X;
3599 texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); 3607 texcolor.G = clippedColor.Y;
3600 texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); 3608 texcolor.B = clippedColor.Z;
3609 if (alpha.HasValue)
3610 {
3611 texcolor.A = clippedAlpha;
3612 }
3601 tex.FaceTextures[i].RGBA = texcolor; 3613 tex.FaceTextures[i].RGBA = texcolor;
3602 } 3614 }
3603 texcolor = tex.DefaultTexture.RGBA; 3615 texcolor = tex.DefaultTexture.RGBA;
3604 texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); 3616 texcolor.R = clippedColor.X;
3605 texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); 3617 texcolor.G = clippedColor.Y;
3606 texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); 3618 texcolor.B = clippedColor.Z;
3619 if (alpha.HasValue)
3620 {
3621 texcolor.A = clippedAlpha;
3622 }
3607 tex.DefaultTexture.RGBA = texcolor; 3623 tex.DefaultTexture.RGBA = texcolor;
3608 } 3624 }
3609 UpdateTextureEntry(tex.GetBytes()); 3625 UpdateTextureEntry(tex.GetBytes());
@@ -4891,6 +4907,57 @@ namespace OpenSim.Region.Framework.Scenes
4891 ScheduleFullUpdate(); 4907 ScheduleFullUpdate();
4892 } 4908 }
4893 4909
4910 public void UpdateSlice(float begin, float end)
4911 {
4912 if (end < begin)
4913 {
4914 float temp = begin;
4915 begin = end;
4916 end = temp;
4917 }
4918 end = Math.Min(1f, Math.Max(0f, end));
4919 begin = Math.Min(Math.Min(1f, Math.Max(0f, begin)), end - 0.02f);
4920 if (begin < 0.02f && end < 0.02f)
4921 {
4922 begin = 0f;
4923 end = 0.02f;
4924 }
4925
4926 ushort uBegin = (ushort)(50000.0 * begin);
4927 ushort uEnd = (ushort)(50000.0 * (1f - end));
4928 bool updatePossiblyNeeded = false;
4929 PrimType primType = GetPrimType();
4930 if (primType == PrimType.SPHERE || primType == PrimType.TORUS || primType == PrimType.TUBE || primType == PrimType.RING)
4931 {
4932 if (m_shape.ProfileBegin != uBegin || m_shape.ProfileEnd != uEnd)
4933 {
4934 m_shape.ProfileBegin = uBegin;
4935 m_shape.ProfileEnd = uEnd;
4936 updatePossiblyNeeded = true;
4937 }
4938 }
4939 else if (m_shape.PathBegin != uBegin || m_shape.PathEnd != uEnd)
4940 {
4941 m_shape.PathBegin = uBegin;
4942 m_shape.PathEnd = uEnd;
4943 updatePossiblyNeeded = true;
4944 }
4945
4946 if (updatePossiblyNeeded && ParentGroup != null)
4947 {
4948 ParentGroup.HasGroupChanged = true;
4949 }
4950 if (updatePossiblyNeeded && PhysActor != null)
4951 {
4952 PhysActor.Shape = m_shape;
4953 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
4954 }
4955 if (updatePossiblyNeeded)
4956 {
4957 ScheduleFullUpdate();
4958 }
4959 }
4960
4894 /// <summary> 4961 /// <summary>
4895 /// If the part is a sculpt/mesh, retrieve the mesh data and reinsert it into the shape so that the physics 4962 /// If the part is a sculpt/mesh, retrieve the mesh data and reinsert it into the shape so that the physics
4896 /// engine can use it. 4963 /// engine can use it.
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 47b2ead..3e8c7e5 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -974,7 +974,9 @@ namespace OpenSim.Region.Framework.Scenes
974 { 974 {
975 if (wasChild && HasAttachments()) 975 if (wasChild && HasAttachments())
976 { 976 {
977 m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments..."); 977 m_log.DebugFormat(
978 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
979
978 // Resume scripts 980 // Resume scripts
979 Util.FireAndForget(delegate(object x) { 981 Util.FireAndForget(delegate(object x) {
980 foreach (SceneObjectGroup sog in m_attachments) 982 foreach (SceneObjectGroup sog in m_attachments)
@@ -1527,17 +1529,22 @@ namespace OpenSim.Region.Framework.Scenes
1527 bool DCFlagKeyPressed = false; 1529 bool DCFlagKeyPressed = false;
1528 Vector3 agent_control_v3 = Vector3.Zero; 1530 Vector3 agent_control_v3 = Vector3.Zero;
1529 1531
1530 bool oldflying = Flying; 1532 bool newFlying = actor.Flying;
1531 1533
1532 if (ForceFly) 1534 if (ForceFly)
1533 actor.Flying = true; 1535 newFlying = true;
1534 else if (FlyDisabled) 1536 else if (FlyDisabled)
1535 actor.Flying = false; 1537 newFlying = false;
1536 else 1538 else
1537 actor.Flying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 1539 newFlying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1538 1540
1539 if (actor.Flying != oldflying) 1541 if (actor.Flying != newFlying)
1542 {
1543 // Note: ScenePresence.Flying is actually fetched from the physical actor
1544 // so setting PhysActor.Flying here also sets the ScenePresence's value.
1545 actor.Flying = newFlying;
1540 update_movementflag = true; 1546 update_movementflag = true;
1547 }
1541 1548
1542 if (ParentID == 0) 1549 if (ParentID == 0)
1543 { 1550 {
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
index 5758869..5faf131 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
@@ -141,7 +141,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
141 TestScene scene = new SceneHelpers().SetupScene(); 141 TestScene scene = new SceneHelpers().SetupScene();
142 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); 142 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
143 143
144 scene.IncomingCloseAgent(sp.UUID); 144 scene.IncomingCloseAgent(sp.UUID, false);
145 145
146 Assert.That(scene.GetScenePresence(sp.UUID), Is.Null); 146 Assert.That(scene.GetScenePresence(sp.UUID), Is.Null);
147 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Null); 147 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Null);
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
index 44d2d45..9457ebb 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
@@ -50,9 +50,41 @@ using OpenSim.Tests.Common.Mock;
50namespace OpenSim.Region.Framework.Tests 50namespace OpenSim.Region.Framework.Tests
51{ 51{
52 [TestFixture] 52 [TestFixture]
53 public class UserInventoryTests 53 public class UserInventoryTests : OpenSimTestCase
54 { 54 {
55 [Test] 55 [Test]
56 public void TestCreateInventoryFolders()
57 {
58 TestHelpers.InMethod();
59// TestHelpers.EnableLogging();
60
61 // For this test both folders will have the same name which is legal in SL user inventories.
62 string foldersName = "f1";
63
64 Scene scene = new SceneHelpers().SetupScene();
65 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001));
66
67 UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, foldersName);
68
69 List<InventoryFolderBase> oneFolder
70 = UserInventoryHelpers.GetInventoryFolders(scene.InventoryService, user1.PrincipalID, foldersName);
71
72 Assert.That(oneFolder.Count, Is.EqualTo(1));
73 InventoryFolderBase firstRetrievedFolder = oneFolder[0];
74 Assert.That(firstRetrievedFolder.Name, Is.EqualTo(foldersName));
75
76 UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, foldersName);
77
78 List<InventoryFolderBase> twoFolders
79 = UserInventoryHelpers.GetInventoryFolders(scene.InventoryService, user1.PrincipalID, foldersName);
80
81 Assert.That(twoFolders.Count, Is.EqualTo(2));
82 Assert.That(twoFolders[0].Name, Is.EqualTo(foldersName));
83 Assert.That(twoFolders[1].Name, Is.EqualTo(foldersName));
84 Assert.That(twoFolders[0].ID, Is.Not.EqualTo(twoFolders[1].ID));
85 }
86
87 [Test]
56 public void TestGiveInventoryItem() 88 public void TestGiveInventoryItem()
57 { 89 {
58 TestHelpers.InMethod(); 90 TestHelpers.InMethod();
@@ -83,7 +115,7 @@ namespace OpenSim.Region.Framework.Tests
83 public void TestGiveInventoryFolder() 115 public void TestGiveInventoryFolder()
84 { 116 {
85 TestHelpers.InMethod(); 117 TestHelpers.InMethod();
86// log4net.Config.XmlConfigurator.Configure(); 118// TestHelpers.EnableLogging();
87 119
88 Scene scene = new SceneHelpers().SetupScene(); 120 Scene scene = new SceneHelpers().SetupScene();
89 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001)); 121 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001));
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 3b83e58..1660c45 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -890,10 +890,10 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
890 890
891 public void Close() 891 public void Close()
892 { 892 {
893 Close(true); 893 Close(true, false);
894 } 894 }
895 895
896 public void Close(bool sendStop) 896 public void Close(bool sendStop, bool force)
897 { 897 {
898 Disconnect(); 898 Disconnect();
899 } 899 }
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index d00a6c0..625342e 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -905,11 +905,13 @@ namespace OpenSim.Region.OptionalModules.World.NPC
905 905
906 public void Close() 906 public void Close()
907 { 907 {
908 Close(true); 908 Close(true, false);
909 } 909 }
910 910
911 public void Close(bool sendStop) 911 public void Close(bool sendStop, bool force)
912 { 912 {
913 // Remove ourselves from the scene
914 m_scene.RemoveClient(AgentId, false);
913 } 915 }
914 916
915 public void Start() 917 public void Start()
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index e2f7af9..1b23a36 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -124,10 +124,14 @@ public class BSCharacter : PhysicsActor
124 // do actual create at taint time 124 // do actual create at taint time
125 _scene.TaintedObject("BSCharacter.create", delegate() 125 _scene.TaintedObject("BSCharacter.create", delegate()
126 { 126 {
127 DetailLog("{0},BSCharacter.create", _localID);
127 BulletSimAPI.CreateObject(parent_scene.WorldID, shapeData); 128 BulletSimAPI.CreateObject(parent_scene.WorldID, shapeData);
128 129
130 // Set the buoyancy for flying. This will be refactored when all the settings happen in C#
131 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy);
132
129 m_body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID)); 133 m_body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID));
130 // avatars get all collisions no matter what 134 // avatars get all collisions no matter what (makes walking on ground and such work)
131 BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 135 BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
132 }); 136 });
133 137
@@ -137,7 +141,7 @@ public class BSCharacter : PhysicsActor
137 // called when this character is being destroyed and the resources should be released 141 // called when this character is being destroyed and the resources should be released
138 public void Destroy() 142 public void Destroy()
139 { 143 {
140 // DetailLog("{0},BSCharacter.Destroy", LocalID); 144 DetailLog("{0},BSCharacter.Destroy", LocalID);
141 _scene.TaintedObject("BSCharacter.destroy", delegate() 145 _scene.TaintedObject("BSCharacter.destroy", delegate()
142 { 146 {
143 BulletSimAPI.DestroyObject(_scene.WorldID, _localID); 147 BulletSimAPI.DestroyObject(_scene.WorldID, _localID);
@@ -319,14 +323,13 @@ public class BSCharacter : PhysicsActor
319 public override bool Flying { 323 public override bool Flying {
320 get { return _flying; } 324 get { return _flying; }
321 set { 325 set {
322 if (_flying != value) 326 _flying = value;
323 { 327 // simulate flying by changing the effect of gravity
324 _flying = value; 328 this.Buoyancy = ComputeBuoyancyFromFlying(_flying);
325 // simulate flying by changing the effect of gravity
326 this.Buoyancy = ComputeBuoyancyFromFlying(_flying);
327 }
328 } 329 }
329 } 330 }
331 // Flying is implimented by changing the avatar's buoyancy.
332 // Would this be done better with a vehicle type?
330 private float ComputeBuoyancyFromFlying(bool ifFlying) { 333 private float ComputeBuoyancyFromFlying(bool ifFlying) {
331 return ifFlying ? 1f : 0f; 334 return ifFlying ? 1f : 0f;
332 } 335 }
@@ -488,11 +491,9 @@ public class BSCharacter : PhysicsActor
488 // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. 491 // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
489 // base.RequestPhysicsterseUpdate(); 492 // base.RequestPhysicsterseUpdate();
490 493
491 /*
492 DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", 494 DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
493 LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, 495 LocalID, entprop.Position, entprop.Rotation, entprop.Velocity,
494 entprop.Acceleration, entprop.RotationalVelocity); 496 entprop.Acceleration, entprop.RotationalVelocity);
495 */
496 } 497 }
497 498
498 // Called by the scene when a collision with this object is reported 499 // Called by the scene when a collision with this object is reported
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 5a9f135..d7213fc 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -57,6 +57,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
57 private int frcount = 0; // Used to limit dynamics debug output to 57 private int frcount = 0; // Used to limit dynamics debug output to
58 // every 100th frame 58 // every 100th frame
59 59
60 private BSScene m_physicsScene;
60 private BSPrim m_prim; // the prim this dynamic controller belongs to 61 private BSPrim m_prim; // the prim this dynamic controller belongs to
61 62
62 // Vehicle properties 63 // Vehicle properties
@@ -74,7 +75,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
74 // HOVER_UP_ONLY 75 // HOVER_UP_ONLY
75 // LIMIT_MOTOR_UP 76 // LIMIT_MOTOR_UP
76 // LIMIT_ROLL_ONLY 77 // LIMIT_ROLL_ONLY
77 private VehicleFlag m_Hoverflags = (VehicleFlag)0;
78 private Vector3 m_BlockingEndPoint = Vector3.Zero; 78 private Vector3 m_BlockingEndPoint = Vector3.Zero;
79 private Quaternion m_RollreferenceFrame = Quaternion.Identity; 79 private Quaternion m_RollreferenceFrame = Quaternion.Identity;
80 // Linear properties 80 // Linear properties
@@ -124,15 +124,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin
124 private float m_verticalAttractionEfficiency = 1.0f; // damped 124 private float m_verticalAttractionEfficiency = 1.0f; // damped
125 private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. 125 private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor.
126 126
127 public BSDynamics(BSPrim myPrim) 127 public BSDynamics(BSScene myScene, BSPrim myPrim)
128 { 128 {
129 m_physicsScene = myScene;
129 m_prim = myPrim; 130 m_prim = myPrim;
130 m_type = Vehicle.TYPE_NONE; 131 m_type = Vehicle.TYPE_NONE;
131 } 132 }
132 133
133 internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue, float timestep) 134 internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue, float timestep)
134 { 135 {
135 DetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); 136 VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
136 switch (pParam) 137 switch (pParam)
137 { 138 {
138 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: 139 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
@@ -231,7 +232,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
231 232
232 internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue, float timestep) 233 internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue, float timestep)
233 { 234 {
234 DetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); 235 VDetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
235 switch (pParam) 236 switch (pParam)
236 { 237 {
237 case Vehicle.ANGULAR_FRICTION_TIMESCALE: 238 case Vehicle.ANGULAR_FRICTION_TIMESCALE:
@@ -266,7 +267,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
266 267
267 internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) 268 internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
268 { 269 {
269 DetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); 270 VDetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
270 switch (pParam) 271 switch (pParam)
271 { 272 {
272 case Vehicle.REFERENCE_FRAME: 273 case Vehicle.REFERENCE_FRAME:
@@ -280,164 +281,27 @@ namespace OpenSim.Region.Physics.BulletSPlugin
280 281
281 internal void ProcessVehicleFlags(int pParam, bool remove) 282 internal void ProcessVehicleFlags(int pParam, bool remove)
282 { 283 {
283 DetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", m_prim.LocalID, pParam, remove); 284 VDetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", m_prim.LocalID, pParam, remove);
285 VehicleFlag parm = (VehicleFlag)pParam;
284 if (remove) 286 if (remove)
285 { 287 {
286 if (pParam == -1) 288 if (pParam == -1)
287 { 289 {
288 m_flags = (VehicleFlag)0; 290 m_flags = (VehicleFlag)0;
289 m_Hoverflags = (VehicleFlag)0;
290 return;
291 } 291 }
292 if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) 292 else
293 {
294 if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != (VehicleFlag)0)
295 m_Hoverflags &= ~(VehicleFlag.HOVER_GLOBAL_HEIGHT);
296 }
297 if ((pParam & (int)VehicleFlag.HOVER_TERRAIN_ONLY) == (int)VehicleFlag.HOVER_TERRAIN_ONLY)
298 {
299 if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != (VehicleFlag)0)
300 m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY);
301 }
302 if ((pParam & (int)VehicleFlag.HOVER_UP_ONLY) == (int)VehicleFlag.HOVER_UP_ONLY)
303 {
304 if ((m_Hoverflags & VehicleFlag.HOVER_UP_ONLY) != (VehicleFlag)0)
305 m_Hoverflags &= ~(VehicleFlag.HOVER_UP_ONLY);
306 }
307 if ((pParam & (int)VehicleFlag.HOVER_WATER_ONLY) == (int)VehicleFlag.HOVER_WATER_ONLY)
308 {
309 if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != (VehicleFlag)0)
310 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY);
311 }
312 if ((pParam & (int)VehicleFlag.LIMIT_MOTOR_UP) == (int)VehicleFlag.LIMIT_MOTOR_UP)
313 {
314 if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != (VehicleFlag)0)
315 m_flags &= ~(VehicleFlag.LIMIT_MOTOR_UP);
316 }
317 if ((pParam & (int)VehicleFlag.LIMIT_ROLL_ONLY) == (int)VehicleFlag.LIMIT_ROLL_ONLY)
318 {
319 if ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) != (VehicleFlag)0)
320 m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY);
321 }
322 if ((pParam & (int)VehicleFlag.MOUSELOOK_BANK) == (int)VehicleFlag.MOUSELOOK_BANK)
323 {
324 if ((m_flags & VehicleFlag.MOUSELOOK_BANK) != (VehicleFlag)0)
325 m_flags &= ~(VehicleFlag.MOUSELOOK_BANK);
326 }
327 if ((pParam & (int)VehicleFlag.MOUSELOOK_STEER) == (int)VehicleFlag.MOUSELOOK_STEER)
328 {
329 if ((m_flags & VehicleFlag.MOUSELOOK_STEER) != (VehicleFlag)0)
330 m_flags &= ~(VehicleFlag.MOUSELOOK_STEER);
331 }
332 if ((pParam & (int)VehicleFlag.NO_DEFLECTION_UP) == (int)VehicleFlag.NO_DEFLECTION_UP)
333 {
334 if ((m_flags & VehicleFlag.NO_DEFLECTION_UP) != (VehicleFlag)0)
335 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP);
336 }
337 if ((pParam & (int)VehicleFlag.CAMERA_DECOUPLED) == (int)VehicleFlag.CAMERA_DECOUPLED)
338 {
339 if ((m_flags & VehicleFlag.CAMERA_DECOUPLED) != (VehicleFlag)0)
340 m_flags &= ~(VehicleFlag.CAMERA_DECOUPLED);
341 }
342 if ((pParam & (int)VehicleFlag.NO_X) == (int)VehicleFlag.NO_X)
343 {
344 if ((m_flags & VehicleFlag.NO_X) != (VehicleFlag)0)
345 m_flags &= ~(VehicleFlag.NO_X);
346 }
347 if ((pParam & (int)VehicleFlag.NO_Y) == (int)VehicleFlag.NO_Y)
348 {
349 if ((m_flags & VehicleFlag.NO_Y) != (VehicleFlag)0)
350 m_flags &= ~(VehicleFlag.NO_Y);
351 }
352 if ((pParam & (int)VehicleFlag.NO_Z) == (int)VehicleFlag.NO_Z)
353 {
354 if ((m_flags & VehicleFlag.NO_Z) != (VehicleFlag)0)
355 m_flags &= ~(VehicleFlag.NO_Z);
356 }
357 if ((pParam & (int)VehicleFlag.LOCK_HOVER_HEIGHT) == (int)VehicleFlag.LOCK_HOVER_HEIGHT)
358 {
359 if ((m_Hoverflags & VehicleFlag.LOCK_HOVER_HEIGHT) != (VehicleFlag)0)
360 m_Hoverflags &= ~(VehicleFlag.LOCK_HOVER_HEIGHT);
361 }
362 if ((pParam & (int)VehicleFlag.NO_DEFLECTION) == (int)VehicleFlag.NO_DEFLECTION)
363 {
364 if ((m_flags & VehicleFlag.NO_DEFLECTION) != (VehicleFlag)0)
365 m_flags &= ~(VehicleFlag.NO_DEFLECTION);
366 }
367 if ((pParam & (int)VehicleFlag.LOCK_ROTATION) == (int)VehicleFlag.LOCK_ROTATION)
368 { 293 {
369 if ((m_flags & VehicleFlag.LOCK_ROTATION) != (VehicleFlag)0) 294 m_flags &= ~parm;
370 m_flags &= ~(VehicleFlag.LOCK_ROTATION);
371 } 295 }
372 } 296 }
373 else 297 else {
374 { 298 m_flags |= parm;
375 if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT)
376 {
377 m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT | m_flags);
378 }
379 if ((pParam & (int)VehicleFlag.HOVER_TERRAIN_ONLY) == (int)VehicleFlag.HOVER_TERRAIN_ONLY)
380 {
381 m_Hoverflags |= (VehicleFlag.HOVER_TERRAIN_ONLY | m_flags);
382 }
383 if ((pParam & (int)VehicleFlag.HOVER_UP_ONLY) == (int)VehicleFlag.HOVER_UP_ONLY)
384 {
385 m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY | m_flags);
386 }
387 if ((pParam & (int)VehicleFlag.HOVER_WATER_ONLY) == (int)VehicleFlag.HOVER_WATER_ONLY)
388 {
389 m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY | m_flags);
390 }
391 if ((pParam & (int)VehicleFlag.LIMIT_MOTOR_UP) == (int)VehicleFlag.LIMIT_MOTOR_UP)
392 {
393 m_flags |= (VehicleFlag.LIMIT_MOTOR_UP | m_flags);
394 }
395 if ((pParam & (int)VehicleFlag.MOUSELOOK_BANK) == (int)VehicleFlag.MOUSELOOK_BANK)
396 {
397 m_flags |= (VehicleFlag.MOUSELOOK_BANK | m_flags);
398 }
399 if ((pParam & (int)VehicleFlag.MOUSELOOK_STEER) == (int)VehicleFlag.MOUSELOOK_STEER)
400 {
401 m_flags |= (VehicleFlag.MOUSELOOK_STEER | m_flags);
402 }
403 if ((pParam & (int)VehicleFlag.NO_DEFLECTION_UP) == (int)VehicleFlag.NO_DEFLECTION_UP)
404 {
405 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | m_flags);
406 }
407 if ((pParam & (int)VehicleFlag.CAMERA_DECOUPLED) == (int)VehicleFlag.CAMERA_DECOUPLED)
408 {
409 m_flags |= (VehicleFlag.CAMERA_DECOUPLED | m_flags);
410 }
411 if ((pParam & (int)VehicleFlag.NO_X) == (int)VehicleFlag.NO_X)
412 {
413 m_flags |= (VehicleFlag.NO_X);
414 }
415 if ((pParam & (int)VehicleFlag.NO_Y) == (int)VehicleFlag.NO_Y)
416 {
417 m_flags |= (VehicleFlag.NO_Y);
418 }
419 if ((pParam & (int)VehicleFlag.NO_Z) == (int)VehicleFlag.NO_Z)
420 {
421 m_flags |= (VehicleFlag.NO_Z);
422 }
423 if ((pParam & (int)VehicleFlag.LOCK_HOVER_HEIGHT) == (int)VehicleFlag.LOCK_HOVER_HEIGHT)
424 {
425 m_Hoverflags |= (VehicleFlag.LOCK_HOVER_HEIGHT);
426 }
427 if ((pParam & (int)VehicleFlag.NO_DEFLECTION) == (int)VehicleFlag.NO_DEFLECTION)
428 {
429 m_flags |= (VehicleFlag.NO_DEFLECTION);
430 }
431 if ((pParam & (int)VehicleFlag.LOCK_ROTATION) == (int)VehicleFlag.LOCK_ROTATION)
432 {
433 m_flags |= (VehicleFlag.LOCK_ROTATION);
434 }
435 } 299 }
436 }//end ProcessVehicleFlags 300 }//end ProcessVehicleFlags
437 301
438 internal void ProcessTypeChange(Vehicle pType) 302 internal void ProcessTypeChange(Vehicle pType, float stepSize)
439 { 303 {
440 DetailLog("{0},ProcessTypeChange,type={1}", m_prim.LocalID, pType); 304 VDetailLog("{0},ProcessTypeChange,type={1}", m_prim.LocalID, pType);
441 // Set Defaults For Type 305 // Set Defaults For Type
442 m_type = pType; 306 m_type = pType;
443 switch (pType) 307 switch (pType)
@@ -478,10 +342,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
478 // m_bankingMix = 1; 342 // m_bankingMix = 1;
479 // m_bankingTimescale = 10; 343 // m_bankingTimescale = 10;
480 // m_referenceFrame = Quaternion.Identity; 344 // m_referenceFrame = Quaternion.Identity;
481 m_Hoverflags &= 345 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
346 m_flags &=
482 ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | 347 ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
483 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); 348 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
484 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
485 break; 349 break;
486 case Vehicle.TYPE_CAR: 350 case Vehicle.TYPE_CAR:
487 m_linearFrictionTimescale = new Vector3(100, 2, 1000); 351 m_linearFrictionTimescale = new Vector3(100, 2, 1000);
@@ -506,10 +370,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
506 // m_bankingMix = 1; 370 // m_bankingMix = 1;
507 // m_bankingTimescale = 1; 371 // m_bankingTimescale = 1;
508 // m_referenceFrame = Quaternion.Identity; 372 // m_referenceFrame = Quaternion.Identity;
509 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
510 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | 373 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY |
511 VehicleFlag.LIMIT_MOTOR_UP); 374 VehicleFlag.LIMIT_MOTOR_UP);
512 m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY); 375 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
376 m_flags |= (VehicleFlag.HOVER_UP_ONLY);
513 break; 377 break;
514 case Vehicle.TYPE_BOAT: 378 case Vehicle.TYPE_BOAT:
515 m_linearFrictionTimescale = new Vector3(10, 3, 2); 379 m_linearFrictionTimescale = new Vector3(10, 3, 2);
@@ -534,12 +398,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
534 // m_bankingMix = 0.8f; 398 // m_bankingMix = 0.8f;
535 // m_bankingTimescale = 1; 399 // m_bankingTimescale = 1;
536 // m_referenceFrame = Quaternion.Identity; 400 // m_referenceFrame = Quaternion.Identity;
537 m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | 401 m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY |
538 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); 402 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
539 m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY); 403 m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY);
540 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | 404 m_flags |= (VehicleFlag.NO_DEFLECTION_UP |
541 VehicleFlag.LIMIT_MOTOR_UP); 405 VehicleFlag.LIMIT_MOTOR_UP);
542 m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY); 406 m_flags |= (VehicleFlag.HOVER_WATER_ONLY);
543 break; 407 break;
544 case Vehicle.TYPE_AIRPLANE: 408 case Vehicle.TYPE_AIRPLANE:
545 m_linearFrictionTimescale = new Vector3(200, 10, 5); 409 m_linearFrictionTimescale = new Vector3(200, 10, 5);
@@ -564,7 +428,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
564 // m_bankingMix = 0.7f; 428 // m_bankingMix = 0.7f;
565 // m_bankingTimescale = 2; 429 // m_bankingTimescale = 2;
566 // m_referenceFrame = Quaternion.Identity; 430 // m_referenceFrame = Quaternion.Identity;
567 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | 431 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
568 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); 432 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
569 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP); 433 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP);
570 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); 434 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
@@ -592,11 +456,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
592 // m_bankingMix = 0.7f; 456 // m_bankingMix = 0.7f;
593 // m_bankingTimescale = 5; 457 // m_bankingTimescale = 5;
594 // m_referenceFrame = Quaternion.Identity; 458 // m_referenceFrame = Quaternion.Identity;
595 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | 459 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
596 VehicleFlag.HOVER_UP_ONLY); 460 VehicleFlag.HOVER_UP_ONLY);
597 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP); 461 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP);
598 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); 462 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
599 m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT); 463 m_flags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT);
600 break; 464 break;
601 } 465 }
602 }//end SetDefaultsForType 466 }//end SetDefaultsForType
@@ -613,7 +477,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
613 MoveAngular(pTimestep); 477 MoveAngular(pTimestep);
614 LimitRotation(pTimestep); 478 LimitRotation(pTimestep);
615 479
616 DetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", 480 VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}",
617 m_prim.LocalID, m_prim.Position, m_prim.Force, m_prim.Velocity, m_prim.RotationalVelocity); 481 m_prim.LocalID, m_prim.Position, m_prim.Force, m_prim.Velocity, m_prim.RotationalVelocity);
618 }// end Step 482 }// end Step
619 483
@@ -657,7 +521,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
657 521
658 */ 522 */
659 523
660 DetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},decay={4},dir={5},vel={6}", 524 VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},decay={4},dir={5},vel={6}",
661 m_prim.LocalID, origDir, origVel, addAmount, decayfraction, m_linearMotorDirection, m_lastLinearVelocityVector); 525 m_prim.LocalID, origDir, origVel, addAmount, decayfraction, m_linearMotorDirection, m_lastLinearVelocityVector);
662 } 526 }
663 else 527 else
@@ -669,7 +533,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
669 m_lastLinearVelocityVector = Vector3.Zero; 533 m_lastLinearVelocityVector = Vector3.Zero;
670 } 534 }
671 535
672 // convert requested object velocity to world-referenced vector 536 // convert requested object velocity to object relative vector
673 Quaternion rotq = m_prim.Orientation; 537 Quaternion rotq = m_prim.Orientation;
674 m_dir = m_lastLinearVelocityVector * rotq; 538 m_dir = m_lastLinearVelocityVector * rotq;
675 539
@@ -722,7 +586,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
722 if (changed) 586 if (changed)
723 { 587 {
724 m_prim.Position = pos; 588 m_prim.Position = pos;
725 DetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}", 589 VDetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}",
726 m_prim.LocalID, m_BlockingEndPoint, posChange, pos); 590 m_prim.LocalID, m_BlockingEndPoint, posChange, pos);
727 } 591 }
728 } 592 }
@@ -732,32 +596,32 @@ namespace OpenSim.Region.Physics.BulletSPlugin
732 { 596 {
733 pos.Z = m_prim.Scene.GetTerrainHeightAtXYZ(pos) + 2; 597 pos.Z = m_prim.Scene.GetTerrainHeightAtXYZ(pos) + 2;
734 m_prim.Position = pos; 598 m_prim.Position = pos;
735 DetailLog("{0},MoveLinear,terrainHeight,pos={1}", m_prim.LocalID, pos); 599 VDetailLog("{0},MoveLinear,terrainHeight,pos={1}", m_prim.LocalID, pos);
736 } 600 }
737 601
738 // Check if hovering 602 // Check if hovering
739 if ((m_Hoverflags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) 603 if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
740 { 604 {
741 // We should hover, get the target height 605 // We should hover, get the target height
742 if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != 0) 606 if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0)
743 { 607 {
744 m_VhoverTargetHeight = m_prim.Scene.GetWaterLevel() + m_VhoverHeight; 608 m_VhoverTargetHeight = m_prim.Scene.GetWaterLevel() + m_VhoverHeight;
745 } 609 }
746 if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) 610 if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
747 { 611 {
748 m_VhoverTargetHeight = m_prim.Scene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight; 612 m_VhoverTargetHeight = m_prim.Scene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight;
749 } 613 }
750 if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0) 614 if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0)
751 { 615 {
752 m_VhoverTargetHeight = m_VhoverHeight; 616 m_VhoverTargetHeight = m_VhoverHeight;
753 } 617 }
754 618
755 if ((m_Hoverflags & VehicleFlag.HOVER_UP_ONLY) != 0) 619 if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0)
756 { 620 {
757 // If body is aready heigher, use its height as target height 621 // If body is aready heigher, use its height as target height
758 if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z; 622 if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z;
759 } 623 }
760 if ((m_Hoverflags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) 624 if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
761 { 625 {
762 if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2) 626 if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2)
763 { 627 {
@@ -779,7 +643,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
779 } 643 }
780 } 644 }
781 645
782 DetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_dir, m_VhoverHeight, m_VhoverTargetHeight); 646 VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_dir, m_VhoverHeight, m_VhoverTargetHeight);
783 647
784// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped 648// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped
785// m_VhoverTimescale = 0f; // time to acheive height 649// m_VhoverTimescale = 0f; // time to acheive height
@@ -815,7 +679,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
815 { 679 {
816 grav.Z = (float)(grav.Z * 1.037125); 680 grav.Z = (float)(grav.Z * 1.037125);
817 } 681 }
818 DetailLog("{0},MoveLinear,limitMotorUp,grav={1}", m_prim.LocalID, grav); 682 VDetailLog("{0},MoveLinear,limitMotorUp,grav={1}", m_prim.LocalID, grav);
819 //End Experimental Values 683 //End Experimental Values
820 } 684 }
821 if ((m_flags & (VehicleFlag.NO_X)) != 0) 685 if ((m_flags & (VehicleFlag.NO_X)) != 0)
@@ -844,7 +708,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
844 Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep); 708 Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep);
845 m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount; 709 m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount;
846 710
847 DetailLog("{0},MoveLinear,done,pos={1},vel={2},force={3},decay={4}", 711 VDetailLog("{0},MoveLinear,done,pos={1},vel={2},force={3},decay={4}",
848 m_prim.LocalID, m_lastPositionVector, m_dir, grav, decayamount); 712 m_prim.LocalID, m_lastPositionVector, m_dir, grav, decayamount);
849 713
850 } // end MoveLinear() 714 } // end MoveLinear()
@@ -870,13 +734,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
870 // There are m_angularMotorApply steps. 734 // There are m_angularMotorApply steps.
871 Vector3 origAngularVelocity = m_angularMotorVelocity; 735 Vector3 origAngularVelocity = m_angularMotorVelocity;
872 // ramp up to new value 736 // ramp up to new value
873 // current velocity += error / (time to get there / step interval) 737 // current velocity += error / (time to get there / step interval)
874 // requested speed - last motor speed 738 // requested speed - last motor speed
875 m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) / (m_angularMotorTimescale / pTimestep); 739 m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) / (m_angularMotorTimescale / pTimestep);
876 m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep); 740 m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep);
877 m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep); 741 m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep);
878 742
879 DetailLog("{0},MoveAngular,angularMotorApply,apply={1},origvel={2},dir={3},vel={4}", 743 VDetailLog("{0},MoveAngular,angularMotorApply,apply={1},origvel={2},dir={3},vel={4}",
880 m_prim.LocalID,m_angularMotorApply,origAngularVelocity, m_angularMotorDirection, m_angularMotorVelocity); 744 m_prim.LocalID,m_angularMotorApply,origAngularVelocity, m_angularMotorDirection, m_angularMotorVelocity);
881 745
882 m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected 746 m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected
@@ -887,6 +751,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
887 // No motor recently applied, keep the body velocity 751 // No motor recently applied, keep the body velocity
888 // and decay the velocity 752 // and decay the velocity
889 m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep); 753 m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep);
754 if (m_angularMotorVelocity.LengthSquared() < 0.00001)
755 m_angularMotorVelocity = Vector3.Zero;
890 } // end motor section 756 } // end motor section
891 757
892 // Vertical attractor section 758 // Vertical attractor section
@@ -924,7 +790,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
924 vertattr.X += bounce * angularVelocity.X; 790 vertattr.X += bounce * angularVelocity.X;
925 vertattr.Y += bounce * angularVelocity.Y; 791 vertattr.Y += bounce * angularVelocity.Y;
926 792
927 DetailLog("{0},MoveAngular,verticalAttraction,verterr={1},bounce={2},vertattr={3}", 793 VDetailLog("{0},MoveAngular,verticalAttraction,verterr={1},bounce={2},vertattr={3}",
928 m_prim.LocalID, verterr, bounce, vertattr); 794 m_prim.LocalID, verterr, bounce, vertattr);
929 795
930 } // else vertical attractor is off 796 } // else vertical attractor is off
@@ -942,13 +808,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
942 { 808 {
943 m_lastAngularVelocity.X = 0; 809 m_lastAngularVelocity.X = 0;
944 m_lastAngularVelocity.Y = 0; 810 m_lastAngularVelocity.Y = 0;
945 DetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity); 811 VDetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity);
946 } 812 }
947 813
948 if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) 814 if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
949 { 815 {
950 m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. 816 m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero.
951 DetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity); 817 VDetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity);
952 } 818 }
953 819
954 // apply friction 820 // apply friction
@@ -958,7 +824,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
958 // Apply to the body 824 // Apply to the body
959 m_prim.RotationalVelocity = m_lastAngularVelocity; 825 m_prim.RotationalVelocity = m_lastAngularVelocity;
960 826
961 DetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", m_prim.LocalID, decayamount, m_lastAngularVelocity); 827 VDetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", m_prim.LocalID, decayamount, m_lastAngularVelocity);
962 } //end MoveAngular 828 } //end MoveAngular
963 829
964 internal void LimitRotation(float timestep) 830 internal void LimitRotation(float timestep)
@@ -1005,11 +871,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1005 if (changed) 871 if (changed)
1006 m_prim.Orientation = m_rot; 872 m_prim.Orientation = m_rot;
1007 873
1008 DetailLog("{0},LimitRotation,done,changed={1},orig={2},new={3}", m_prim.LocalID, changed, rotq, m_rot); 874 VDetailLog("{0},LimitRotation,done,changed={1},orig={2},new={3}", m_prim.LocalID, changed, rotq, m_rot);
1009 } 875 }
1010 876
1011 // Invoke the detailed logger and output something if it's enabled. 877 // Invoke the detailed logger and output something if it's enabled.
1012 private void DetailLog(string msg, params Object[] args) 878 private void VDetailLog(string msg, params Object[] args)
1013 { 879 {
1014 if (m_prim.Scene.VehicleLoggingEnabled) 880 if (m_prim.Scene.VehicleLoggingEnabled)
1015 m_prim.Scene.PhysicsLogging.Write(msg, args); 881 m_prim.Scene.PhysicsLogging.Write(msg, args);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index 087b9bb..9e3f0db 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -42,6 +42,9 @@ public class BSLinkset
42 private BSScene m_physicsScene; 42 private BSScene m_physicsScene;
43 public BSScene PhysicsScene { get { return m_physicsScene; } } 43 public BSScene PhysicsScene { get { return m_physicsScene; } }
44 44
45 static int m_nextLinksetID = 1;
46 public int LinksetID { get; private set; }
47
45 // The children under the root in this linkset 48 // The children under the root in this linkset
46 private List<BSPrim> m_children; 49 private List<BSPrim> m_children;
47 50
@@ -74,6 +77,10 @@ public class BSLinkset
74 public BSLinkset(BSScene scene, BSPrim parent) 77 public BSLinkset(BSScene scene, BSPrim parent)
75 { 78 {
76 // A simple linkset of one (no children) 79 // A simple linkset of one (no children)
80 LinksetID = m_nextLinksetID++;
81 // We create LOTS of linksets.
82 if (m_nextLinksetID < 0)
83 m_nextLinksetID = 1;
77 m_physicsScene = scene; 84 m_physicsScene = scene;
78 m_linksetRoot = parent; 85 m_linksetRoot = parent;
79 m_children = new List<BSPrim>(); 86 m_children = new List<BSPrim>();
@@ -258,8 +265,7 @@ public class BSLinkset
258 BSPrim childx = child; 265 BSPrim childx = child;
259 m_physicsScene.TaintedObject("AddChildToLinkset", delegate() 266 m_physicsScene.TaintedObject("AddChildToLinkset", delegate()
260 { 267 {
261 // DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, m_linksetRoot.LocalID); 268 DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
262 // DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
263 PhysicallyLinkAChildToRoot(rootx, childx); // build the physical binding between me and the child 269 PhysicallyLinkAChildToRoot(rootx, childx); // build the physical binding between me and the child
264 }); 270 });
265 } 271 }
@@ -287,8 +293,7 @@ public class BSLinkset
287 BSPrim childx = child; 293 BSPrim childx = child;
288 m_physicsScene.TaintedObject("RemoveChildFromLinkset", delegate() 294 m_physicsScene.TaintedObject("RemoveChildFromLinkset", delegate()
289 { 295 {
290 // DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID); 296 DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
291 // DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
292 297
293 PhysicallyUnlinkAChildFromRoot(rootx, childx); 298 PhysicallyUnlinkAChildFromRoot(rootx, childx);
294 }); 299 });
@@ -319,7 +324,6 @@ public class BSLinkset
319 324
320 // create a constraint that allows no freedom of movement between the two objects 325 // create a constraint that allows no freedom of movement between the two objects
321 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 326 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
322 // DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID);
323 DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2},rLoc={3},cLoc={4},midLoc={5}", 327 DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2},rLoc={3},cLoc={4},midLoc={5}",
324 rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID, rootPrim.Position, childPrim.Position, midPoint); 328 rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID, rootPrim.Position, childPrim.Position, midPoint);
325 BS6DofConstraint constrain = new BS6DofConstraint( 329 BS6DofConstraint constrain = new BS6DofConstraint(
@@ -328,10 +332,10 @@ public class BSLinkset
328 true, 332 true,
329 true 333 true
330 ); 334 );
331 /* NOTE: attempt to build constraint with full frame computation, etc. 335 /* NOTE: below is an attempt to build constraint with full frame computation, etc.
332 * Using the midpoint is easier since it lets the Bullet code use the transforms 336 * Using the midpoint is easier since it lets the Bullet code use the transforms
333 * of the objects. 337 * of the objects.
334 * Code left here as an example. 338 * Code left as a warning to future programmers.
335 // ================================================================================== 339 // ==================================================================================
336 // relative position normalized to the root prim 340 // relative position normalized to the root prim
337 OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation); 341 OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation);
@@ -343,7 +347,6 @@ public class BSLinkset
343 347
344 // create a constraint that allows no freedom of movement between the two objects 348 // create a constraint that allows no freedom of movement between the two objects
345 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 349 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
346 // DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID);
347 DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); 350 DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
348 BS6DofConstraint constrain = new BS6DofConstraint( 351 BS6DofConstraint constrain = new BS6DofConstraint(
349 PhysicsScene.World, rootPrim.Body, childPrim.Body, 352 PhysicsScene.World, rootPrim.Body, childPrim.Body,
@@ -382,8 +385,6 @@ public class BSLinkset
382 // Called at taint time! 385 // Called at taint time!
383 private void PhysicallyUnlinkAChildFromRoot(BSPrim rootPrim, BSPrim childPrim) 386 private void PhysicallyUnlinkAChildFromRoot(BSPrim rootPrim, BSPrim childPrim)
384 { 387 {
385 // DebugLog("{0}: PhysicallyUnlinkAChildFromRoot: RemoveConstraint between root prim {1} and child prim {2}",
386 // LogHeader, rootPrim.LocalID, childPrim.LocalID);
387 DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); 388 DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
388 389
389 // Find the constraint for this link and get rid of it from the overall collection and from my list 390 // Find the constraint for this link and get rid of it from the overall collection and from my list
@@ -397,20 +398,12 @@ public class BSLinkset
397 // Called at taint time! 398 // Called at taint time!
398 private void PhysicallyUnlinkAllChildrenFromRoot(BSPrim rootPrim) 399 private void PhysicallyUnlinkAllChildrenFromRoot(BSPrim rootPrim)
399 { 400 {
400 // DebugLog("{0}: PhysicallyUnlinkAllChildren:", LogHeader);
401 DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); 401 DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID);
402 402
403 m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body); 403 m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body);
404 } 404 }
405 405
406 // Invoke the detailed logger and output something if it's enabled. 406 // Invoke the detailed logger and output something if it's enabled.
407 private void DebugLog(string msg, params Object[] args)
408 {
409 if (m_physicsScene.ShouldDebugLog)
410 m_physicsScene.Logger.DebugFormat(msg, args);
411 }
412
413 // Invoke the detailed logger and output something if it's enabled.
414 private void DetailLog(string msg, params Object[] args) 407 private void DetailLog(string msg, params Object[] args)
415 { 408 {
416 m_physicsScene.PhysicsLogging.Write(msg, args); 409 m_physicsScene.PhysicsLogging.Write(msg, args);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 9c20004..d3f1e9c 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -42,8 +42,6 @@ public sealed class BSPrim : PhysicsActor
42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43 private static readonly string LogHeader = "[BULLETS PRIM]"; 43 private static readonly string LogHeader = "[BULLETS PRIM]";
44 44
45 private void DebugLog(string mm, params Object[] xx) { if (_scene.ShouldDebugLog) m_log.DebugFormat(mm, xx); }
46
47 private IMesh _mesh; 45 private IMesh _mesh;
48 private PrimitiveBaseShape _pbs; 46 private PrimitiveBaseShape _pbs;
49 private ShapeData.PhysicsShapeType _shapeType; 47 private ShapeData.PhysicsShapeType _shapeType;
@@ -141,8 +139,8 @@ public sealed class BSPrim : PhysicsActor
141 _friction = _scene.Params.defaultFriction; // TODO: compute based on object material 139 _friction = _scene.Params.defaultFriction; // TODO: compute based on object material
142 _density = _scene.Params.defaultDensity; // TODO: compute based on object material 140 _density = _scene.Params.defaultDensity; // TODO: compute based on object material
143 _restitution = _scene.Params.defaultRestitution; 141 _restitution = _scene.Params.defaultRestitution;
144 _linkset = new BSLinkset(_scene, this); // a linkset of one 142 _linkset = new BSLinkset(Scene, this); // a linkset of one
145 _vehicle = new BSDynamics(this); // add vehicleness 143 _vehicle = new BSDynamics(Scene, this); // add vehicleness
146 _mass = CalculateMass(); 144 _mass = CalculateMass();
147 // do the actual object creation at taint time 145 // do the actual object creation at taint time
148 DetailLog("{0},BSPrim.constructor,call", LocalID); 146 DetailLog("{0},BSPrim.constructor,call", LocalID);
@@ -193,7 +191,7 @@ public sealed class BSPrim : PhysicsActor
193 { 191 {
194 _mass = CalculateMass(); // changing size changes the mass 192 _mass = CalculateMass(); // changing size changes the mass
195 BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical); 193 BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical);
196 // DetailLog("{0}: BSPrim.setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical); 194 DetailLog("{0}: BSPrim.setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical);
197 RecreateGeomAndObject(); 195 RecreateGeomAndObject();
198 }); 196 });
199 } 197 }
@@ -232,7 +230,6 @@ public sealed class BSPrim : PhysicsActor
232 BSPrim parent = obj as BSPrim; 230 BSPrim parent = obj as BSPrim;
233 if (parent != null) 231 if (parent != null)
234 { 232 {
235 DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, parent.LocalID);
236 BSPrim parentBefore = _linkset.LinksetRoot; 233 BSPrim parentBefore = _linkset.LinksetRoot;
237 int childrenBefore = _linkset.NumberOfChildren; 234 int childrenBefore = _linkset.NumberOfChildren;
238 235
@@ -248,8 +245,6 @@ public sealed class BSPrim : PhysicsActor
248 public override void delink() { 245 public override void delink() {
249 // TODO: decide if this parent checking needs to happen at taint time 246 // TODO: decide if this parent checking needs to happen at taint time
250 // Race condition here: if link() and delink() in same simulation tick, the delink will not happen 247 // Race condition here: if link() and delink() in same simulation tick, the delink will not happen
251 DebugLog("{0}: delink {1}/{2}. Parent={3}", LogHeader, _avName, _localID,
252 _linkset.LinksetRoot._avName+"/"+_linkset.LinksetRoot.LocalID.ToString());
253 248
254 BSPrim parentBefore = _linkset.LinksetRoot; 249 BSPrim parentBefore = _linkset.LinksetRoot;
255 int childrenBefore = _linkset.NumberOfChildren; 250 int childrenBefore = _linkset.NumberOfChildren;
@@ -280,7 +275,7 @@ public sealed class BSPrim : PhysicsActor
280 275
281 public override void LockAngularMotion(OMV.Vector3 axis) 276 public override void LockAngularMotion(OMV.Vector3 axis)
282 { 277 {
283 // DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis); 278 DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis);
284 return; 279 return;
285 } 280 }
286 281
@@ -299,7 +294,7 @@ public sealed class BSPrim : PhysicsActor
299 // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint? 294 // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint?
300 _scene.TaintedObject("BSPrim.setPosition", delegate() 295 _scene.TaintedObject("BSPrim.setPosition", delegate()
301 { 296 {
302 // DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); 297 DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
303 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); 298 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
304 }); 299 });
305 } 300 }
@@ -336,7 +331,7 @@ public sealed class BSPrim : PhysicsActor
336 _force = value; 331 _force = value;
337 _scene.TaintedObject("BSPrim.setForce", delegate() 332 _scene.TaintedObject("BSPrim.setForce", delegate()
338 { 333 {
339 // DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force); 334 DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force);
340 // BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); 335 // BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
341 BulletSimAPI.SetObjectForce2(Body.Ptr, _force); 336 BulletSimAPI.SetObjectForce2(Body.Ptr, _force);
342 }); 337 });
@@ -354,7 +349,7 @@ public sealed class BSPrim : PhysicsActor
354 { 349 {
355 // Done at taint time so we're sure the physics engine is not using the variables 350 // Done at taint time so we're sure the physics engine is not using the variables
356 // Vehicle code changes the parameters for this vehicle type. 351 // Vehicle code changes the parameters for this vehicle type.
357 _vehicle.ProcessTypeChange(type); 352 _vehicle.ProcessTypeChange(type, Scene.LastSimulatedTimestep);
358 // Tell the scene about the vehicle so it will get processing each frame. 353 // Tell the scene about the vehicle so it will get processing each frame.
359 _scene.VehicleInSceneTypeChanged(this, type); 354 _scene.VehicleInSceneTypeChanged(this, type);
360 }); 355 });
@@ -414,7 +409,7 @@ public sealed class BSPrim : PhysicsActor
414 _velocity = value; 409 _velocity = value;
415 _scene.TaintedObject("BSPrim.setVelocity", delegate() 410 _scene.TaintedObject("BSPrim.setVelocity", delegate()
416 { 411 {
417 // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); 412 DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity);
418 BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity); 413 BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity);
419 }); 414 });
420 } 415 }
@@ -422,7 +417,7 @@ public sealed class BSPrim : PhysicsActor
422 public override OMV.Vector3 Torque { 417 public override OMV.Vector3 Torque {
423 get { return _torque; } 418 get { return _torque; }
424 set { _torque = value; 419 set { _torque = value;
425 // DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque); 420 DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque);
426 } 421 }
427 } 422 }
428 public override float CollisionScore { 423 public override float CollisionScore {
@@ -449,7 +444,7 @@ public sealed class BSPrim : PhysicsActor
449 _scene.TaintedObject("BSPrim.setOrientation", delegate() 444 _scene.TaintedObject("BSPrim.setOrientation", delegate()
450 { 445 {
451 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); 446 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
452 // DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); 447 DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation);
453 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); 448 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
454 }); 449 });
455 } 450 }
@@ -486,11 +481,8 @@ public sealed class BSPrim : PhysicsActor
486 // No locking here because only called when it is safe 481 // No locking here because only called when it is safe
487 private void SetObjectDynamic() 482 private void SetObjectDynamic()
488 { 483 {
489 // RA: remove this for the moment. 484 // If it's becoming dynamic, it will need hullness
490 // The problem is that dynamic objects are hulls so if we are becoming physical 485 VerifyCorrectPhysicalShape();
491 // the shape has to be checked and possibly built.
492 // Maybe a VerifyCorrectPhysicalShape() routine?
493 // RecreateGeomAndObject();
494 486
495 // Bullet wants static objects to have a mass of zero 487 // Bullet wants static objects to have a mass of zero
496 float mass = IsStatic ? 0f : _mass; 488 float mass = IsStatic ? 0f : _mass;
@@ -501,13 +493,15 @@ public sealed class BSPrim : PhysicsActor
501 _linkset.Refresh(this); 493 _linkset.Refresh(this);
502 494
503 CollisionFlags cf = BulletSimAPI.GetCollisionFlags2(Body.Ptr); 495 CollisionFlags cf = BulletSimAPI.GetCollisionFlags2(Body.Ptr);
504 // DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, cf); 496 DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, cf);
505 } 497 }
506 498
507 // prims don't fly 499 // prims don't fly
508 public override bool Flying { 500 public override bool Flying {
509 get { return _flying; } 501 get { return _flying; }
510 set { _flying = value; } 502 set {
503 _flying = value;
504 }
511 } 505 }
512 public override bool SetAlwaysRun { 506 public override bool SetAlwaysRun {
513 get { return _setAlwaysRun; } 507 get { return _setAlwaysRun; }
@@ -558,7 +552,7 @@ public sealed class BSPrim : PhysicsActor
558 // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); 552 // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
559 _scene.TaintedObject("BSPrim.setRotationalVelocity", delegate() 553 _scene.TaintedObject("BSPrim.setRotationalVelocity", delegate()
560 { 554 {
561 // DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); 555 DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
562 BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity); 556 BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity);
563 }); 557 });
564 } 558 }
@@ -575,7 +569,7 @@ public sealed class BSPrim : PhysicsActor
575 _buoyancy = value; 569 _buoyancy = value;
576 _scene.TaintedObject("BSPrim.setBuoyancy", delegate() 570 _scene.TaintedObject("BSPrim.setBuoyancy", delegate()
577 { 571 {
578 // DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy); 572 DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
579 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy); 573 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy);
580 }); 574 });
581 } 575 }
@@ -638,17 +632,17 @@ public sealed class BSPrim : PhysicsActor
638 } 632 }
639 m_accumulatedForces.Clear(); 633 m_accumulatedForces.Clear();
640 } 634 }
641 // DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, _force); 635 DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, _force);
642 BulletSimAPI.AddObjectForce2(Body.Ptr, fSum); 636 BulletSimAPI.AddObjectForce2(Body.Ptr, fSum);
643 }); 637 });
644 } 638 }
645 639
646 public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { 640 public override void AddAngularForce(OMV.Vector3 force, bool pushforce) {
647 // DetailLog("{0},BSPrim.AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce); 641 DetailLog("{0},BSPrim.AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce);
648 // m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce); 642 // m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce);
649 } 643 }
650 public override void SetMomentum(OMV.Vector3 momentum) { 644 public override void SetMomentum(OMV.Vector3 momentum) {
651 // DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum); 645 DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum);
652 } 646 }
653 public override void SubscribeEvents(int ms) { 647 public override void SubscribeEvents(int ms) {
654 _subscribedEventsMs = ms; 648 _subscribedEventsMs = ms;
@@ -992,7 +986,7 @@ public sealed class BSPrim : PhysicsActor
992 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size); 986 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size);
993 if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE)) 987 if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE))
994 { 988 {
995 // DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild); 989 DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild);
996 _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE; 990 _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE;
997 // Bullet native objects are scaled by the Bullet engine so pass the size in 991 // Bullet native objects are scaled by the Bullet engine so pass the size in
998 _scale = _size; 992 _scale = _size;
@@ -1006,7 +1000,7 @@ public sealed class BSPrim : PhysicsActor
1006 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size); 1000 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size);
1007 if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX)) 1001 if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX))
1008 { 1002 {
1009 // DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild); 1003 DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild);
1010 _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX; 1004 _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX;
1011 _scale = _size; 1005 _scale = _size;
1012 // TODO: do we need to check for and destroy a mesh or hull that might have been left from before? 1006 // TODO: do we need to check for and destroy a mesh or hull that might have been left from before?
@@ -1042,19 +1036,26 @@ public sealed class BSPrim : PhysicsActor
1042 // No locking here because this is done when we know physics is not simulating 1036 // No locking here because this is done when we know physics is not simulating
1043 private void CreateGeomMesh() 1037 private void CreateGeomMesh()
1044 { 1038 {
1045 float lod = _pbs.SculptEntry ? _scene.SculptLOD : _scene.MeshLOD; 1039 // level of detail based on size and type of the object
1040 float lod = _scene.MeshLOD;
1041 if (_pbs.SculptEntry)
1042 lod = _scene.SculptLOD;
1043 float maxAxis = Math.Max(_size.X, Math.Max(_size.Y, _size.Z));
1044 if (maxAxis > _scene.MeshMegaPrimThreshold)
1045 lod = _scene.MeshMegaPrimLOD;
1046
1046 ulong newMeshKey = (ulong)_pbs.GetMeshKey(_size, lod); 1047 ulong newMeshKey = (ulong)_pbs.GetMeshKey(_size, lod);
1047 // m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey); 1048 // m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey);
1048 1049
1049 // if this new shape is the same as last time, don't recreate the mesh 1050 // if this new shape is the same as last time, don't recreate the mesh
1050 if (_meshKey == newMeshKey) return; 1051 if (_meshKey == newMeshKey) return;
1051 1052
1052 // DetailLog("{0},BSPrim.CreateGeomMesh,create,key={1}", LocalID, newMeshKey); 1053 DetailLog("{0},BSPrim.CreateGeomMesh,create,key={1}", LocalID, newMeshKey);
1053 // Since we're recreating new, get rid of any previously generated shape 1054 // Since we're recreating new, get rid of any previously generated shape
1054 if (_meshKey != 0) 1055 if (_meshKey != 0)
1055 { 1056 {
1056 // m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey); 1057 // m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey);
1057 // DetailLog("{0},BSPrim.CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey); 1058 DetailLog("{0},BSPrim.CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey);
1058 BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey); 1059 BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey);
1059 _mesh = null; 1060 _mesh = null;
1060 _meshKey = 0; 1061 _meshKey = 0;
@@ -1084,7 +1085,7 @@ public sealed class BSPrim : PhysicsActor
1084 _shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH; 1085 _shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH;
1085 // meshes are already scaled by the meshmerizer 1086 // meshes are already scaled by the meshmerizer
1086 _scale = new OMV.Vector3(1f, 1f, 1f); 1087 _scale = new OMV.Vector3(1f, 1f, 1f);
1087 // DetailLog("{0},BSPrim.CreateGeomMesh,done", LocalID); 1088 DetailLog("{0},BSPrim.CreateGeomMesh,done", LocalID);
1088 return; 1089 return;
1089 } 1090 }
1090 1091
@@ -1098,13 +1099,13 @@ public sealed class BSPrim : PhysicsActor
1098 // if the hull hasn't changed, don't rebuild it 1099 // if the hull hasn't changed, don't rebuild it
1099 if (newHullKey == _hullKey) return; 1100 if (newHullKey == _hullKey) return;
1100 1101
1101 // DetailLog("{0},BSPrim.CreateGeomHull,create,oldKey={1},newKey={2}", LocalID, _hullKey, newHullKey); 1102 DetailLog("{0},BSPrim.CreateGeomHull,create,oldKey={1},newKey={2}", LocalID, _hullKey, newHullKey);
1102 1103
1103 // Since we're recreating new, get rid of any previously generated shape 1104 // Since we're recreating new, get rid of any previously generated shape
1104 if (_hullKey != 0) 1105 if (_hullKey != 0)
1105 { 1106 {
1106 // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey); 1107 // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey);
1107 // DetailLog("{0},BSPrim.CreateGeomHull,deleteOldHull,key={1}", LocalID, _hullKey); 1108 DetailLog("{0},BSPrim.CreateGeomHull,deleteOldHull,key={1}", LocalID, _hullKey);
1108 BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey); 1109 BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey);
1109 _hullKey = 0; 1110 _hullKey = 0;
1110 } 1111 }
@@ -1198,7 +1199,7 @@ public sealed class BSPrim : PhysicsActor
1198 _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL; 1199 _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL;
1199 // meshes are already scaled by the meshmerizer 1200 // meshes are already scaled by the meshmerizer
1200 _scale = new OMV.Vector3(1f, 1f, 1f); 1201 _scale = new OMV.Vector3(1f, 1f, 1f);
1201 // DetailLog("{0},BSPrim.CreateGeomHull,done", LocalID); 1202 DetailLog("{0},BSPrim.CreateGeomHull,done", LocalID);
1202 return; 1203 return;
1203 } 1204 }
1204 1205
@@ -1210,6 +1211,27 @@ public sealed class BSPrim : PhysicsActor
1210 return; 1211 return;
1211 } 1212 }
1212 1213
1214 private void VerifyCorrectPhysicalShape()
1215 {
1216 if (IsStatic)
1217 {
1218 // if static, we don't need a hull so, if there is one, rebuild without it
1219 if (_hullKey != 0)
1220 {
1221 RecreateGeomAndObject();
1222 }
1223 }
1224 else
1225 {
1226 // if not static, it will need a hull to efficiently collide with things
1227 if (_hullKey == 0)
1228 {
1229 RecreateGeomAndObject();
1230 }
1231
1232 }
1233 }
1234
1213 // Create an object in Bullet if it has not already been created 1235 // Create an object in Bullet if it has not already been created
1214 // No locking here because this is done when the physics engine is not simulating 1236 // No locking here because this is done when the physics engine is not simulating
1215 // Returns 'true' if an object was actually created. 1237 // Returns 'true' if an object was actually created.
@@ -1334,10 +1356,8 @@ public sealed class BSPrim : PhysicsActor
1334 _acceleration = entprop.Acceleration; 1356 _acceleration = entprop.Acceleration;
1335 _rotationalVelocity = entprop.RotationalVelocity; 1357 _rotationalVelocity = entprop.RotationalVelocity;
1336 1358
1337 // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}, vel={5}, acc={6}, rvel={7}", 1359 DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
1338 // LogHeader, LocalID, changed, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); 1360 LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
1339 // DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
1340 // LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
1341 1361
1342 base.RequestPhysicsterseUpdate(); 1362 base.RequestPhysicsterseUpdate();
1343 } 1363 }
@@ -1353,6 +1373,7 @@ public sealed class BSPrim : PhysicsActor
1353 } 1373 }
1354 1374
1355 // I've collided with something 1375 // I've collided with something
1376 // Called at taint time from within the Step() function
1356 CollisionEventUpdate collisionCollection; 1377 CollisionEventUpdate collisionCollection;
1357 public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) 1378 public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
1358 { 1379 {
@@ -1366,6 +1387,15 @@ public sealed class BSPrim : PhysicsActor
1366 } 1387 }
1367 1388
1368 // DetailLog("{0},BSPrim.Collison,call,with={1}", LocalID, collidingWith); 1389 // DetailLog("{0},BSPrim.Collison,call,with={1}", LocalID, collidingWith);
1390 BSPrim collidingWithPrim;
1391 if (_scene.Prims.TryGetValue(collidingWith, out collidingWithPrim))
1392 {
1393 // prims in the same linkset cannot collide with each other
1394 if (this.Linkset.LinksetID == collidingWithPrim.Linkset.LinksetID)
1395 {
1396 return;
1397 }
1398 }
1369 1399
1370 // if someone is subscribed to collision events.... 1400 // if someone is subscribed to collision events....
1371 if (_subscribedEventsMs != 0) { 1401 if (_subscribedEventsMs != 0) {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index a31c578..56924aa 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -73,15 +73,22 @@ public class BSScene : PhysicsScene, IPhysicsParameters
73 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 73 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
74 private static readonly string LogHeader = "[BULLETS SCENE]"; 74 private static readonly string LogHeader = "[BULLETS SCENE]";
75 75
76 public void DebugLog(string mm, params Object[] xx) { if (ShouldDebugLog) m_log.DebugFormat(mm, xx); } 76 // The name of the region we're working for.
77 public string RegionName { get; private set; }
77 78
78 public string BulletSimVersion = "?"; 79 public string BulletSimVersion = "?";
79 80
80 private Dictionary<uint, BSCharacter> m_avatars = new Dictionary<uint, BSCharacter>(); 81 private Dictionary<uint, BSCharacter> m_avatars = new Dictionary<uint, BSCharacter>();
82 public Dictionary<uint, BSCharacter> Characters { get { return m_avatars; } }
83
81 private Dictionary<uint, BSPrim> m_prims = new Dictionary<uint, BSPrim>(); 84 private Dictionary<uint, BSPrim> m_prims = new Dictionary<uint, BSPrim>();
85 public Dictionary<uint, BSPrim> Prims { get { return m_prims; } }
86
82 private HashSet<BSCharacter> m_avatarsWithCollisions = new HashSet<BSCharacter>(); 87 private HashSet<BSCharacter> m_avatarsWithCollisions = new HashSet<BSCharacter>();
83 private HashSet<BSPrim> m_primsWithCollisions = new HashSet<BSPrim>(); 88 private HashSet<BSPrim> m_primsWithCollisions = new HashSet<BSPrim>();
89
84 private List<BSPrim> m_vehicles = new List<BSPrim>(); 90 private List<BSPrim> m_vehicles = new List<BSPrim>();
91
85 private float[] m_heightMap; 92 private float[] m_heightMap;
86 private float m_waterLevel; 93 private float m_waterLevel;
87 private uint m_worldID; 94 private uint m_worldID;
@@ -95,16 +102,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters
95 private int m_detailedStatsStep = 0; 102 private int m_detailedStatsStep = 0;
96 103
97 public IMesher mesher; 104 public IMesher mesher;
98 private float m_meshLOD; 105 // Level of Detail values kept as float because that's what the Meshmerizer wants
99 public float MeshLOD 106 public float MeshLOD { get; private set; }
100 { 107 public float MeshMegaPrimLOD { get; private set; }
101 get { return m_meshLOD; } 108 public float MeshMegaPrimThreshold { get; private set; }
102 } 109 public float SculptLOD { get; private set; }
103 private float m_sculptLOD;
104 public float SculptLOD
105 {
106 get { return m_sculptLOD; }
107 }
108 110
109 private BulletSim m_worldSim; 111 private BulletSim m_worldSim;
110 public BulletSim World 112 public BulletSim World
@@ -179,8 +181,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
179 ConfigurationParameters[] m_params; 181 ConfigurationParameters[] m_params;
180 GCHandle m_paramsHandle; 182 GCHandle m_paramsHandle;
181 183
182 public bool ShouldDebugLog { get; private set; } 184 // Handle to the callback used by the unmanaged code to call into the managed code.
183 185 // Used for debug logging.
186 // Need to store the handle in a persistant variable so it won't be freed.
184 private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle; 187 private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle;
185 188
186 // Sometimes you just have to log everything. 189 // Sometimes you just have to log everything.
@@ -196,6 +199,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
196 public BSScene(string identifier) 199 public BSScene(string identifier)
197 { 200 {
198 m_initialized = false; 201 m_initialized = false;
202 // we are passed the name of the region we're working for.
203 RegionName = identifier;
199 } 204 }
200 205
201 public override void Initialise(IMesher meshmerizer, IConfigSource config) 206 public override void Initialise(IMesher meshmerizer, IConfigSource config)
@@ -281,10 +286,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters
281 // Very detailed logging for physics debugging 286 // Very detailed logging for physics debugging
282 m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false); 287 m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false);
283 m_physicsLoggingDir = pConfig.GetString("PhysicsLoggingDir", "."); 288 m_physicsLoggingDir = pConfig.GetString("PhysicsLoggingDir", ".");
284 m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-"); 289 m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-%REGIONNAME%-");
285 m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5); 290 m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5);
286 // Very detailed logging for vehicle debugging 291 // Very detailed logging for vehicle debugging
287 m_vehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false); 292 m_vehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false);
293
294 // Do any replacements in the parameters
295 m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName);
288 } 296 }
289 } 297 }
290 } 298 }
@@ -362,7 +370,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
362 BSPrim bsprim = prim as BSPrim; 370 BSPrim bsprim = prim as BSPrim;
363 if (bsprim != null) 371 if (bsprim != null)
364 { 372 {
365 // DetailLog("{0},RemovePrim,call", bsprim.LocalID); 373 DetailLog("{0},RemovePrim,call", bsprim.LocalID);
366 // m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID); 374 // m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID);
367 try 375 try
368 { 376 {
@@ -388,7 +396,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
388 396
389 if (!m_initialized) return null; 397 if (!m_initialized) return null;
390 398
391 // DetailLog("{0},AddPrimShape,call", localID); 399 DetailLog("{0},AddPrimShape,call", localID);
392 400
393 BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical); 401 BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical);
394 lock (m_prims) m_prims.Add(localID, prim); 402 lock (m_prims) m_prims.Add(localID, prim);
@@ -429,13 +437,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters
429 { 437 {
430 numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep, 438 numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep,
431 out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr); 439 out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr);
432 // DetailLog("{0},Simulate,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount); 440 DetailLog("{0},Simulate,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount);
433 } 441 }
434 catch (Exception e) 442 catch (Exception e)
435 { 443 {
436 m_log.WarnFormat("{0},PhysicsStep Exception: substeps={1}, updates={2}, colliders={3}, e={4}", LogHeader, numSubSteps, updatedEntityCount, collidersCount, e); 444 m_log.WarnFormat("{0},PhysicsStep Exception: substeps={1}, updates={2}, colliders={3}, e={4}", LogHeader, numSubSteps, updatedEntityCount, collidersCount, e);
437 // DetailLog("{0},PhysicsStepException,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount); 445 // DetailLog("{0},PhysicsStepException,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount);
438 // updatedEntityCount = 0; 446 updatedEntityCount = 0;
439 collidersCount = 0; 447 collidersCount = 0;
440 } 448 }
441 449
@@ -534,6 +542,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
534 else if (m_avatars.ContainsKey(collidingWith)) 542 else if (m_avatars.ContainsKey(collidingWith))
535 type = ActorTypes.Agent; 543 type = ActorTypes.Agent;
536 544
545 // DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith);
546
537 BSPrim prim; 547 BSPrim prim;
538 if (m_prims.TryGetValue(localID, out prim)) { 548 if (m_prims.TryGetValue(localID, out prim)) {
539 prim.Collide(collidingWith, type, collidePoint, collideNormal, penitration); 549 prim.Collide(collidingWith, type, collidePoint, collideNormal, penitration);
@@ -897,16 +907,26 @@ public class BSScene : PhysicsScene, IPhysicsParameters
897 (s) => { return s.NumericBool(s._forceSimplePrimMeshing); }, 907 (s) => { return s.NumericBool(s._forceSimplePrimMeshing); },
898 (s,p,l,v) => { s._forceSimplePrimMeshing = s.BoolNumeric(v); } ), 908 (s,p,l,v) => { s._forceSimplePrimMeshing = s.BoolNumeric(v); } ),
899 909
900 new ParameterDefn("MeshLOD", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", 910 new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)",
901 8f, 911 8f,
902 (s,cf,p,v) => { s.m_meshLOD = cf.GetInt(p, (int)v); }, 912 (s,cf,p,v) => { s.MeshLOD = (float)cf.GetInt(p, (int)v); },
903 (s) => { return (float)s.m_meshLOD; }, 913 (s) => { return s.MeshLOD; },
904 (s,p,l,v) => { s.m_meshLOD = (int)v; } ), 914 (s,p,l,v) => { s.MeshLOD = v; } ),
905 new ParameterDefn("SculptLOD", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)", 915 new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters",
916 16f,
917 (s,cf,p,v) => { s.MeshMegaPrimLOD = (float)cf.GetInt(p, (int)v); },
918 (s) => { return s.MeshMegaPrimLOD; },
919 (s,p,l,v) => { s.MeshMegaPrimLOD = v; } ),
920 new ParameterDefn("MeshLevelOfDetailMegaPrimThreshold", "Size (in meters) of a mesh before using MeshMegaPrimLOD",
921 10f,
922 (s,cf,p,v) => { s.MeshMegaPrimThreshold = (float)cf.GetInt(p, (int)v); },
923 (s) => { return s.MeshMegaPrimThreshold; },
924 (s,p,l,v) => { s.MeshMegaPrimThreshold = v; } ),
925 new ParameterDefn("SculptLevelOfDetail", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)",
906 32f, 926 32f,
907 (s,cf,p,v) => { s.m_sculptLOD = cf.GetInt(p, (int)v); }, 927 (s,cf,p,v) => { s.SculptLOD = (float)cf.GetInt(p, (int)v); },
908 (s) => { return (float)s.m_sculptLOD; }, 928 (s) => { return s.SculptLOD; },
909 (s,p,l,v) => { s.m_sculptLOD = (int)v; } ), 929 (s,p,l,v) => { s.SculptLOD = v; } ),
910 930
911 new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps", 931 new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps",
912 10f, 932 10f,
@@ -1137,12 +1157,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1137 (s,cf,p,v) => { s.m_detailedStatsStep = cf.GetInt(p, (int)v); }, 1157 (s,cf,p,v) => { s.m_detailedStatsStep = cf.GetInt(p, (int)v); },
1138 (s) => { return (float)s.m_detailedStatsStep; }, 1158 (s) => { return (float)s.m_detailedStatsStep; },
1139 (s,p,l,v) => { s.m_detailedStatsStep = (int)v; } ), 1159 (s,p,l,v) => { s.m_detailedStatsStep = (int)v; } ),
1140 new ParameterDefn("ShouldDebugLog", "Enables detailed DEBUG log statements",
1141 ConfigurationParameters.numericFalse,
1142 (s,cf,p,v) => { s.ShouldDebugLog = cf.GetBoolean(p, s.BoolNumeric(v)); },
1143 (s) => { return s.NumericBool(s.ShouldDebugLog); },
1144 (s,p,l,v) => { s.ShouldDebugLog = s.BoolNumeric(v); } ),
1145
1146 }; 1160 };
1147 1161
1148 // Convert a boolean to our numeric true and false values 1162 // Convert a boolean to our numeric true and false values
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index d5e611c..4335592 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -426,14 +426,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
426 return key; 426 return key;
427 } 427 }
428 428
429 // convert a LSL_Rotation to a Quaternion
430 public static Quaternion Rot2Quaternion(LSL_Rotation r)
431 {
432 Quaternion q = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
433 q.Normalize();
434 return q;
435 }
436
437 //These are the implementations of the various ll-functions used by the LSL scripts. 429 //These are the implementations of the various ll-functions used by the LSL scripts.
438 public LSL_Float llSin(double f) 430 public LSL_Float llSin(double f)
439 { 431 {
@@ -1240,9 +1232,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1240 public LSL_Float llGround(LSL_Vector offset) 1232 public LSL_Float llGround(LSL_Vector offset)
1241 { 1233 {
1242 m_host.AddScriptLPS(1); 1234 m_host.AddScriptLPS(1);
1243 Vector3 pos = m_host.GetWorldPosition() + new Vector3((float)offset.x, 1235 Vector3 pos = m_host.GetWorldPosition() + (Vector3)offset;
1244 (float)offset.y,
1245 (float)offset.z);
1246 1236
1247 //Get the slope normal. This gives us the equation of the plane tangent to the slope. 1237 //Get the slope normal. This gives us the equation of the plane tangent to the slope.
1248 LSL_Vector vsn = llGroundNormal(offset); 1238 LSL_Vector vsn = llGroundNormal(offset);
@@ -1492,31 +1482,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1492 if (part == null || part.ParentGroup.IsDeleted) 1482 if (part == null || part.ParentGroup.IsDeleted)
1493 return; 1483 return;
1494 1484
1495 if (scale.x < 0.01) 1485 // First we need to check whether or not we need to clamp the size of a physics-enabled prim
1496 scale.x = 0.01;
1497 if (scale.y < 0.01)
1498 scale.y = 0.01;
1499 if (scale.z < 0.01)
1500 scale.z = 0.01;
1501
1502 PhysicsActor pa = part.ParentGroup.RootPart.PhysActor; 1486 PhysicsActor pa = part.ParentGroup.RootPart.PhysActor;
1503
1504 if (pa != null && pa.IsPhysical) 1487 if (pa != null && pa.IsPhysical)
1505 { 1488 {
1506 if (scale.x > World.m_maxPhys) 1489 scale.x = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.x));
1507 scale.x = World.m_maxPhys; 1490 scale.y = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.y));
1508 if (scale.y > World.m_maxPhys) 1491 scale.z = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.z));
1509 scale.y = World.m_maxPhys; 1492 }
1510 if (scale.z > World.m_maxPhys) 1493 else
1511 scale.z = World.m_maxPhys; 1494 {
1495 // If not physical, then we clamp the scale to the non-physical min/max
1496 scale.x = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.x));
1497 scale.y = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.y));
1498 scale.z = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.z));
1512 } 1499 }
1513
1514 if (scale.x > World.m_maxNonphys)
1515 scale.x = World.m_maxNonphys;
1516 if (scale.y > World.m_maxNonphys)
1517 scale.y = World.m_maxNonphys;
1518 if (scale.z > World.m_maxNonphys)
1519 scale.z = World.m_maxNonphys;
1520 1500
1521 Vector3 tmp = part.Scale; 1501 Vector3 tmp = part.Scale;
1522 tmp.X = (float)scale.x; 1502 tmp.X = (float)scale.x;
@@ -1590,7 +1570,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1590 if (face == ScriptBaseClass.ALL_SIDES) 1570 if (face == ScriptBaseClass.ALL_SIDES)
1591 face = SceneObjectPart.ALL_SIDES; 1571 face = SceneObjectPart.ALL_SIDES;
1592 1572
1593 m_host.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 1573 m_host.SetFaceColorAlpha(face, color, null);
1594 } 1574 }
1595 1575
1596 public void SetTexGen(SceneObjectPart part, int face,int style) 1576 public void SetTexGen(SceneObjectPart part, int face,int style)
@@ -2220,7 +2200,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2220 2200
2221 bool sameParcel = here.GlobalID == there.GlobalID; 2201 bool sameParcel = here.GlobalID == there.GlobalID;
2222 2202
2223 if (!sameParcel && !World.Permissions.CanObjectEntry(m_host.UUID, false, new Vector3((float)pos.x, (float)pos.y, (float)pos.z))) 2203 if (!sameParcel && !World.Permissions.CanRezObject(
2204 m_host.ParentGroup.PrimCount, m_host.ParentGroup.OwnerID, pos))
2224 { 2205 {
2225 return 0; 2206 return 0;
2226 } 2207 }
@@ -2279,16 +2260,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2279 if (part.ParentGroup.RootPart == part) 2260 if (part.ParentGroup.RootPart == part)
2280 { 2261 {
2281 SceneObjectGroup parent = part.ParentGroup; 2262 SceneObjectGroup parent = part.ParentGroup;
2282 Vector3 dest = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z); 2263 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2283 if (!World.Permissions.CanObjectEntry(parent.UUID, false, dest))
2284 return; 2264 return;
2285 Util.FireAndForget(delegate(object x) { 2265 Util.FireAndForget(delegate(object x) {
2286 parent.UpdateGroupPosition(dest); 2266 parent.UpdateGroupPosition((Vector3)toPos);
2287 }); 2267 });
2288 } 2268 }
2289 else 2269 else
2290 { 2270 {
2291 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z); 2271 part.OffsetPosition = (Vector3)toPos;
2292 SceneObjectGroup parent = part.ParentGroup; 2272 SceneObjectGroup parent = part.ParentGroup;
2293 parent.HasGroupChanged = true; 2273 parent.HasGroupChanged = true;
2294 parent.ScheduleGroupForTerseUpdate(); 2274 parent.ScheduleGroupForTerseUpdate();
@@ -2326,7 +2306,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2326 pos = part.AbsolutePosition; 2306 pos = part.AbsolutePosition;
2327 } 2307 }
2328 2308
2329 return new LSL_Vector(pos.X, pos.Y, pos.Z); 2309// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
2310
2311 return new LSL_Vector(pos);
2330 } 2312 }
2331 2313
2332 public void llSetRot(LSL_Rotation rot) 2314 public void llSetRot(LSL_Rotation rot)
@@ -2343,7 +2325,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2343 // using it would cause attachments and HUDs to rotate 2325 // using it would cause attachments and HUDs to rotate
2344 // to the wrong positions. 2326 // to the wrong positions.
2345 2327
2346 SetRot(m_host, Rot2Quaternion(rot)); 2328 SetRot(m_host, rot);
2347 } 2329 }
2348 else 2330 else
2349 { 2331 {
@@ -2353,7 +2335,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2353 { 2335 {
2354 rootPart = m_host.ParentGroup.RootPart; 2336 rootPart = m_host.ParentGroup.RootPart;
2355 if (rootPart != null) 2337 if (rootPart != null)
2356 SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot)); 2338 SetRot(m_host, rootPart.RotationOffset * (Quaternion)rot);
2357 } 2339 }
2358 } 2340 }
2359 2341
@@ -2363,8 +2345,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2363 public void llSetLocalRot(LSL_Rotation rot) 2345 public void llSetLocalRot(LSL_Rotation rot)
2364 { 2346 {
2365 m_host.AddScriptLPS(1); 2347 m_host.AddScriptLPS(1);
2366 2348 SetRot(m_host, rot);
2367 SetRot(m_host, Rot2Quaternion(rot));
2368 ScriptSleep(200); 2349 ScriptSleep(200);
2369 } 2350 }
2370 2351
@@ -2476,7 +2457,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2476 if (local != 0) 2457 if (local != 0)
2477 force *= llGetRot(); 2458 force *= llGetRot();
2478 2459
2479 m_host.ParentGroup.RootPart.SetForce(new Vector3((float)force.x, (float)force.y, (float)force.z)); 2460 m_host.ParentGroup.RootPart.SetForce(force);
2480 } 2461 }
2481 } 2462 }
2482 2463
@@ -2488,10 +2469,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2488 2469
2489 if (!m_host.ParentGroup.IsDeleted) 2470 if (!m_host.ParentGroup.IsDeleted)
2490 { 2471 {
2491 Vector3 tmpForce = m_host.ParentGroup.RootPart.GetForce(); 2472 force = m_host.ParentGroup.RootPart.GetForce();
2492 force.x = tmpForce.X;
2493 force.y = tmpForce.Y;
2494 force.z = tmpForce.Z;
2495 } 2473 }
2496 2474
2497 return force; 2475 return force;
@@ -2500,8 +2478,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2500 public LSL_Integer llTarget(LSL_Vector position, double range) 2478 public LSL_Integer llTarget(LSL_Vector position, double range)
2501 { 2479 {
2502 m_host.AddScriptLPS(1); 2480 m_host.AddScriptLPS(1);
2503 return m_host.ParentGroup.registerTargetWaypoint( 2481 return m_host.ParentGroup.registerTargetWaypoint(position,
2504 new Vector3((float)position.x, (float)position.y, (float)position.z), (float)range); 2482 (float)range);
2505 } 2483 }
2506 2484
2507 public void llTargetRemove(int number) 2485 public void llTargetRemove(int number)
@@ -2513,8 +2491,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2513 public LSL_Integer llRotTarget(LSL_Rotation rot, double error) 2491 public LSL_Integer llRotTarget(LSL_Rotation rot, double error)
2514 { 2492 {
2515 m_host.AddScriptLPS(1); 2493 m_host.AddScriptLPS(1);
2516 return m_host.ParentGroup.registerRotTargetWaypoint( 2494 return m_host.ParentGroup.registerRotTargetWaypoint(rot, (float)error);
2517 new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s), (float)error);
2518 } 2495 }
2519 2496
2520 public void llRotTargetRemove(int number) 2497 public void llRotTargetRemove(int number)
@@ -2526,7 +2503,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2526 public void llMoveToTarget(LSL_Vector target, double tau) 2503 public void llMoveToTarget(LSL_Vector target, double tau)
2527 { 2504 {
2528 m_host.AddScriptLPS(1); 2505 m_host.AddScriptLPS(1);
2529 m_host.MoveToTarget(new Vector3((float)target.x, (float)target.y, (float)target.z), (float)tau); 2506 m_host.MoveToTarget(target, (float)tau);
2530 } 2507 }
2531 2508
2532 public void llStopMoveToTarget() 2509 public void llStopMoveToTarget()
@@ -2539,7 +2516,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2539 { 2516 {
2540 m_host.AddScriptLPS(1); 2517 m_host.AddScriptLPS(1);
2541 //No energy force yet 2518 //No energy force yet
2542 Vector3 v = new Vector3((float)force.x, (float)force.y, (float)force.z); 2519 Vector3 v = force;
2543 if (v.Length() > 20000.0f) 2520 if (v.Length() > 20000.0f)
2544 { 2521 {
2545 v.Normalize(); 2522 v.Normalize();
@@ -2552,13 +2529,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2552 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2529 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2553 { 2530 {
2554 m_host.AddScriptLPS(1); 2531 m_host.AddScriptLPS(1);
2555 m_host.ParentGroup.RootPart.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); 2532 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2556 } 2533 }
2557 2534
2558 public void llSetTorque(LSL_Vector torque, int local) 2535 public void llSetTorque(LSL_Vector torque, int local)
2559 { 2536 {
2560 m_host.AddScriptLPS(1); 2537 m_host.AddScriptLPS(1);
2561 m_host.ParentGroup.RootPart.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); 2538 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2562 } 2539 }
2563 2540
2564 public LSL_Vector llGetTorque() 2541 public LSL_Vector llGetTorque()
@@ -3123,13 +3100,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3123 return; 3100 return;
3124 } 3101 }
3125 3102
3126 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
3127 Vector3 llvel = new Vector3((float)vel.x, (float)vel.y, (float)vel.z);
3128
3129 // need the magnitude later 3103 // need the magnitude later
3130 // float velmag = (float)Util.GetMagnitude(llvel); 3104 // float velmag = (float)Util.GetMagnitude(llvel);
3131 3105
3132 SceneObjectGroup new_group = World.RezObject(m_host, item, llpos, Rot2Quaternion(rot), llvel, param); 3106 SceneObjectGroup new_group = World.RezObject(m_host, item, pos, rot, vel, param);
3133 3107
3134 // If either of these are null, then there was an unknown error. 3108 // If either of these are null, then there was an unknown error.
3135 if (new_group == null) 3109 if (new_group == null)
@@ -3156,11 +3130,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3156 3130
3157 PhysicsActor pa = new_group.RootPart.PhysActor; 3131 PhysicsActor pa = new_group.RootPart.PhysActor;
3158 3132
3159 if (pa != null && pa.IsPhysical && llvel != Vector3.Zero) 3133 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
3160 { 3134 {
3161 float groupmass = new_group.GetMass(); 3135 float groupmass = new_group.GetMass();
3162 llvel *= -groupmass; 3136 vel *= -groupmass;
3163 llApplyImpulse(new LSL_Vector(llvel.X, llvel.Y,llvel.Z), 0); 3137 llApplyImpulse(vel, 0);
3164 } 3138 }
3165 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3139 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3166 return; 3140 return;
@@ -3211,7 +3185,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3211 return; 3185 return;
3212 } 3186 }
3213 3187
3214 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping); 3188 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
3215 } 3189 }
3216 } 3190 }
3217 3191
@@ -3637,7 +3611,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3637 } 3611 }
3638 else 3612 else
3639 { 3613 {
3640 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping); 3614 m_host.RotLookAt(target, (float)strength, (float)damping);
3641 } 3615 }
3642 } 3616 }
3643 3617
@@ -3718,7 +3692,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3718 3692
3719 protected void TargetOmega(SceneObjectPart part, LSL_Vector axis, double spinrate, double gain) 3693 protected void TargetOmega(SceneObjectPart part, LSL_Vector axis, double spinrate, double gain)
3720 { 3694 {
3721 part.UpdateAngularVelocity(new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate))); 3695 part.UpdateAngularVelocity(axis * spinrate);
3722 } 3696 }
3723 3697
3724 public LSL_Integer llGetStartParameter() 3698 public LSL_Integer llGetStartParameter()
@@ -3928,7 +3902,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3928 try 3902 try
3929 { 3903 {
3930 foreach (SceneObjectPart part in parts) 3904 foreach (SceneObjectPart part in parts)
3931 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3905 part.SetFaceColorAlpha(face, color, null);
3932 } 3906 }
3933 finally 3907 finally
3934 { 3908 {
@@ -4398,9 +4372,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4398 public void llSetText(string text, LSL_Vector color, double alpha) 4372 public void llSetText(string text, LSL_Vector color, double alpha)
4399 { 4373 {
4400 m_host.AddScriptLPS(1); 4374 m_host.AddScriptLPS(1);
4401 Vector3 av3 = new Vector3(Util.Clip((float)color.x, 0.0f, 1.0f), 4375 Vector3 av3 = Util.Clip(color, 0.0f, 1.0f);
4402 Util.Clip((float)color.y, 0.0f, 1.0f),
4403 Util.Clip((float)color.z, 0.0f, 1.0f));
4404 m_host.SetText(text.Length > 254 ? text.Remove(254) : text, av3, Util.Clip((float)alpha, 0.0f, 1.0f)); 4376 m_host.SetText(text.Length > 254 ? text.Remove(254) : text, av3, Util.Clip((float)alpha, 0.0f, 1.0f));
4405 //m_host.ParentGroup.HasGroupChanged = true; 4377 //m_host.ParentGroup.HasGroupChanged = true;
4406 //m_host.ParentGroup.ScheduleGroupForFullUpdate(); 4378 //m_host.ParentGroup.ScheduleGroupForFullUpdate();
@@ -4616,14 +4588,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4616 ScriptSleep(5000); 4588 ScriptSleep(5000);
4617 } 4589 }
4618 4590
4619 public void llTeleportAgent(string agent, string destination, LSL_Vector pos, LSL_Vector lookAt) 4591 public void llTeleportAgent(string agent, string destination, LSL_Vector targetPos, LSL_Vector targetLookAt)
4620 { 4592 {
4621 m_host.AddScriptLPS(1); 4593 m_host.AddScriptLPS(1);
4622 UUID agentId = new UUID(); 4594 UUID agentId = new UUID();
4623 4595
4624 Vector3 targetPos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
4625 Vector3 targetLookAt = new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z);
4626
4627 if (UUID.TryParse(agent, out agentId)) 4596 if (UUID.TryParse(agent, out agentId))
4628 { 4597 {
4629 ScenePresence presence = World.GetScenePresence(agentId); 4598 ScenePresence presence = World.GetScenePresence(agentId);
@@ -4652,15 +4621,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4652 } 4621 }
4653 } 4622 }
4654 4623
4655 public void llTeleportAgentGlobalCoords(string agent, LSL_Vector global_coords, LSL_Vector pos, LSL_Vector lookAt) 4624 public void llTeleportAgentGlobalCoords(string agent, LSL_Vector global_coords, LSL_Vector targetPos, LSL_Vector targetLookAt)
4656 { 4625 {
4657 m_host.AddScriptLPS(1); 4626 m_host.AddScriptLPS(1);
4658 UUID agentId = new UUID(); 4627 UUID agentId = new UUID();
4659 4628
4660 ulong regionHandle = Utils.UIntsToLong((uint)global_coords.x, (uint)global_coords.y); 4629 ulong regionHandle = Utils.UIntsToLong((uint)global_coords.x, (uint)global_coords.y);
4661 4630
4662 Vector3 targetPos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
4663 Vector3 targetLookAt = new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z);
4664 if (UUID.TryParse(agent, out agentId)) 4631 if (UUID.TryParse(agent, out agentId))
4665 { 4632 {
4666 ScenePresence presence = World.GetScenePresence(agentId); 4633 ScenePresence presence = World.GetScenePresence(agentId);
@@ -4957,7 +4924,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4957 distance_attenuation = 1f / normalized_units; 4924 distance_attenuation = 1f / normalized_units;
4958 } 4925 }
4959 4926
4960 Vector3 applied_linear_impulse = new Vector3((float)impulse.x, (float)impulse.y, (float)impulse.z); 4927 Vector3 applied_linear_impulse = impulse;
4961 { 4928 {
4962 float impulse_length = applied_linear_impulse.Length(); 4929 float impulse_length = applied_linear_impulse.Length();
4963 4930
@@ -5605,25 +5572,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5605 /// separated list. There is a space after 5572 /// separated list. There is a space after
5606 /// each comma. 5573 /// each comma.
5607 /// </summary> 5574 /// </summary>
5608
5609 public LSL_String llList2CSV(LSL_List src) 5575 public LSL_String llList2CSV(LSL_List src)
5610 { 5576 {
5611
5612 string ret = String.Empty;
5613 int x = 0;
5614
5615 m_host.AddScriptLPS(1); 5577 m_host.AddScriptLPS(1);
5616 5578
5617 if (src.Data.Length > 0) 5579 return string.Join(", ",
5618 { 5580 (new List<object>(src.Data)).ConvertAll<string>(o =>
5619 ret = src.Data[x++].ToString(); 5581 {
5620 for (; x < src.Data.Length; x++) 5582 return o.ToString();
5621 { 5583 }).ToArray());
5622 ret += ", "+src.Data[x].ToString();
5623 }
5624 }
5625
5626 return ret;
5627 } 5584 }
5628 5585
5629 /// <summary> 5586 /// <summary>
@@ -6296,19 +6253,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6296 m_host.AddScriptLPS(1); 6253 m_host.AddScriptLPS(1);
6297 6254
6298 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6255 List<SceneObjectPart> parts = GetLinkParts(linknumber);
6299 if (parts.Count > 0) 6256
6257 try
6300 { 6258 {
6301 try 6259 foreach (SceneObjectPart part in parts)
6302 {
6303 foreach (var part in parts)
6304 {
6305 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6306 }
6307 }
6308 finally
6309 { 6260 {
6261 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6310 } 6262 }
6311 } 6263 }
6264 finally
6265 {
6266 }
6312 } 6267 }
6313 6268
6314 private void SetTextureAnim(SceneObjectPart part, int mode, int face, int sizex, int sizey, double start, double length, double rate) 6269 private void SetTextureAnim(SceneObjectPart part, int mode, int face, int sizex, int sizey, double start, double length, double rate)
@@ -6526,9 +6481,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6526 6481
6527 //Plug the x,y coordinates of the slope normal into the equation of the plane to get 6482 //Plug the x,y coordinates of the slope normal into the equation of the plane to get
6528 //the height of that point on the plane. The resulting vector gives the slope. 6483 //the height of that point on the plane. The resulting vector gives the slope.
6529 Vector3 vsl = new Vector3(); 6484 Vector3 vsl = vsn;
6530 vsl.X = (float)vsn.x;
6531 vsl.Y = (float)vsn.y;
6532 vsl.Z = (float)(((vsn.x * vsn.x) + (vsn.y * vsn.y)) / (-1 * vsn.z)); 6485 vsl.Z = (float)(((vsn.x * vsn.x) + (vsn.y * vsn.y)) / (-1 * vsn.z));
6533 vsl.Normalize(); 6486 vsl.Normalize();
6534 //Normalization might be overkill here 6487 //Normalization might be overkill here
@@ -6539,9 +6492,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6539 public LSL_Vector llGroundNormal(LSL_Vector offset) 6492 public LSL_Vector llGroundNormal(LSL_Vector offset)
6540 { 6493 {
6541 m_host.AddScriptLPS(1); 6494 m_host.AddScriptLPS(1);
6542 Vector3 pos = m_host.GetWorldPosition() + new Vector3((float)offset.x, 6495 Vector3 pos = m_host.GetWorldPosition() + (Vector3)offset;
6543 (float)offset.y,
6544 (float)offset.z);
6545 // Clamp to valid position 6496 // Clamp to valid position
6546 if (pos.X < 0) 6497 if (pos.X < 0)
6547 pos.X = 0; 6498 pos.X = 0;
@@ -6706,7 +6657,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6706 6657
6707 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6658 List<SceneObjectPart> parts = GetLinkParts(linknumber);
6708 6659
6709 foreach (var part in parts) 6660 foreach (SceneObjectPart part in parts)
6710 { 6661 {
6711 SetParticleSystem(part, rules); 6662 SetParticleSystem(part, rules);
6712 } 6663 }
@@ -6995,8 +6946,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6995 6946
6996 if (!m_host.ParentGroup.IsDeleted) 6947 if (!m_host.ParentGroup.IsDeleted)
6997 { 6948 {
6998 m_host.ParentGroup.RootPart.SetVehicleVectorParam(param, 6949 m_host.ParentGroup.RootPart.SetVehicleVectorParam(param, vec);
6999 new Vector3((float)vec.x, (float)vec.y, (float)vec.z));
7000 } 6950 }
7001 } 6951 }
7002 6952
@@ -7008,7 +6958,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7008 6958
7009 if (!m_host.ParentGroup.IsDeleted) 6959 if (!m_host.ParentGroup.IsDeleted)
7010 { 6960 {
7011 m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, Rot2Quaternion(rot)); 6961 m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, rot);
7012 } 6962 }
7013 } 6963 }
7014 6964
@@ -7038,8 +6988,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7038 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0) 6988 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7039 rot.s = 1; // ZERO_ROTATION = 0,0,0,1 6989 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7040 6990
7041 part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z); 6991 part.SitTargetPosition = offset;
7042 part.SitTargetOrientation = Rot2Quaternion(rot); 6992 part.SitTargetOrientation = rot;
7043 part.ParentGroup.HasGroupChanged = true; 6993 part.ParentGroup.HasGroupChanged = true;
7044 } 6994 }
7045 6995
@@ -7142,13 +7092,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7142 public void llSetCameraEyeOffset(LSL_Vector offset) 7092 public void llSetCameraEyeOffset(LSL_Vector offset)
7143 { 7093 {
7144 m_host.AddScriptLPS(1); 7094 m_host.AddScriptLPS(1);
7145 m_host.SetCameraEyeOffset(new Vector3((float)offset.x, (float)offset.y, (float)offset.z)); 7095 m_host.SetCameraEyeOffset(offset);
7146 } 7096 }
7147 7097
7148 public void llSetCameraAtOffset(LSL_Vector offset) 7098 public void llSetCameraAtOffset(LSL_Vector offset)
7149 { 7099 {
7150 m_host.AddScriptLPS(1); 7100 m_host.AddScriptLPS(1);
7151 m_host.SetCameraAtOffset(new Vector3((float)offset.x, (float)offset.y, (float)offset.z)); 7101 m_host.SetCameraAtOffset(offset);
7152 } 7102 }
7153 7103
7154 public LSL_String llDumpList2String(LSL_List src, string seperator) 7104 public LSL_String llDumpList2String(LSL_List src, string seperator)
@@ -7170,7 +7120,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7170 public LSL_Integer llScriptDanger(LSL_Vector pos) 7120 public LSL_Integer llScriptDanger(LSL_Vector pos)
7171 { 7121 {
7172 m_host.AddScriptLPS(1); 7122 m_host.AddScriptLPS(1);
7173 bool result = World.ScriptDanger(m_host.LocalId, new Vector3((float)pos.x, (float)pos.y, (float)pos.z)); 7123 bool result = World.ScriptDanger(m_host.LocalId, pos);
7174 if (result) 7124 if (result)
7175 { 7125 {
7176 return 1; 7126 return 1;
@@ -7752,7 +7702,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7752 { 7702 {
7753 m_host.AddScriptLPS(1); 7703 m_host.AddScriptLPS(1);
7754 7704
7755 setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules); 7705 setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules, "llSetPrimitiveParams");
7756 7706
7757 ScriptSleep(200); 7707 ScriptSleep(200);
7758 } 7708 }
@@ -7761,10 +7711,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7761 { 7711 {
7762 m_host.AddScriptLPS(1); 7712 m_host.AddScriptLPS(1);
7763 7713
7764 setLinkPrimParams(linknumber, rules); 7714 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7715
7716 ScriptSleep(200);
7765 } 7717 }
7766 7718
7767 private void setLinkPrimParams(int linknumber, LSL_List rules) 7719 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7768 { 7720 {
7769 List<object> parts = new List<object>(); 7721 List<object> parts = new List<object>();
7770 List<SceneObjectPart> prims = GetLinkParts(linknumber); 7722 List<SceneObjectPart> prims = GetLinkParts(linknumber);
@@ -7775,15 +7727,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7775 parts.Add(p); 7727 parts.Add(p);
7776 7728
7777 LSL_List remaining = null; 7729 LSL_List remaining = null;
7730 uint rulesParsed = 0;
7778 7731
7779 if (parts.Count > 0) 7732 if (parts.Count > 0)
7780 { 7733 {
7781 foreach (object part in parts) 7734 foreach (object part in parts)
7782 { 7735 {
7783 if (part is SceneObjectPart) 7736 if (part is SceneObjectPart)
7784 remaining = SetPrimParams((SceneObjectPart)part, rules); 7737 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7785 else 7738 else
7786 remaining = SetPrimParams((ScenePresence)part, rules); 7739 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7787 } 7740 }
7788 7741
7789 while ((object)remaining != null && remaining.Length > 2) 7742 while ((object)remaining != null && remaining.Length > 2)
@@ -7802,9 +7755,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7802 foreach (object part in parts) 7755 foreach (object part in parts)
7803 { 7756 {
7804 if (part is SceneObjectPart) 7757 if (part is SceneObjectPart)
7805 remaining = SetPrimParams((SceneObjectPart)part, rules); 7758 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7806 else 7759 else
7807 remaining = SetPrimParams((ScenePresence)part, rules); 7760 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7808 } 7761 }
7809 } 7762 }
7810 } 7763 }
@@ -7842,6 +7795,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7842 7795
7843 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7796 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7844 { 7797 {
7798 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7845 llSetLinkPrimitiveParamsFast(linknumber, rules); 7799 llSetLinkPrimitiveParamsFast(linknumber, rules);
7846 ScriptSleep(200); 7800 ScriptSleep(200);
7847 } 7801 }
@@ -7869,195 +7823,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7869 return new Vector3((float)x, (float)y, (float)z); 7823 return new Vector3((float)x, (float)y, (float)z);
7870 } 7824 }
7871 7825
7872 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules) 7826 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7873 {
7874 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7875
7876 int idx = 0;
7877
7878 bool positionChanged = false;
7879 Vector3 finalPos = Vector3.Zero;
7880
7881 try
7882 {
7883 while (idx < rules.Length)
7884 {
7885 int code = rules.GetLSLIntegerItem(idx++);
7886
7887 int remain = rules.Length - idx;
7888
7889 switch (code)
7890 {
7891 case (int)ScriptBaseClass.PRIM_POSITION:
7892 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7893 {
7894 if (remain < 1)
7895 return null;
7896
7897 LSL_Vector v;
7898 v = rules.GetVector3Item(idx++);
7899
7900 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7901 if (part == null)
7902 break;
7903
7904 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7905 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7906 if (part.LinkNum > 1)
7907 {
7908 localRot = GetPartLocalRot(part);
7909 localPos = GetPartLocalPos(part);
7910 }
7911
7912 v -= localPos;
7913 v /= localRot;
7914
7915 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
7916
7917 v = v + 2 * sitOffset;
7918
7919 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7920 av.SendAvatarDataToAllAgents();
7921
7922 }
7923 break;
7924
7925 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7926 case (int)ScriptBaseClass.PRIM_ROTATION:
7927 {
7928 if (remain < 1)
7929 return null;
7930
7931 LSL_Rotation r;
7932 r = rules.GetQuaternionItem(idx++);
7933
7934 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7935 if (part == null)
7936 break;
7937
7938 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7939 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7940
7941 if (part.LinkNum > 1)
7942 localRot = GetPartLocalRot(part);
7943
7944 r = r * llGetRootRotation() / localRot;
7945 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7946 av.SendAvatarDataToAllAgents();
7947 }
7948 break;
7949
7950 // parse rest doing nothing but number of parameters error check
7951 case (int)ScriptBaseClass.PRIM_SIZE:
7952 case (int)ScriptBaseClass.PRIM_MATERIAL:
7953 case (int)ScriptBaseClass.PRIM_PHANTOM:
7954 case (int)ScriptBaseClass.PRIM_PHYSICS:
7955 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
7956 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7957 case (int)ScriptBaseClass.PRIM_NAME:
7958 case (int)ScriptBaseClass.PRIM_DESC:
7959 if (remain < 1)
7960 return null;
7961 idx++;
7962 break;
7963
7964 case (int)ScriptBaseClass.PRIM_GLOW:
7965 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7966 case (int)ScriptBaseClass.PRIM_TEXGEN:
7967 if (remain < 2)
7968 return null;
7969 idx += 2;
7970 break;
7971
7972 case (int)ScriptBaseClass.PRIM_TYPE:
7973 if (remain < 3)
7974 return null;
7975 code = (int)rules.GetLSLIntegerItem(idx++);
7976 remain = rules.Length - idx;
7977 switch (code)
7978 {
7979 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
7980 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
7981 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
7982 if (remain < 6)
7983 return null;
7984 idx += 6;
7985 break;
7986
7987 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
7988 if (remain < 5)
7989 return null;
7990 idx += 5;
7991 break;
7992
7993 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
7994 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
7995 case (int)ScriptBaseClass.PRIM_TYPE_RING:
7996 if (remain < 11)
7997 return null;
7998 idx += 11;
7999 break;
8000
8001 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
8002 if (remain < 2)
8003 return null;
8004 idx += 2;
8005 break;
8006 }
8007 break;
8008
8009 case (int)ScriptBaseClass.PRIM_COLOR:
8010 case (int)ScriptBaseClass.PRIM_TEXT:
8011 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8012 case (int)ScriptBaseClass.PRIM_OMEGA:
8013 if (remain < 3)
8014 return null;
8015 idx += 3;
8016 break;
8017
8018 case (int)ScriptBaseClass.PRIM_TEXTURE:
8019 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
8020 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8021 if (remain < 5)
8022 return null;
8023 idx += 5;
8024 break;
8025
8026 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
8027 if (remain < 7)
8028 return null;
8029
8030 idx += 7;
8031 break;
8032
8033 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
8034 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
8035 return null;
8036
8037 return rules.GetSublist(idx, -1);
8038 }
8039 }
8040 }
8041
8042 finally
8043 {
8044 if (positionChanged)
8045 {
8046 av.OffsetPosition = finalPos;
8047// av.SendAvatarDataToAllAgents();
8048 av.SendTerseUpdateToAllClients();
8049 positionChanged = false;
8050 }
8051 }
8052 return null;
8053 }
8054
8055 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules)
8056 { 7827 {
8057 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 7828 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8058 return null; 7829 return null;
8059 7830
8060 int idx = 0; 7831 int idx = 0;
7832 int idxStart = 0;
8061 7833
8062 SceneObjectGroup parentgrp = part.ParentGroup; 7834 SceneObjectGroup parentgrp = part.ParentGroup;
8063 7835
@@ -8068,9 +7840,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8068 { 7840 {
8069 while (idx < rules.Length) 7841 while (idx < rules.Length)
8070 { 7842 {
7843 ++rulesParsed;
8071 int code = rules.GetLSLIntegerItem(idx++); 7844 int code = rules.GetLSLIntegerItem(idx++);
8072 7845
8073 int remain = rules.Length - idx; 7846 int remain = rules.Length - idx;
7847 idxStart = idx;
8074 7848
8075 int face; 7849 int face;
8076 LSL_Vector v; 7850 LSL_Vector v;
@@ -8105,13 +7879,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8105 if (rootPart == part) 7879 if (rootPart == part)
8106 { 7880 {
8107 // special case: If we are root, rotate complete SOG to new rotation 7881 // special case: If we are root, rotate complete SOG to new rotation
8108 SetRot(part, Rot2Quaternion(q)); 7882 SetRot(part, q);
8109 } 7883 }
8110 else 7884 else
8111 { 7885 {
8112 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 7886 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
8113 // sounds like sl bug that we need to replicate 7887 // sounds like sl bug that we need to replicate
8114 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q)); 7888 SetRot(part, rootPart.RotationOffset * (Quaternion)q);
8115 } 7889 }
8116 7890
8117 break; 7891 break;
@@ -8285,8 +8059,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8285 LSL_Vector color=rules.GetVector3Item(idx++); 8059 LSL_Vector color=rules.GetVector3Item(idx++);
8286 double alpha=(double)rules.GetLSLFloatItem(idx++); 8060 double alpha=(double)rules.GetLSLFloatItem(idx++);
8287 8061
8288 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 8062 part.SetFaceColorAlpha(face, color, alpha);
8289 SetAlpha(part, alpha, face);
8290 8063
8291 break; 8064 break;
8292 8065
@@ -8434,9 +8207,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8434 string primText = rules.GetLSLStringItem(idx++); 8207 string primText = rules.GetLSLStringItem(idx++);
8435 LSL_Vector primTextColor = rules.GetVector3Item(idx++); 8208 LSL_Vector primTextColor = rules.GetVector3Item(idx++);
8436 LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++); 8209 LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++);
8437 Vector3 av3 = new Vector3(Util.Clip((float)primTextColor.x, 0.0f, 1.0f), 8210 Vector3 av3 = Util.Clip(primTextColor, 0.0f, 1.0f);
8438 Util.Clip((float)primTextColor.y, 0.0f, 1.0f),
8439 Util.Clip((float)primTextColor.z, 0.0f, 1.0f));
8440 part.SetText(primText, av3, Util.Clip((float)primTextAlpha, 0.0f, 1.0f)); 8211 part.SetText(primText, av3, Util.Clip((float)primTextAlpha, 0.0f, 1.0f));
8441 8212
8442 break; 8213 break;
@@ -8455,8 +8226,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8455 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 8226 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8456 if (remain < 1) 8227 if (remain < 1)
8457 return null; 8228 return null;
8458 LSL_Rotation lr = rules.GetQuaternionItem(idx++); 8229 SetRot(part, rules.GetQuaternionItem(idx++));
8459 SetRot(part, Rot2Quaternion(lr));
8460 break; 8230 break;
8461 case (int)ScriptBaseClass.PRIM_OMEGA: 8231 case (int)ScriptBaseClass.PRIM_OMEGA:
8462 if (remain < 3) 8232 if (remain < 3)
@@ -8466,7 +8236,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8466 LSL_Float gain = rules.GetLSLFloatItem(idx++); 8236 LSL_Float gain = rules.GetLSLFloatItem(idx++);
8467 TargetOmega(part, axis, (double)spinrate, (double)gain); 8237 TargetOmega(part, axis, (double)spinrate, (double)gain);
8468 break; 8238 break;
8469 8239 case (int)ScriptBaseClass.PRIM_SLICE:
8240 if (remain < 1)
8241 return null;
8242 LSL_Vector slice = rules.GetVector3Item(idx++);
8243 part.UpdateSlice((float)slice.x, (float)slice.y);
8244 break;
8470 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 8245 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
8471 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. 8246 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
8472 return null; 8247 return null;
@@ -8475,6 +8250,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8475 } 8250 }
8476 } 8251 }
8477 } 8252 }
8253 catch (InvalidCastException e)
8254 {
8255 ShoutError(string.Format(
8256 "{0} error running rule #{1}: arg #{2} ",
8257 originFunc, rulesParsed, idx - idxStart) + e.Message);
8258 }
8478 finally 8259 finally
8479 { 8260 {
8480 if (positionChanged) 8261 if (positionChanged)
@@ -8483,12 +8264,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8483 { 8264 {
8484 SceneObjectGroup parent = part.ParentGroup; 8265 SceneObjectGroup parent = part.ParentGroup;
8485 Util.FireAndForget(delegate(object x) { 8266 Util.FireAndForget(delegate(object x) {
8486 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8267 parent.UpdateGroupPosition(currentPosition);
8487 }); 8268 });
8488 } 8269 }
8489 else 8270 else
8490 { 8271 {
8491 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z); 8272 part.OffsetPosition = currentPosition;
8492 SceneObjectGroup parent = part.ParentGroup; 8273 SceneObjectGroup parent = part.ParentGroup;
8493 parent.HasGroupChanged = true; 8274 parent.HasGroupChanged = true;
8494 parent.ScheduleGroupForTerseUpdate(); 8275 parent.ScheduleGroupForTerseUpdate();
@@ -8866,7 +8647,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8866 public LSL_List llGetPrimitiveParams(LSL_List rules) 8647 public LSL_List llGetPrimitiveParams(LSL_List rules)
8867 { 8648 {
8868 m_host.AddScriptLPS(1); 8649 m_host.AddScriptLPS(1);
8869 return GetLinkPrimitiveParams(m_host, rules); 8650
8651 LSL_List result = new LSL_List();
8652
8653 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
8654
8655 while (remaining != null && remaining.Length > 2)
8656 {
8657 int linknumber = remaining.GetLSLIntegerItem(0);
8658 rules = remaining.GetSublist(1, -1);
8659 List<SceneObjectPart> parts = GetLinkParts(linknumber);
8660
8661 foreach (SceneObjectPart part in parts)
8662 remaining = GetPrimParams(part, rules, ref result);
8663 }
8664
8665 return result;
8870 } 8666 }
8871 8667
8872 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules) 8668 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules)
@@ -8876,294 +8672,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8876 // acording to SL wiki this must indicate a single link number or link_root or link_this. 8672 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8877 // keep other options as before 8673 // keep other options as before
8878 8674
8879 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8675 List<SceneObjectPart> parts;
8880 List<ScenePresence> avatars = GetLinkAvatars(linknumber); 8676 List<ScenePresence> avatars;
8881 8677
8882 LSL_List res = new LSL_List(); 8678 LSL_List res = new LSL_List();
8679 LSL_List remaining = null;
8883 8680
8884 if (parts.Count > 0) 8681 while (rules.Length > 0)
8885 { 8682 {
8886 foreach (var part in parts) 8683 parts = GetLinkParts(linknumber);
8684 avatars = GetLinkAvatars(linknumber);
8685
8686 remaining = null;
8687 foreach (SceneObjectPart part in parts)
8887 { 8688 {
8888 LSL_List partRes = GetLinkPrimitiveParams(part, rules); 8689 remaining = GetPrimParams(part, rules, ref res);
8889 res += partRes;
8890 } 8690 }
8891 }
8892 if (avatars.Count > 0)
8893 {
8894 foreach (ScenePresence avatar in avatars) 8691 foreach (ScenePresence avatar in avatars)
8895 { 8692 {
8896 LSL_List avaRes = GetLinkPrimitiveParams(avatar, rules); 8693 remaining = GetPrimParams(avatar, rules, ref res);
8897 res += avaRes;
8898 } 8694 }
8899 }
8900 return res;
8901 }
8902
8903 public LSL_List GetLinkPrimitiveParams(ScenePresence avatar, LSL_List rules)
8904 {
8905 // avatars case
8906 // replies as SL wiki
8907
8908 LSL_List res = new LSL_List();
8909// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
8910 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
8911 8695
8912 int idx = 0; 8696 if (remaining != null && remaining.Length > 0)
8913 while (idx < rules.Length)
8914 {
8915 int code = (int)rules.GetLSLIntegerItem(idx++);
8916 int remain = rules.Length - idx;
8917
8918 switch (code)
8919 { 8697 {
8920 case (int)ScriptBaseClass.PRIM_MATERIAL: 8698 linknumber = remaining.GetLSLIntegerItem(0);
8921 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh)); 8699 rules = remaining.GetSublist(1, -1);
8922 break;
8923
8924 case (int)ScriptBaseClass.PRIM_PHYSICS:
8925 res.Add(new LSL_Integer(0));
8926 break;
8927
8928 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8929 res.Add(new LSL_Integer(0));
8930 break;
8931
8932 case (int)ScriptBaseClass.PRIM_PHANTOM:
8933 res.Add(new LSL_Integer(0));
8934 break;
8935
8936 case (int)ScriptBaseClass.PRIM_POSITION:
8937
8938 Vector3 pos = avatar.OffsetPosition;
8939
8940 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
8941 pos -= sitOffset;
8942
8943 if( sitPart != null)
8944 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
8945
8946 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
8947 break;
8948
8949 case (int)ScriptBaseClass.PRIM_SIZE:
8950 // as in llGetAgentSize above
8951 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
8952 break;
8953
8954 case (int)ScriptBaseClass.PRIM_ROTATION:
8955 Quaternion rot = avatar.Rotation;
8956 if (sitPart != null)
8957 {
8958 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
8959 }
8960
8961 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
8962 break;
8963
8964 case (int)ScriptBaseClass.PRIM_TYPE:
8965 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8966 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8967 res.Add(new LSL_Vector(0f,1.0f,0f));
8968 res.Add(new LSL_Float(0.0f));
8969 res.Add(new LSL_Vector(0, 0, 0));
8970 res.Add(new LSL_Vector(1.0f,1.0f,0f));
8971 res.Add(new LSL_Vector(0, 0, 0));
8972 break;
8973
8974 case (int)ScriptBaseClass.PRIM_TEXTURE:
8975 if (remain < 1)
8976 return res;
8977
8978 int face = (int)rules.GetLSLIntegerItem(idx++);
8979 if (face == ScriptBaseClass.ALL_SIDES)
8980 {
8981 for (face = 0; face < 21; face++)
8982 {
8983 res.Add(new LSL_String(""));
8984 res.Add(new LSL_Vector(0,0,0));
8985 res.Add(new LSL_Vector(0,0,0));
8986 res.Add(new LSL_Float(0.0));
8987 }
8988 }
8989 else
8990 {
8991 if (face >= 0 && face < 21)
8992 {
8993 res.Add(new LSL_String(""));
8994 res.Add(new LSL_Vector(0,0,0));
8995 res.Add(new LSL_Vector(0,0,0));
8996 res.Add(new LSL_Float(0.0));
8997 }
8998 }
8999 break;
9000
9001 case (int)ScriptBaseClass.PRIM_COLOR:
9002 if (remain < 1)
9003 return res;
9004
9005 face = (int)rules.GetLSLIntegerItem(idx++);
9006
9007 if (face == ScriptBaseClass.ALL_SIDES)
9008 {
9009 for (face = 0; face < 21; face++)
9010 {
9011 res.Add(new LSL_Vector(0,0,0));
9012 res.Add(new LSL_Float(0));
9013 }
9014 }
9015 else
9016 {
9017 res.Add(new LSL_Vector(0,0,0));
9018 res.Add(new LSL_Float(0));
9019 }
9020 break;
9021
9022 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
9023 if (remain < 1)
9024 return res;
9025 face = (int)rules.GetLSLIntegerItem(idx++);
9026
9027 if (face == ScriptBaseClass.ALL_SIDES)
9028 {
9029 for (face = 0; face < 21; face++)
9030 {
9031 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
9032 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
9033 }
9034 }
9035 else
9036 {
9037 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
9038 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
9039 }
9040 break;
9041
9042 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
9043 if (remain < 1)
9044 return res;
9045 face = (int)rules.GetLSLIntegerItem(idx++);
9046
9047 if (face == ScriptBaseClass.ALL_SIDES)
9048 {
9049 for (face = 0; face < 21; face++)
9050 {
9051 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
9052 }
9053 }
9054 else
9055 {
9056 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
9057 }
9058 break;
9059
9060 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
9061 res.Add(new LSL_Integer(0));
9062 res.Add(new LSL_Integer(0));// softness
9063 res.Add(new LSL_Float(0.0f)); // gravity
9064 res.Add(new LSL_Float(0.0f)); // friction
9065 res.Add(new LSL_Float(0.0f)); // wind
9066 res.Add(new LSL_Float(0.0f)); // tension
9067 res.Add(new LSL_Vector(0f,0f,0f));
9068 break;
9069
9070 case (int)ScriptBaseClass.PRIM_TEXGEN:
9071 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
9072 if (remain < 1)
9073 return res;
9074 face = (int)rules.GetLSLIntegerItem(idx++);
9075
9076 if (face == ScriptBaseClass.ALL_SIDES)
9077 {
9078 for (face = 0; face < 21; face++)
9079 {
9080 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9081 }
9082 }
9083 else
9084 {
9085 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9086 }
9087 break;
9088
9089 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
9090 res.Add(new LSL_Integer(0));
9091 res.Add(new LSL_Vector(0f,0f,0f));
9092 res.Add(new LSL_Float(0f)); // intensity
9093 res.Add(new LSL_Float(0f)); // radius
9094 res.Add(new LSL_Float(0f)); // falloff
9095 break;
9096
9097 case (int)ScriptBaseClass.PRIM_GLOW:
9098 if (remain < 1)
9099 return res;
9100 face = (int)rules.GetLSLIntegerItem(idx++);
9101
9102 if (face == ScriptBaseClass.ALL_SIDES)
9103 {
9104 for (face = 0; face < 21; face++)
9105 {
9106 res.Add(new LSL_Float(0f));
9107 }
9108 }
9109 else
9110 {
9111 res.Add(new LSL_Float(0f));
9112 }
9113 break;
9114
9115 case (int)ScriptBaseClass.PRIM_TEXT:
9116 res.Add(new LSL_String(""));
9117 res.Add(new LSL_Vector(0f,0f,0f));
9118 res.Add(new LSL_Float(1.0f));
9119 break;
9120
9121 case (int)ScriptBaseClass.PRIM_NAME:
9122 res.Add(new LSL_String(avatar.Name));
9123 break;
9124
9125 case (int)ScriptBaseClass.PRIM_DESC:
9126 res.Add(new LSL_String(""));
9127 break;
9128
9129 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
9130 Quaternion lrot = avatar.Rotation;
9131
9132 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9133 {
9134 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
9135 }
9136 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
9137 break;
9138
9139 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
9140 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
9141 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
9142 lpos -= lsitOffset;
9143
9144 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9145 {
9146 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
9147 }
9148 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
9149 break;
9150
9151 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9152 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9153 return res;
9154 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9155 LSL_List new_rules = rules.GetSublist(idx, -1);
9156
9157 res += llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9158 return res;
9159 } 8700 }
9160 } 8701 }
8702
9161 return res; 8703 return res;
9162 } 8704 }
9163 8705
9164 public LSL_List GetLinkPrimitiveParams(SceneObjectPart part, LSL_List rules) 8706 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res)
9165 { 8707 {
9166 LSL_List res = new LSL_List();
9167 int idx=0; 8708 int idx=0;
9168 while (idx < rules.Length) 8709 while (idx < rules.Length)
9169 { 8710 {
@@ -9301,7 +8842,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9301 8842
9302 case (int)ScriptBaseClass.PRIM_TEXTURE: 8843 case (int)ScriptBaseClass.PRIM_TEXTURE:
9303 if (remain < 1) 8844 if (remain < 1)
9304 return res; 8845 return null;
9305 8846
9306 int face = (int)rules.GetLSLIntegerItem(idx++); 8847 int face = (int)rules.GetLSLIntegerItem(idx++);
9307 Primitive.TextureEntry tex = part.Shape.Textures; 8848 Primitive.TextureEntry tex = part.Shape.Textures;
@@ -9341,7 +8882,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9341 8882
9342 case (int)ScriptBaseClass.PRIM_COLOR: 8883 case (int)ScriptBaseClass.PRIM_COLOR:
9343 if (remain < 1) 8884 if (remain < 1)
9344 return res; 8885 return null;
9345 8886
9346 face=(int)rules.GetLSLIntegerItem(idx++); 8887 face=(int)rules.GetLSLIntegerItem(idx++);
9347 8888
@@ -9370,7 +8911,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9370 8911
9371 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8912 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
9372 if (remain < 1) 8913 if (remain < 1)
9373 return res; 8914 return null;
8915
9374 face = (int)rules.GetLSLIntegerItem(idx++); 8916 face = (int)rules.GetLSLIntegerItem(idx++);
9375 8917
9376 tex = part.Shape.Textures; 8918 tex = part.Shape.Textures;
@@ -9426,7 +8968,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9426 8968
9427 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8969 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
9428 if (remain < 1) 8970 if (remain < 1)
9429 return res; 8971 return null;
8972
9430 face = (int)rules.GetLSLIntegerItem(idx++); 8973 face = (int)rules.GetLSLIntegerItem(idx++);
9431 8974
9432 tex = part.Shape.Textures; 8975 tex = part.Shape.Textures;
@@ -9480,7 +9023,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9480 case (int)ScriptBaseClass.PRIM_TEXGEN: 9023 case (int)ScriptBaseClass.PRIM_TEXGEN:
9481 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) 9024 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
9482 if (remain < 1) 9025 if (remain < 1)
9483 return res; 9026 return null;
9027
9484 face = (int)rules.GetLSLIntegerItem(idx++); 9028 face = (int)rules.GetLSLIntegerItem(idx++);
9485 9029
9486 tex = part.Shape.Textures; 9030 tex = part.Shape.Textures;
@@ -9528,7 +9072,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9528 9072
9529 case (int)ScriptBaseClass.PRIM_GLOW: 9073 case (int)ScriptBaseClass.PRIM_GLOW:
9530 if (remain < 1) 9074 if (remain < 1)
9531 return res; 9075 return null;
9076
9532 face = (int)rules.GetLSLIntegerItem(idx++); 9077 face = (int)rules.GetLSLIntegerItem(idx++);
9533 9078
9534 tex = part.Shape.Textures; 9079 tex = part.Shape.Textures;
@@ -9572,18 +9117,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9572 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9117 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
9573 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9118 res.Add(new LSL_Vector(GetPartLocalPos(part)));
9574 break; 9119 break;
9575 9120 case (int)ScriptBaseClass.PRIM_SLICE:
9121 PrimType prim_type = part.GetPrimType();
9122 bool useProfileBeginEnd = (prim_type == PrimType.SPHERE || prim_type == PrimType.TORUS || prim_type == PrimType.TUBE || prim_type == PrimType.RING);
9123 res.Add(new LSL_Vector(
9124 (useProfileBeginEnd ? part.Shape.ProfileBegin : part.Shape.PathBegin) / 50000.0,
9125 1 - (useProfileBeginEnd ? part.Shape.ProfileEnd : part.Shape.PathEnd) / 50000.0,
9126 0
9127 ));
9128 break;
9576 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 9129 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9577 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. 9130 if(remain < 3)
9578 return res; 9131 return null;
9579 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++); 9132
9580 LSL_List new_rules = rules.GetSublist(idx, -1); 9133 return rules.GetSublist(idx, -1);
9581 LSL_List tres = llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9582 res += tres;
9583 return res;
9584 } 9134 }
9585 } 9135 }
9586 return res; 9136
9137 return null;
9587 } 9138 }
9588 9139
9589 public LSL_List llGetPrimMediaParams(int face, LSL_List rules) 9140 public LSL_List llGetPrimMediaParams(int face, LSL_List rules)
@@ -11166,9 +10717,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11166 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10717 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
11167 if (avatar != null) 10718 if (avatar != null)
11168 { 10719 {
11169 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, simname, 10720 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
11170 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10721 simname, pos, lookAt);
11171 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
11172 } 10722 }
11173 10723
11174 ScriptSleep(1000); 10724 ScriptSleep(1000);
@@ -11903,13 +11453,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11903 else 11453 else
11904 rot = obj.GetWorldRotation(); 11454 rot = obj.GetWorldRotation();
11905 11455
11906 LSL_Rotation objrot = new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W); 11456 LSL_Rotation objrot = new LSL_Rotation(rot);
11907 ret.Add(objrot); 11457 ret.Add(objrot);
11908 } 11458 }
11909 break; 11459 break;
11910 case ScriptBaseClass.OBJECT_VELOCITY: 11460 case ScriptBaseClass.OBJECT_VELOCITY:
11911 Vector3 ovel = obj.Velocity; 11461 ret.Add(new LSL_Vector(obj.Velocity));
11912 ret.Add(new LSL_Vector(ovel.X, ovel.Y, ovel.Z));
11913 break; 11462 break;
11914 case ScriptBaseClass.OBJECT_OWNER: 11463 case ScriptBaseClass.OBJECT_OWNER:
11915 ret.Add(new LSL_String(obj.OwnerID.ToString())); 11464 ret.Add(new LSL_String(obj.OwnerID.ToString()));
@@ -12122,7 +11671,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12122 return tid.ToString(); 11671 return tid.ToString();
12123 } 11672 }
12124 11673
12125 public void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules) 11674 public void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc)
12126 { 11675 {
12127 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim)); 11676 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim));
12128 if (obj == null) 11677 if (obj == null)
@@ -12131,28 +11680,41 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12131 if (obj.OwnerID != m_host.OwnerID) 11680 if (obj.OwnerID != m_host.OwnerID)
12132 return; 11681 return;
12133 11682
12134 LSL_List remaining = SetPrimParams(obj, rules); 11683 uint rulesParsed = 0;
11684 LSL_List remaining = SetPrimParams(obj, rules, originFunc, ref rulesParsed);
12135 11685
12136 while ((object)remaining != null && remaining.Length > 2) 11686 while ((object)remaining != null && remaining.Length > 2)
12137 { 11687 {
12138 LSL_Integer newLink = remaining.GetLSLIntegerItem(0); 11688 LSL_Integer newLink = remaining.GetLSLIntegerItem(0);
12139 LSL_List newrules = remaining.GetSublist(1, -1); 11689 LSL_List newrules = remaining.GetSublist(1, -1);
12140 foreach(SceneObjectPart part in GetLinkParts(obj, newLink)){ 11690 foreach(SceneObjectPart part in GetLinkParts(obj, newLink)){
12141 remaining = SetPrimParams(part, newrules); 11691 remaining = SetPrimParams(part, newrules, originFunc, ref rulesParsed);
12142 } 11692 }
12143 } 11693 }
12144 } 11694 }
12145 11695
12146 public LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules) 11696 public LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules)
12147 { 11697 {
12148 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim)); 11698 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim));
12149 if (obj == null)
12150 return new LSL_List();
12151 11699
12152 if (obj.OwnerID != m_host.OwnerID) 11700 LSL_List result = new LSL_List();
12153 return new LSL_List(); 11701
11702 if (obj != null && obj.OwnerID != m_host.OwnerID)
11703 {
11704 LSL_List remaining = GetPrimParams(obj, rules, ref result);
12154 11705
12155 return GetLinkPrimitiveParams(obj, rules); 11706 while (remaining != null && remaining.Length > 2)
11707 {
11708 int linknumber = remaining.GetLSLIntegerItem(0);
11709 rules = remaining.GetSublist(1, -1);
11710 List<SceneObjectPart> parts = GetLinkParts(linknumber);
11711
11712 foreach (SceneObjectPart part in parts)
11713 remaining = GetPrimParams(part, rules, ref result);
11714 }
11715 }
11716
11717 return result;
12156 } 11718 }
12157 11719
12158 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link) 11720 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
@@ -12515,8 +12077,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12515 12077
12516 m_host.AddScriptLPS(1); 12078 m_host.AddScriptLPS(1);
12517 12079
12518 Vector3 rayStart = new Vector3((float)start.x, (float)start.y, (float)start.z); 12080 Vector3 rayStart = start;
12519 Vector3 rayEnd = new Vector3((float)end.x, (float)end.y, (float)end.z); 12081 Vector3 rayEnd = end;
12520 Vector3 dir = rayEnd - rayStart; 12082 Vector3 dir = rayEnd - rayStart;
12521 12083
12522 float dist = Vector3.Mag(dir); 12084 float dist = Vector3.Mag(dir);
@@ -13090,6 +12652,455 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13090 } 12652 }
13091 } 12653 }
13092 } 12654 }
12655
12656 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12657 {
12658 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12659
12660 int idx = 0;
12661 int idxStart = 0;
12662
12663 bool positionChanged = false;
12664 Vector3 finalPos = Vector3.Zero;
12665
12666 try
12667 {
12668 while (idx < rules.Length)
12669 {
12670 ++rulesParsed;
12671 int code = rules.GetLSLIntegerItem(idx++);
12672
12673 int remain = rules.Length - idx;
12674 idxStart = idx;
12675
12676 switch (code)
12677 {
12678 case (int)ScriptBaseClass.PRIM_POSITION:
12679 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12680 {
12681 if (remain < 1)
12682 return null;
12683
12684 LSL_Vector v;
12685 v = rules.GetVector3Item(idx++);
12686
12687 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12688 if (part == null)
12689 break;
12690
12691 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12692 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12693 if (part.LinkNum > 1)
12694 {
12695 localRot = GetPartLocalRot(part);
12696 localPos = GetPartLocalPos(part);
12697 }
12698
12699 v -= localPos;
12700 v /= localRot;
12701
12702 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12703
12704 v = v + 2 * sitOffset;
12705
12706 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12707 av.SendAvatarDataToAllAgents();
12708
12709 }
12710 break;
12711
12712 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12713 case (int)ScriptBaseClass.PRIM_ROTATION:
12714 {
12715 if (remain < 1)
12716 return null;
12717
12718 LSL_Rotation r;
12719 r = rules.GetQuaternionItem(idx++);
12720
12721 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12722 if (part == null)
12723 break;
12724
12725 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12726 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12727
12728 if (part.LinkNum > 1)
12729 localRot = GetPartLocalRot(part);
12730
12731 r = r * llGetRootRotation() / localRot;
12732 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12733 av.SendAvatarDataToAllAgents();
12734 }
12735 break;
12736
12737 // parse rest doing nothing but number of parameters error check
12738 case (int)ScriptBaseClass.PRIM_SIZE:
12739 case (int)ScriptBaseClass.PRIM_MATERIAL:
12740 case (int)ScriptBaseClass.PRIM_PHANTOM:
12741 case (int)ScriptBaseClass.PRIM_PHYSICS:
12742 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12743 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12744 case (int)ScriptBaseClass.PRIM_NAME:
12745 case (int)ScriptBaseClass.PRIM_DESC:
12746 if (remain < 1)
12747 return null;
12748 idx++;
12749 break;
12750
12751 case (int)ScriptBaseClass.PRIM_GLOW:
12752 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12753 case (int)ScriptBaseClass.PRIM_TEXGEN:
12754 if (remain < 2)
12755 return null;
12756 idx += 2;
12757 break;
12758
12759 case (int)ScriptBaseClass.PRIM_TYPE:
12760 if (remain < 3)
12761 return null;
12762 code = (int)rules.GetLSLIntegerItem(idx++);
12763 remain = rules.Length - idx;
12764 switch (code)
12765 {
12766 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12767 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12768 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12769 if (remain < 6)
12770 return null;
12771 idx += 6;
12772 break;
12773
12774 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12775 if (remain < 5)
12776 return null;
12777 idx += 5;
12778 break;
12779
12780 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12781 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12782 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12783 if (remain < 11)
12784 return null;
12785 idx += 11;
12786 break;
12787
12788 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12789 if (remain < 2)
12790 return null;
12791 idx += 2;
12792 break;
12793 }
12794 break;
12795
12796 case (int)ScriptBaseClass.PRIM_COLOR:
12797 case (int)ScriptBaseClass.PRIM_TEXT:
12798 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12799 case (int)ScriptBaseClass.PRIM_OMEGA:
12800 if (remain < 3)
12801 return null;
12802 idx += 3;
12803 break;
12804
12805 case (int)ScriptBaseClass.PRIM_TEXTURE:
12806 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12807 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12808 if (remain < 5)
12809 return null;
12810 idx += 5;
12811 break;
12812
12813 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12814 if (remain < 7)
12815 return null;
12816
12817 idx += 7;
12818 break;
12819
12820 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12821 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12822 return null;
12823
12824 return rules.GetSublist(idx, -1);
12825 }
12826 }
12827 }
12828 catch (InvalidCastException e)
12829 {
12830 ShoutError(string.Format(
12831 "{0} error running rule #{1}: arg #{2} ",
12832 originFunc, rulesParsed, idx - idxStart) + e.Message);
12833 }
12834 finally
12835 {
12836 if (positionChanged)
12837 {
12838 av.OffsetPosition = finalPos;
12839// av.SendAvatarDataToAllAgents();
12840 av.SendTerseUpdateToAllClients();
12841 positionChanged = false;
12842 }
12843 }
12844 return null;
12845 }
12846
12847 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
12848 {
12849 // avatars case
12850 // replies as SL wiki
12851
12852// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
12853 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
12854
12855 int idx = 0;
12856 while (idx < rules.Length)
12857 {
12858 int code = (int)rules.GetLSLIntegerItem(idx++);
12859 int remain = rules.Length - idx;
12860
12861 switch (code)
12862 {
12863 case (int)ScriptBaseClass.PRIM_MATERIAL:
12864 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
12865 break;
12866
12867 case (int)ScriptBaseClass.PRIM_PHYSICS:
12868 res.Add(new LSL_Integer(0));
12869 break;
12870
12871 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12872 res.Add(new LSL_Integer(0));
12873 break;
12874
12875 case (int)ScriptBaseClass.PRIM_PHANTOM:
12876 res.Add(new LSL_Integer(0));
12877 break;
12878
12879 case (int)ScriptBaseClass.PRIM_POSITION:
12880
12881 Vector3 pos = avatar.OffsetPosition;
12882
12883 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
12884 pos -= sitOffset;
12885
12886 if( sitPart != null)
12887 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
12888
12889 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
12890 break;
12891
12892 case (int)ScriptBaseClass.PRIM_SIZE:
12893 // as in llGetAgentSize above
12894 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
12895 break;
12896
12897 case (int)ScriptBaseClass.PRIM_ROTATION:
12898 Quaternion rot = avatar.Rotation;
12899 if (sitPart != null)
12900 {
12901 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
12902 }
12903
12904 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
12905 break;
12906
12907 case (int)ScriptBaseClass.PRIM_TYPE:
12908 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
12909 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
12910 res.Add(new LSL_Vector(0f,1.0f,0f));
12911 res.Add(new LSL_Float(0.0f));
12912 res.Add(new LSL_Vector(0, 0, 0));
12913 res.Add(new LSL_Vector(1.0f,1.0f,0f));
12914 res.Add(new LSL_Vector(0, 0, 0));
12915 break;
12916
12917 case (int)ScriptBaseClass.PRIM_TEXTURE:
12918 if (remain < 1)
12919 return null;
12920
12921 int face = (int)rules.GetLSLIntegerItem(idx++);
12922 if (face == ScriptBaseClass.ALL_SIDES)
12923 {
12924 for (face = 0; face < 21; face++)
12925 {
12926 res.Add(new LSL_String(""));
12927 res.Add(new LSL_Vector(0,0,0));
12928 res.Add(new LSL_Vector(0,0,0));
12929 res.Add(new LSL_Float(0.0));
12930 }
12931 }
12932 else
12933 {
12934 if (face >= 0 && face < 21)
12935 {
12936 res.Add(new LSL_String(""));
12937 res.Add(new LSL_Vector(0,0,0));
12938 res.Add(new LSL_Vector(0,0,0));
12939 res.Add(new LSL_Float(0.0));
12940 }
12941 }
12942 break;
12943
12944 case (int)ScriptBaseClass.PRIM_COLOR:
12945 if (remain < 1)
12946 return null;
12947
12948 face = (int)rules.GetLSLIntegerItem(idx++);
12949
12950 if (face == ScriptBaseClass.ALL_SIDES)
12951 {
12952 for (face = 0; face < 21; face++)
12953 {
12954 res.Add(new LSL_Vector(0,0,0));
12955 res.Add(new LSL_Float(0));
12956 }
12957 }
12958 else
12959 {
12960 res.Add(new LSL_Vector(0,0,0));
12961 res.Add(new LSL_Float(0));
12962 }
12963 break;
12964
12965 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12966 if (remain < 1)
12967 return null;
12968 face = (int)rules.GetLSLIntegerItem(idx++);
12969
12970 if (face == ScriptBaseClass.ALL_SIDES)
12971 {
12972 for (face = 0; face < 21; face++)
12973 {
12974 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12975 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12976 }
12977 }
12978 else
12979 {
12980 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12981 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12982 }
12983 break;
12984
12985 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12986 if (remain < 1)
12987 return null;
12988 face = (int)rules.GetLSLIntegerItem(idx++);
12989
12990 if (face == ScriptBaseClass.ALL_SIDES)
12991 {
12992 for (face = 0; face < 21; face++)
12993 {
12994 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
12995 }
12996 }
12997 else
12998 {
12999 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13000 }
13001 break;
13002
13003 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13004 res.Add(new LSL_Integer(0));
13005 res.Add(new LSL_Integer(0));// softness
13006 res.Add(new LSL_Float(0.0f)); // gravity
13007 res.Add(new LSL_Float(0.0f)); // friction
13008 res.Add(new LSL_Float(0.0f)); // wind
13009 res.Add(new LSL_Float(0.0f)); // tension
13010 res.Add(new LSL_Vector(0f,0f,0f));
13011 break;
13012
13013 case (int)ScriptBaseClass.PRIM_TEXGEN:
13014 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13015 if (remain < 1)
13016 return null;
13017 face = (int)rules.GetLSLIntegerItem(idx++);
13018
13019 if (face == ScriptBaseClass.ALL_SIDES)
13020 {
13021 for (face = 0; face < 21; face++)
13022 {
13023 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13024 }
13025 }
13026 else
13027 {
13028 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13029 }
13030 break;
13031
13032 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13033 res.Add(new LSL_Integer(0));
13034 res.Add(new LSL_Vector(0f,0f,0f));
13035 res.Add(new LSL_Float(0f)); // intensity
13036 res.Add(new LSL_Float(0f)); // radius
13037 res.Add(new LSL_Float(0f)); // falloff
13038 break;
13039
13040 case (int)ScriptBaseClass.PRIM_GLOW:
13041 if (remain < 1)
13042 return null;
13043 face = (int)rules.GetLSLIntegerItem(idx++);
13044
13045 if (face == ScriptBaseClass.ALL_SIDES)
13046 {
13047 for (face = 0; face < 21; face++)
13048 {
13049 res.Add(new LSL_Float(0f));
13050 }
13051 }
13052 else
13053 {
13054 res.Add(new LSL_Float(0f));
13055 }
13056 break;
13057
13058 case (int)ScriptBaseClass.PRIM_TEXT:
13059 res.Add(new LSL_String(""));
13060 res.Add(new LSL_Vector(0f,0f,0f));
13061 res.Add(new LSL_Float(1.0f));
13062 break;
13063
13064 case (int)ScriptBaseClass.PRIM_NAME:
13065 res.Add(new LSL_String(avatar.Name));
13066 break;
13067
13068 case (int)ScriptBaseClass.PRIM_DESC:
13069 res.Add(new LSL_String(""));
13070 break;
13071
13072 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13073 Quaternion lrot = avatar.Rotation;
13074
13075 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13076 {
13077 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13078 }
13079 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13080 break;
13081
13082 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13083 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13084 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13085 lpos -= lsitOffset;
13086
13087 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13088 {
13089 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13090 }
13091 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13092 break;
13093
13094 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13095 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13096 return null;
13097
13098 return rules.GetSublist(idx, -1);
13099 }
13100 }
13101
13102 return null;
13103 }
13093 } 13104 }
13094 13105
13095 public class NotecardCache 13106 public class NotecardCache
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
index 795de80..ceb4660 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
@@ -304,7 +304,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
304 case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: 304 case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY:
305 idx++; 305 idx++;
306 iV = rules.GetVector3Item(idx); 306 iV = rules.GetVector3Item(idx);
307 wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); 307 wl.cloudDetailXYDensity = iV;
308 break; 308 break;
309 case (int)ScriptBaseClass.WL_CLOUD_SCALE: 309 case (int)ScriptBaseClass.WL_CLOUD_SCALE:
310 idx++; 310 idx++;
@@ -329,7 +329,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
329 case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: 329 case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY:
330 idx++; 330 idx++;
331 iV = rules.GetVector3Item(idx); 331 iV = rules.GetVector3Item(idx);
332 wl.cloudXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); 332 wl.cloudXYDensity = iV;
333 break; 333 break;
334 case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: 334 case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER:
335 idx++; 335 idx++;
@@ -384,7 +384,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
384 case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: 384 case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE:
385 idx++; 385 idx++;
386 iV = rules.GetVector3Item(idx); 386 iV = rules.GetVector3Item(idx);
387 wl.reflectionWaveletScale = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); 387 wl.reflectionWaveletScale = iV;
388 break; 388 break;
389 case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: 389 case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE:
390 idx++; 390 idx++;
@@ -422,7 +422,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
422 case (int)ScriptBaseClass.WL_WATER_COLOR: 422 case (int)ScriptBaseClass.WL_WATER_COLOR:
423 idx++; 423 idx++;
424 iV = rules.GetVector3Item(idx); 424 iV = rules.GetVector3Item(idx);
425 wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); 425 wl.waterColor = iV;
426 break; 426 break;
427 case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: 427 case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT:
428 idx++; 428 idx++;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
index 7844c75..84cf6ca 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
@@ -333,8 +333,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
333 { 333 {
334 if (type == typeof(OpenMetaverse.Quaternion)) 334 if (type == typeof(OpenMetaverse.Quaternion))
335 { 335 {
336 LSL_Rotation rot = (LSL_Rotation)lslparm; 336 return (OpenMetaverse.Quaternion)((LSL_Rotation)lslparm);
337 return new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s);
338 } 337 }
339 } 338 }
340 339
@@ -343,8 +342,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
343 { 342 {
344 if (type == typeof(OpenMetaverse.Vector3)) 343 if (type == typeof(OpenMetaverse.Vector3))
345 { 344 {
346 LSL_Vector vect = (LSL_Vector)lslparm; 345 return (OpenMetaverse.Vector3)((LSL_Vector)lslparm);
347 return new OpenMetaverse.Vector3((float)vect.x,(float)vect.y,(float)vect.z);
348 } 346 }
349 } 347 }
350 348
@@ -367,13 +365,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
367 result[i] = new UUID((LSL_Key)plist[i]); 365 result[i] = new UUID((LSL_Key)plist[i]);
368 else if (plist[i] is LSL_Rotation) 366 else if (plist[i] is LSL_Rotation)
369 { 367 {
370 LSL_Rotation rot = (LSL_Rotation)plist[i]; 368 result[i] = (OpenMetaverse.Quaternion)(
371 result[i] = new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s); 369 (LSL_Rotation)plist[i]);
372 } 370 }
373 else if (plist[i] is LSL_Vector) 371 else if (plist[i] is LSL_Vector)
374 { 372 {
375 LSL_Vector vect = (LSL_Vector)plist[i]; 373 result[i] = (OpenMetaverse.Vector3)(
376 result[i] = new OpenMetaverse.Vector3((float)vect.x,(float)vect.y,(float)vect.z); 374 (LSL_Vector)plist[i]);
377 } 375 }
378 else 376 else
379 MODError("unknown LSL list element type"); 377 MODError("unknown LSL list element type");
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 2f02f1f..ceff889 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -782,10 +782,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
782 782
783 // We will launch the teleport on a new thread so that when the script threads are terminated 783 // We will launch the teleport on a new thread so that when the script threads are terminated
784 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting. 784 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.
785 Util.FireAndForget( 785 Util.FireAndForget(o => World.RequestTeleportLocation(
786 o => World.RequestTeleportLocation(presence.ControllingClient, regionName, 786 presence.ControllingClient, regionName, position,
787 new Vector3((float)position.x, (float)position.y, (float)position.z), 787 lookat, (uint)TPFlags.ViaLocation));
788 new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation));
789 788
790 ScriptSleep(5000); 789 ScriptSleep(5000);
791 790
@@ -828,10 +827,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
828 827
829 // We will launch the teleport on a new thread so that when the script threads are terminated 828 // We will launch the teleport on a new thread so that when the script threads are terminated
830 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting. 829 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.
831 Util.FireAndForget( 830 Util.FireAndForget(o => World.RequestTeleportLocation(
832 o => World.RequestTeleportLocation(presence.ControllingClient, regionHandle, 831 presence.ControllingClient, regionHandle,
833 new Vector3((float)position.x, (float)position.y, (float)position.z), 832 position, lookat, (uint)TPFlags.ViaLocation));
834 new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation));
835 833
836 ScriptSleep(5000); 834 ScriptSleep(5000);
837 835
@@ -2259,11 +2257,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2259 CheckThreatLevel(ThreatLevel.High, "osGetLinkPrimitiveParams"); 2257 CheckThreatLevel(ThreatLevel.High, "osGetLinkPrimitiveParams");
2260 m_host.AddScriptLPS(1); 2258 m_host.AddScriptLPS(1);
2261 InitLSL(); 2259 InitLSL();
2260 // One needs to cast m_LSL_Api because we're using functions not
2261 // on the ILSL_Api interface.
2262 LSL_Api LSL_Api = (LSL_Api)m_LSL_Api;
2262 LSL_List retVal = new LSL_List(); 2263 LSL_List retVal = new LSL_List();
2263 List<SceneObjectPart> parts = ((LSL_Api)m_LSL_Api).GetLinkParts(linknumber); 2264 LSL_List remaining = null;
2265 List<SceneObjectPart> parts = LSL_Api.GetLinkParts(linknumber);
2264 foreach (SceneObjectPart part in parts) 2266 foreach (SceneObjectPart part in parts)
2265 { 2267 {
2266 retVal += ((LSL_Api)m_LSL_Api).GetLinkPrimitiveParams(part, rules); 2268 remaining = LSL_Api.GetPrimParams(part, rules, ref retVal);
2269 }
2270
2271 while (remaining != null && remaining.Length > 2)
2272 {
2273 linknumber = remaining.GetLSLIntegerItem(0);
2274 rules = remaining.GetSublist(1, -1);
2275 parts = LSL_Api.GetLinkParts(linknumber);
2276
2277 foreach (SceneObjectPart part in parts)
2278 remaining = LSL_Api.GetPrimParams(part, rules, ref retVal);
2267 } 2279 }
2268 return retVal; 2280 return retVal;
2269 } 2281 }
@@ -2355,7 +2367,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2355 ownerID = m_host.OwnerID; 2367 ownerID = m_host.OwnerID;
2356 UUID x = module.CreateNPC(firstname, 2368 UUID x = module.CreateNPC(firstname,
2357 lastname, 2369 lastname,
2358 new Vector3((float) position.x, (float) position.y, (float) position.z), 2370 position,
2359 ownerID, 2371 ownerID,
2360 senseAsAgent, 2372 senseAsAgent,
2361 World, 2373 World,
@@ -2478,7 +2490,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2478 return new LSL_Vector(0, 0, 0); 2490 return new LSL_Vector(0, 0, 0);
2479 } 2491 }
2480 2492
2481 public void osNpcMoveTo(LSL_Key npc, LSL_Vector position) 2493 public void osNpcMoveTo(LSL_Key npc, LSL_Vector pos)
2482 { 2494 {
2483 CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo"); 2495 CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo");
2484 m_host.AddScriptLPS(1); 2496 m_host.AddScriptLPS(1);
@@ -2493,7 +2505,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2493 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2505 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2494 return; 2506 return;
2495 2507
2496 Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z);
2497 module.MoveToTarget(npcId, World, pos, false, true, false); 2508 module.MoveToTarget(npcId, World, pos, false, true, false);
2498 } 2509 }
2499 } 2510 }
@@ -2513,11 +2524,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2513 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2524 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2514 return; 2525 return;
2515 2526
2516 Vector3 pos = new Vector3((float)target.x, (float)target.y, (float)target.z);
2517 module.MoveToTarget( 2527 module.MoveToTarget(
2518 new UUID(npc.m_string), 2528 new UUID(npc.m_string),
2519 World, 2529 World,
2520 pos, 2530 target,
2521 (options & ScriptBaseClass.OS_NPC_NO_FLY) != 0, 2531 (options & ScriptBaseClass.OS_NPC_NO_FLY) != 0,
2522 (options & ScriptBaseClass.OS_NPC_LAND_AT_TARGET) != 0, 2532 (options & ScriptBaseClass.OS_NPC_LAND_AT_TARGET) != 0,
2523 (options & ScriptBaseClass.OS_NPC_RUNNING) != 0); 2533 (options & ScriptBaseClass.OS_NPC_RUNNING) != 0);
@@ -2569,7 +2579,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2569 ScenePresence sp = World.GetScenePresence(npcId); 2579 ScenePresence sp = World.GetScenePresence(npcId);
2570 2580
2571 if (sp != null) 2581 if (sp != null)
2572 sp.Rotation = LSL_Api.Rot2Quaternion(rotation); 2582 sp.Rotation = rotation;
2573 } 2583 }
2574 } 2584 }
2575 2585
@@ -2929,7 +2939,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2929 avatar.SpeedModifier = (float)SpeedModifier; 2939 avatar.SpeedModifier = (float)SpeedModifier;
2930 } 2940 }
2931 2941
2932 public void osKickAvatar(string FirstName,string SurName,string alert) 2942 public void osKickAvatar(string FirstName, string SurName, string alert)
2933 { 2943 {
2934 CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar"); 2944 CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar");
2935 m_host.AddScriptLPS(1); 2945 m_host.AddScriptLPS(1);
@@ -2943,10 +2953,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2943 sp.ControllingClient.Kick(alert); 2953 sp.ControllingClient.Kick(alert);
2944 2954
2945 // ...and close on our side 2955 // ...and close on our side
2946 sp.Scene.IncomingCloseAgent(sp.UUID); 2956 sp.Scene.IncomingCloseAgent(sp.UUID, false);
2947 } 2957 }
2948 }); 2958 });
2949 } 2959 }
2960
2961 public LSL_Float osGetHealth(string avatar)
2962 {
2963 CheckThreatLevel(ThreatLevel.None, "osGetHealth");
2964 m_host.AddScriptLPS(1);
2965
2966 LSL_Float health = new LSL_Float(-1);
2967 ScenePresence presence = World.GetScenePresence(new UUID(avatar));
2968 if (presence != null) health = presence.Health;
2969 return health;
2970 }
2950 2971
2951 public void osCauseDamage(string avatar, double damage) 2972 public void osCauseDamage(string avatar, double damage)
2952 { 2973 {
@@ -3006,7 +3027,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3006 m_host.AddScriptLPS(1); 3027 m_host.AddScriptLPS(1);
3007 InitLSL(); 3028 InitLSL();
3008 3029
3009 return m_LSL_Api.GetLinkPrimitiveParamsEx(prim, rules); 3030 return m_LSL_Api.GetPrimitiveParamsEx(prim, rules);
3010 } 3031 }
3011 3032
3012 public void osSetPrimitiveParams(LSL_Key prim, LSL_List rules) 3033 public void osSetPrimitiveParams(LSL_Key prim, LSL_List rules)
@@ -3015,7 +3036,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3015 m_host.AddScriptLPS(1); 3036 m_host.AddScriptLPS(1);
3016 InitLSL(); 3037 InitLSL();
3017 3038
3018 m_LSL_Api.SetPrimitiveParamsEx(prim, rules); 3039 m_LSL_Api.SetPrimitiveParamsEx(prim, rules, "osSetPrimitiveParams");
3019 } 3040 }
3020 3041
3021 /// <summary> 3042 /// <summary>
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 678f9d5..4dd795d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -352,7 +352,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
352 q = avatar.Rotation; 352 q = avatar.Rotation;
353 } 353 }
354 354
355 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 355 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
356 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); 356 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
357 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); 357 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
358 358
@@ -429,9 +429,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
429 try 429 try
430 { 430 {
431 Vector3 diff = toRegionPos - fromRegionPos; 431 Vector3 diff = toRegionPos - fromRegionPos;
432 LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(diff.X, diff.Y, diff.Z); 432 double dot = LSL_Types.Vector3.Dot(forward_dir, diff);
433 double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir); 433 double mag_obj = LSL_Types.Vector3.Mag(diff);
434 double mag_obj = LSL_Types.Vector3.Mag(obj_dir);
435 ang_obj = Math.Acos(dot / (mag_fwd * mag_obj)); 434 ang_obj = Math.Acos(dot / (mag_fwd * mag_obj));
436 } 435 }
437 catch 436 catch
@@ -483,7 +482,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
483 q = avatar.Rotation; 482 q = avatar.Rotation;
484 } 483 }
485 484
486 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 485 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
487 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); 486 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
488 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); 487 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
489 bool attached = (SensePoint.ParentGroup.AttachmentPoint != 0); 488 bool attached = (SensePoint.ParentGroup.AttachmentPoint != 0);
@@ -564,8 +563,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
564 double ang_obj = 0; 563 double ang_obj = 0;
565 try 564 try
566 { 565 {
567 Vector3 diff = toRegionPos - fromRegionPos; 566 LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(
568 LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(diff.X, diff.Y, diff.Z); 567 toRegionPos - fromRegionPos);
569 double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir); 568 double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir);
570 double mag_obj = LSL_Types.Vector3.Mag(obj_dir); 569 double mag_obj = LSL_Types.Vector3.Mag(obj_dir);
571 ang_obj = Math.Acos(dot / (mag_fwd * mag_obj)); 570 ang_obj = Math.Acos(dot / (mag_fwd * mag_obj));
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index af35258..05c20f9 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -429,8 +429,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
429 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link); 429 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
430 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density); 430 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
431 431
432 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 432 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc);
433 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
434 void llSetKeyframedMotion(LSL_List frames, LSL_List options); 433 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
434 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
435 } 435 }
436} 436}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 8c34ed3..d0e041c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -40,16 +40,75 @@ using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
40 40
41namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces 41namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
42{ 42{
43 /// <summary>
44 /// To permit region owners to enable the extended scripting functionality
45 /// of OSSL, without allowing malicious scripts to access potentially
46 /// troublesome functions, each OSSL function is assigned a threat level,
47 /// and access to the functions is granted or denied based on a default
48 /// threshold set in OpenSim.ini (which can be overridden for individual
49 /// functions on a case-by-case basis)
50 /// </summary>
43 public enum ThreatLevel 51 public enum ThreatLevel
44 { 52 {
53 // Not documented, presumably means permanently disabled ?
45 NoAccess = -1, 54 NoAccess = -1,
55
56 /// <summary>
57 /// Function is no threat at all. It doesn't constitute a threat to
58 /// either users or the system and has no known side effects.
59 /// </summary>
46 None = 0, 60 None = 0,
61
62 /// <summary>
63 /// Abuse of this command can cause a nuisance to the region operator,
64 /// such as log message spew.
65 /// </summary>
47 Nuisance = 1, 66 Nuisance = 1,
67
68 /// <summary>
69 /// Extreme levels of abuse of this function can cause impaired
70 /// functioning of the region, or very gullible users can be tricked
71 /// into experiencing harmless effects.
72 /// </summary>
48 VeryLow = 2, 73 VeryLow = 2,
74
75 /// <summary>
76 /// Intentional abuse can cause crashes or malfunction under certain
77 /// circumstances, which can be easily rectified; or certain users can
78 /// be tricked into certain situations in an avoidable manner.
79 /// </summary>
49 Low = 3, 80 Low = 3,
81
82 /// <summary>
83 /// Intentional abuse can cause denial of service and crashes with
84 /// potential of data or state loss; or trusting users can be tricked
85 /// into embarrassing or uncomfortable situations.
86 /// </summary>
50 Moderate = 4, 87 Moderate = 4,
88
89 /// <summary>
90 /// Casual abuse can cause impaired functionality or temporary denial
91 /// of service conditions. Intentional abuse can easily cause crashes
92 /// with potential data loss, or can be used to trick experienced and
93 /// cautious users into unwanted situations, or changes global data
94 /// permanently and without undo ability.
95 /// </summary>
51 High = 5, 96 High = 5,
97
98 /// <summary>
99 /// Even normal use may, depending on the number of instances, or
100 /// frequency of use, result in severe service impairment or crash
101 /// with loss of data, or can be used to cause unwanted or harmful
102 /// effects on users without giving the user a means to avoid it.
103 /// </summary>
52 VeryHigh = 6, 104 VeryHigh = 6,
105
106 /// <summary>
107 /// Even casual use is a danger to region stability, or function allows
108 /// console or OS command execution, or function allows taking money
109 /// without consent, or allows deletion or modification of user data,
110 /// or allows the compromise of sensitive data by design.
111 /// </summary>
53 Severe = 7 112 Severe = 7
54 }; 113 };
55 114
@@ -258,6 +317,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
258 int osGetSimulatorMemory(); 317 int osGetSimulatorMemory();
259 void osKickAvatar(string FirstName,string SurName,string alert); 318 void osKickAvatar(string FirstName,string SurName,string alert);
260 void osSetSpeed(string UUID, LSL_Float SpeedModifier); 319 void osSetSpeed(string UUID, LSL_Float SpeedModifier);
320 LSL_Float osGetHealth(string avatar);
261 void osCauseHealing(string avatar, double healing); 321 void osCauseHealing(string avatar, double healing);
262 void osCauseDamage(string avatar, double damage); 322 void osCauseDamage(string avatar, double damage);
263 LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules); 323 LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index f989cc6..05ba222 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -329,6 +329,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
329 public const int PRIM_OMEGA = 32; 329 public const int PRIM_OMEGA = 32;
330 public const int PRIM_POS_LOCAL = 33; 330 public const int PRIM_POS_LOCAL = 33;
331 public const int PRIM_LINK_TARGET = 34; 331 public const int PRIM_LINK_TARGET = 34;
332 public const int PRIM_SLICE = 35;
332 public const int PRIM_TEXGEN_DEFAULT = 0; 333 public const int PRIM_TEXGEN_DEFAULT = 0;
333 public const int PRIM_TEXGEN_PLANAR = 1; 334 public const int PRIM_TEXGEN_PLANAR = 1;
334 335
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index 94405d2..e9131e4 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -865,7 +865,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
865 { 865 {
866 m_OSSL_Functions.osSetSpeed(UUID, SpeedModifier); 866 m_OSSL_Functions.osSetSpeed(UUID, SpeedModifier);
867 } 867 }
868 868
869 public LSL_Float osGetHealth(string avatar)
870 {
871 return m_OSSL_Functions.osGetHealth(avatar);
872 }
873
869 public void osCauseDamage(string avatar, double damage) 874 public void osCauseDamage(string avatar, double damage)
870 { 875 {
871 m_OSSL_Functions.osCauseDamage(avatar, damage); 876 m_OSSL_Functions.osCauseDamage(avatar, damage);
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
index 17a0d69..03be2ab 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
@@ -546,6 +546,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
546 "OpenSim.Region.ScriptEngine.Shared.dll")); 546 "OpenSim.Region.ScriptEngine.Shared.dll"));
547 parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, 547 parameters.ReferencedAssemblies.Add(Path.Combine(rootPath,
548 "OpenSim.Region.ScriptEngine.Shared.Api.Runtime.dll")); 548 "OpenSim.Region.ScriptEngine.Shared.Api.Runtime.dll"));
549 parameters.ReferencedAssemblies.Add(Path.Combine(rootPath,
550 "OpenMetaverseTypes.dll"));
549 551
550 if (lang == enumCompileType.yp) 552 if (lang == enumCompileType.yp)
551 { 553 {
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index 9e5fb24..22804f5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -164,11 +164,11 @@ namespace OpenSim.Region.ScriptEngine.Shared
164 else 164 else
165 { 165 {
166 // Set the values from the touch data provided by the client 166 // Set the values from the touch data provided by the client
167 touchST = new LSL_Types.Vector3(value.STCoord.X, value.STCoord.Y, value.STCoord.Z); 167 touchST = new LSL_Types.Vector3(value.STCoord);
168 touchUV = new LSL_Types.Vector3(value.UVCoord.X, value.UVCoord.Y, value.UVCoord.Z); 168 touchUV = new LSL_Types.Vector3(value.UVCoord);
169 touchNormal = new LSL_Types.Vector3(value.Normal.X, value.Normal.Y, value.Normal.Z); 169 touchNormal = new LSL_Types.Vector3(value.Normal);
170 touchBinormal = new LSL_Types.Vector3(value.Binormal.X, value.Binormal.Y, value.Binormal.Z); 170 touchBinormal = new LSL_Types.Vector3(value.Binormal);
171 touchPos = new LSL_Types.Vector3(value.Position.X, value.Position.Y, value.Position.Z); 171 touchPos = new LSL_Types.Vector3(value.Position);
172 touchFace = value.FaceIndex; 172 touchFace = value.FaceIndex;
173 } 173 }
174 } 174 }
@@ -189,19 +189,13 @@ namespace OpenSim.Region.ScriptEngine.Shared
189 Country = account.UserCountry; 189 Country = account.UserCountry;
190 190
191 Owner = Key; 191 Owner = Key;
192 Position = new LSL_Types.Vector3( 192 Position = new LSL_Types.Vector3(presence.AbsolutePosition);
193 presence.AbsolutePosition.X,
194 presence.AbsolutePosition.Y,
195 presence.AbsolutePosition.Z);
196 Rotation = new LSL_Types.Quaternion( 193 Rotation = new LSL_Types.Quaternion(
197 presence.Rotation.X, 194 presence.Rotation.X,
198 presence.Rotation.Y, 195 presence.Rotation.Y,
199 presence.Rotation.Z, 196 presence.Rotation.Z,
200 presence.Rotation.W); 197 presence.Rotation.W);
201 Velocity = new LSL_Types.Vector3( 198 Velocity = new LSL_Types.Vector3(presence.Velocity);
202 presence.Velocity.X,
203 presence.Velocity.Y,
204 presence.Velocity.Z);
205 199
206 Type = 0x01; // Avatar 200 Type = 0x01; // Avatar
207 if (presence.PresenceType == PresenceType.Npc) 201 if (presence.PresenceType == PresenceType.Npc)
@@ -254,16 +248,12 @@ namespace OpenSim.Region.ScriptEngine.Shared
254 } 248 }
255 } 249 }
256 250
257 Position = new LSL_Types.Vector3(part.AbsolutePosition.X, 251 Position = new LSL_Types.Vector3(part.AbsolutePosition);
258 part.AbsolutePosition.Y,
259 part.AbsolutePosition.Z);
260 252
261 Quaternion wr = part.ParentGroup.GroupRotation; 253 Quaternion wr = part.ParentGroup.GroupRotation;
262 Rotation = new LSL_Types.Quaternion(wr.X, wr.Y, wr.Z, wr.W); 254 Rotation = new LSL_Types.Quaternion(wr.X, wr.Y, wr.Z, wr.W);
263 255
264 Velocity = new LSL_Types.Vector3(part.Velocity.X, 256 Velocity = new LSL_Types.Vector3(part.Velocity);
265 part.Velocity.Y,
266 part.Velocity.Z);
267 } 257 }
268 } 258 }
269 259
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index 8adf4c5..c9c4753 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -31,6 +31,11 @@ using System.Globalization;
31using System.Text.RegularExpressions; 31using System.Text.RegularExpressions;
32using OpenSim.Framework; 32using OpenSim.Framework;
33 33
34using OpenMetaverse;
35using OMV_Vector3 = OpenMetaverse.Vector3;
36using OMV_Vector3d = OpenMetaverse.Vector3d;
37using OMV_Quaternion = OpenMetaverse.Quaternion;
38
34namespace OpenSim.Region.ScriptEngine.Shared 39namespace OpenSim.Region.ScriptEngine.Shared
35{ 40{
36 [Serializable] 41 [Serializable]
@@ -54,6 +59,20 @@ namespace OpenSim.Region.ScriptEngine.Shared
54 z = (float)vector.z; 59 z = (float)vector.z;
55 } 60 }
56 61
62 public Vector3(OMV_Vector3 vector)
63 {
64 x = vector.X;
65 y = vector.Y;
66 z = vector.Z;
67 }
68
69 public Vector3(OMV_Vector3d vector)
70 {
71 x = vector.X;
72 y = vector.Y;
73 z = vector.Z;
74 }
75
57 public Vector3(double X, double Y, double Z) 76 public Vector3(double X, double Y, double Z)
58 { 77 {
59 x = X; 78 x = X;
@@ -109,6 +128,26 @@ namespace OpenSim.Region.ScriptEngine.Shared
109 return new list(new object[] { vec }); 128 return new list(new object[] { vec });
110 } 129 }
111 130
131 public static implicit operator OMV_Vector3(Vector3 vec)
132 {
133 return new OMV_Vector3((float)vec.x, (float)vec.y, (float)vec.z);
134 }
135
136 public static implicit operator Vector3(OMV_Vector3 vec)
137 {
138 return new Vector3(vec);
139 }
140
141 public static implicit operator OMV_Vector3d(Vector3 vec)
142 {
143 return new OMV_Vector3d(vec.x, vec.y, vec.z);
144 }
145
146 public static implicit operator Vector3(OMV_Vector3d vec)
147 {
148 return new Vector3(vec);
149 }
150
112 public static bool operator ==(Vector3 lhs, Vector3 rhs) 151 public static bool operator ==(Vector3 lhs, Vector3 rhs)
113 { 152 {
114 return (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z); 153 return (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z);
@@ -322,6 +361,14 @@ namespace OpenSim.Region.ScriptEngine.Shared
322 s = 1; 361 s = 1;
323 } 362 }
324 363
364 public Quaternion(OMV_Quaternion rot)
365 {
366 x = rot.X;
367 y = rot.Y;
368 z = rot.Z;
369 s = rot.W;
370 }
371
325 #endregion 372 #endregion
326 373
327 #region Overriders 374 #region Overriders
@@ -368,6 +415,21 @@ namespace OpenSim.Region.ScriptEngine.Shared
368 return new list(new object[] { r }); 415 return new list(new object[] { r });
369 } 416 }
370 417
418 public static implicit operator OMV_Quaternion(Quaternion rot)
419 {
420 // LSL quaternions can normalize to 0, normal Quaternions can't.
421 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
422 rot.z = 1; // ZERO_ROTATION = 0,0,0,1
423 OMV_Quaternion omvrot = new OMV_Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
424 omvrot.Normalize();
425 return omvrot;
426 }
427
428 public static implicit operator Quaternion(OMV_Quaternion rot)
429 {
430 return new Quaternion(rot);
431 }
432
371 public static bool operator ==(Quaternion lhs, Quaternion rhs) 433 public static bool operator ==(Quaternion lhs, Quaternion rhs)
372 { 434 {
373 // Return true if the fields match: 435 // Return true if the fields match:
@@ -562,12 +624,23 @@ namespace OpenSim.Region.ScriptEngine.Shared
562 else if (m_data[itemIndex] is LSL_Types.LSLString) 624 else if (m_data[itemIndex] is LSL_Types.LSLString)
563 return new LSLInteger(m_data[itemIndex].ToString()); 625 return new LSLInteger(m_data[itemIndex].ToString());
564 else 626 else
565 throw new InvalidCastException(); 627 throw new InvalidCastException(string.Format(
628 "{0} expected but {1} given",
629 typeof(LSL_Types.LSLInteger).Name,
630 m_data[itemIndex] != null ?
631 m_data[itemIndex].GetType().Name : "null"));
566 } 632 }
567 633
568 public LSL_Types.Vector3 GetVector3Item(int itemIndex) 634 public LSL_Types.Vector3 GetVector3Item(int itemIndex)
569 { 635 {
570 return (LSL_Types.Vector3)m_data[itemIndex]; 636 if(m_data[itemIndex] is LSL_Types.Vector3)
637 return (LSL_Types.Vector3)m_data[itemIndex];
638 else
639 throw new InvalidCastException(string.Format(
640 "{0} expected but {1} given",
641 typeof(LSL_Types.Vector3).Name,
642 m_data[itemIndex] != null ?
643 m_data[itemIndex].GetType().Name : "null"));
571 } 644 }
572 645
573 public LSL_Types.Quaternion GetQuaternionItem(int itemIndex) 646 public LSL_Types.Quaternion GetQuaternionItem(int itemIndex)
diff --git a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
index 5c4174e..cee10df 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
@@ -152,9 +152,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
152 det[0] = new DetectParams(); 152 det[0] = new DetectParams();
153 det[0].Key = remoteClient.AgentId; 153 det[0].Key = remoteClient.AgentId;
154 det[0].Populate(myScriptEngine.World); 154 det[0].Populate(myScriptEngine.World);
155 det[0].OffsetPos = new LSL_Types.Vector3(offsetPos.X, 155 det[0].OffsetPos = offsetPos;
156 offsetPos.Y,
157 offsetPos.Z);
158 156
159 if (originalID == 0) 157 if (originalID == 0)
160 { 158 {
@@ -298,9 +296,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
298 foreach (DetectedObject detobj in col.Colliders) 296 foreach (DetectedObject detobj in col.Colliders)
299 { 297 {
300 DetectParams d = new DetectParams(); 298 DetectParams d = new DetectParams();
301 d.Position = new LSL_Types.Vector3(detobj.posVector.X, 299 d.Position = detobj.posVector;
302 detobj.posVector.Y,
303 detobj.posVector.Z);
304 d.Populate(myScriptEngine.World); 300 d.Populate(myScriptEngine.World);
305 det.Add(d); 301 det.Add(d);
306 myScriptEngine.PostObjectEvent(localID, new EventParams( 302 myScriptEngine.PostObjectEvent(localID, new EventParams(
@@ -318,9 +314,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
318 foreach (DetectedObject detobj in col.Colliders) 314 foreach (DetectedObject detobj in col.Colliders)
319 { 315 {
320 DetectParams d = new DetectParams(); 316 DetectParams d = new DetectParams();
321 d.Position = new LSL_Types.Vector3(detobj.posVector.X, 317 d.Position = detobj.posVector;
322 detobj.posVector.Y,
323 detobj.posVector.Z);
324 d.Populate(myScriptEngine.World); 318 d.Populate(myScriptEngine.World);
325 det.Add(d); 319 det.Add(d);
326 myScriptEngine.PostObjectEvent(localID, new EventParams( 320 myScriptEngine.PostObjectEvent(localID, new EventParams(
@@ -337,9 +331,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
337 foreach (DetectedObject detobj in col.Colliders) 331 foreach (DetectedObject detobj in col.Colliders)
338 { 332 {
339 DetectParams d = new DetectParams(); 333 DetectParams d = new DetectParams();
340 d.Position = new LSL_Types.Vector3(detobj.posVector.X, 334 d.Position = detobj.posVector;
341 detobj.posVector.Y,
342 detobj.posVector.Z);
343 d.Populate(myScriptEngine.World); 335 d.Populate(myScriptEngine.World);
344 det.Add(d); 336 det.Add(d);
345 myScriptEngine.PostObjectEvent(localID, new EventParams( 337 myScriptEngine.PostObjectEvent(localID, new EventParams(
@@ -381,8 +373,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
381 myScriptEngine.PostObjectEvent(localID, new EventParams( 373 myScriptEngine.PostObjectEvent(localID, new EventParams(
382 "at_target", new object[] { 374 "at_target", new object[] {
383 new LSL_Types.LSLInteger(handle), 375 new LSL_Types.LSLInteger(handle),
384 new LSL_Types.Vector3(targetpos.X,targetpos.Y,targetpos.Z), 376 new LSL_Types.Vector3(targetpos),
385 new LSL_Types.Vector3(atpos.X,atpos.Y,atpos.Z) }, 377 new LSL_Types.Vector3(atpos) },
386 new DetectParams[0])); 378 new DetectParams[0]));
387 } 379 }
388 380
@@ -399,8 +391,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
399 myScriptEngine.PostObjectEvent(localID, new EventParams( 391 myScriptEngine.PostObjectEvent(localID, new EventParams(
400 "at_rot_target", new object[] { 392 "at_rot_target", new object[] {
401 new LSL_Types.LSLInteger(handle), 393 new LSL_Types.LSLInteger(handle),
402 new LSL_Types.Quaternion(targetrot.X,targetrot.Y,targetrot.Z,targetrot.W), 394 new LSL_Types.Quaternion(targetrot),
403 new LSL_Types.Quaternion(atrot.X,atrot.Y,atrot.Z,atrot.W) }, 395 new LSL_Types.Quaternion(atrot) },
404 new DetectParams[0])); 396 new DetectParams[0]));
405 } 397 }
406 398
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index f6cb7df..9f05666 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -656,7 +656,19 @@ namespace OpenSim.Region.ScriptEngine.XEngine
656 if (m_Assemblies.ContainsKey(instance.AssetID)) 656 if (m_Assemblies.ContainsKey(instance.AssetID))
657 { 657 {
658 string assembly = m_Assemblies[instance.AssetID]; 658 string assembly = m_Assemblies[instance.AssetID];
659 instance.SaveState(assembly); 659
660 try
661 {
662 instance.SaveState(assembly);
663 }
664 catch (Exception e)
665 {
666 m_log.Error(
667 string.Format(
668 "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
669 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
670 , e);
671 }
660 } 672 }
661 673
662 // Clear the event queue and abort the instance thread 674 // Clear the event queue and abort the instance thread
@@ -778,7 +790,18 @@ namespace OpenSim.Region.ScriptEngine.XEngine
778 assembly = m_Assemblies[i.AssetID]; 790 assembly = m_Assemblies[i.AssetID];
779 791
780 792
781 i.SaveState(assembly); 793 try
794 {
795 i.SaveState(assembly);
796 }
797 catch (Exception e)
798 {
799 m_log.Error(
800 string.Format(
801 "[XEngine]: Failed to save state of script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
802 i.PrimName, i.ScriptName, i.ItemID, i.ObjectID, World.Name)
803 , e);
804 }
782 } 805 }
783 806
784 instances.Clear(); 807 instances.Clear();
@@ -971,6 +994,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
971 // This delay exists to stop mono problems where script compilation and startup would stop the sim 994 // This delay exists to stop mono problems where script compilation and startup would stop the sim
972 // working properly for the session. 995 // working properly for the session.
973 System.Threading.Thread.Sleep(m_StartDelay); 996 System.Threading.Thread.Sleep(m_StartDelay);
997
998 m_log.InfoFormat("[XEngine]: Performing initial script startup on {0}", m_Scene.Name);
974 } 999 }
975 1000
976 object[] o; 1001 object[] o;
@@ -986,13 +1011,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine
986 if (m_InitialStartup) 1011 if (m_InitialStartup)
987 if (scriptsStarted % 50 == 0) 1012 if (scriptsStarted % 50 == 0)
988 m_log.InfoFormat( 1013 m_log.InfoFormat(
989 "[XEngine]: Started {0} scripts in {1}", scriptsStarted, m_Scene.RegionInfo.RegionName); 1014 "[XEngine]: Started {0} scripts in {1}", scriptsStarted, m_Scene.Name);
990 } 1015 }
991 } 1016 }
992 1017
993 if (m_InitialStartup) 1018 if (m_InitialStartup)
994 m_log.InfoFormat( 1019 m_log.InfoFormat(
995 "[XEngine]: Completed starting {0} scripts on {1}", scriptsStarted, m_Scene.RegionInfo.RegionName); 1020 "[XEngine]: Completed starting {0} scripts on {1}", scriptsStarted, m_Scene.Name);
996 1021
997 // NOTE: Despite having a lockless queue, this lock is required 1022 // NOTE: Despite having a lockless queue, this lock is required
998 // to make sure there is never no compile thread while there 1023 // to make sure there is never no compile thread while there
@@ -1053,10 +1078,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1053 return false; 1078 return false;
1054 } 1079 }
1055 1080
1056 UUID assetID = item.AssetID; 1081 m_log.DebugFormat(
1082 "[XEngine] Loading script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
1083 part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
1084 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1057 1085
1058 //m_log.DebugFormat("[XEngine] Compiling script {0} ({1} on object {2})", 1086 UUID assetID = item.AssetID;
1059 // item.Name, itemID.ToString(), part.ParentGroup.RootPart.Name);
1060 1087
1061 ScenePresence presence = m_Scene.GetScenePresence(item.OwnerID); 1088 ScenePresence presence = m_Scene.GetScenePresence(item.OwnerID);
1062 1089
@@ -1235,10 +1262,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1235 item.Name, startParam, postOnRez, 1262 item.Name, startParam, postOnRez,
1236 stateSource, m_MaxScriptQueue); 1263 stateSource, m_MaxScriptQueue);
1237 1264
1238 m_log.DebugFormat( 1265// m_log.DebugFormat(
1239 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", 1266// "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1240 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, 1267// part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
1241 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 1268// part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1242 1269
1243 if (presence != null) 1270 if (presence != null)
1244 { 1271 {
@@ -1554,9 +1581,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1554 else if (p[i] is string) 1581 else if (p[i] is string)
1555 lsl_p[i] = new LSL_Types.LSLString((string)p[i]); 1582 lsl_p[i] = new LSL_Types.LSLString((string)p[i]);
1556 else if (p[i] is Vector3) 1583 else if (p[i] is Vector3)
1557 lsl_p[i] = new LSL_Types.Vector3(((Vector3)p[i]).X, ((Vector3)p[i]).Y, ((Vector3)p[i]).Z); 1584 lsl_p[i] = new LSL_Types.Vector3((Vector3)p[i]);
1558 else if (p[i] is Quaternion) 1585 else if (p[i] is Quaternion)
1559 lsl_p[i] = new LSL_Types.Quaternion(((Quaternion)p[i]).X, ((Quaternion)p[i]).Y, ((Quaternion)p[i]).Z, ((Quaternion)p[i]).W); 1586 lsl_p[i] = new LSL_Types.Quaternion((Quaternion)p[i]);
1560 else if (p[i] is float) 1587 else if (p[i] is float)
1561 lsl_p[i] = new LSL_Types.LSLFloat((float)p[i]); 1588 lsl_p[i] = new LSL_Types.LSLFloat((float)p[i]);
1562 else 1589 else
@@ -1580,9 +1607,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1580 else if (p[i] is string) 1607 else if (p[i] is string)
1581 lsl_p[i] = new LSL_Types.LSLString((string)p[i]); 1608 lsl_p[i] = new LSL_Types.LSLString((string)p[i]);
1582 else if (p[i] is Vector3) 1609 else if (p[i] is Vector3)
1583 lsl_p[i] = new LSL_Types.Vector3(((Vector3)p[i]).X, ((Vector3)p[i]).Y, ((Vector3)p[i]).Z); 1610 lsl_p[i] = new LSL_Types.Vector3((Vector3)p[i]);
1584 else if (p[i] is Quaternion) 1611 else if (p[i] is Quaternion)
1585 lsl_p[i] = new LSL_Types.Quaternion(((Quaternion)p[i]).X, ((Quaternion)p[i]).Y, ((Quaternion)p[i]).Z, ((Quaternion)p[i]).W); 1612 lsl_p[i] = new LSL_Types.Quaternion((Quaternion)p[i]);
1586 else if (p[i] is float) 1613 else if (p[i] is float)
1587 lsl_p[i] = new LSL_Types.LSLFloat((float)p[i]); 1614 lsl_p[i] = new LSL_Types.LSLFloat((float)p[i]);
1588 else 1615 else