aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorMelanie2013-08-07 23:29:42 +0100
committerMelanie2013-08-07 23:29:42 +0100
commit005c69511dac490a8353233423a3152abf5580dd (patch)
treeabae7717af4af3ed7844f3747ab28398fdad9cdf /OpenSim/Region
parentMerge branch 'avination-current' into careminster (diff)
parentminor: add some method doc to ScenePresence fields used for entity transfer, ... (diff)
downloadopensim-SC-005c69511dac490a8353233423a3152abf5580dd.zip
opensim-SC-005c69511dac490a8353233423a3152abf5580dd.tar.gz
opensim-SC-005c69511dac490a8353233423a3152abf5580dd.tar.bz2
opensim-SC-005c69511dac490a8353233423a3152abf5580dd.tar.xz
Merge branch 'master' into careminster
Conflicts: OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs OpenSim/Region/Framework/Scenes/Scene.Inventory.cs OpenSim/Region/Framework/Scenes/Scene.cs
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/Application/Application.cs41
-rw-r--r--OpenSim/Region/Application/ConfigurationLoader.cs1
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs12
-rw-r--r--OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs18
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs35
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs42
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs34
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs21
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs59
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs36
-rwxr-xr-xOpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs65
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs53
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs5
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs206
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs44
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs41
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs17
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsActor.cs3
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsScene.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs2
25 files changed, 568 insertions, 188 deletions
diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs
index e451aa8..2e155ec 100644
--- a/OpenSim/Region/Application/Application.cs
+++ b/OpenSim/Region/Application/Application.cs
@@ -103,26 +103,38 @@ namespace OpenSim
103 "[OPENSIM MAIN]: Environment variable MONO_THREADS_PER_CPU is {0}", monoThreadsPerCpu ?? "unset"); 103 "[OPENSIM MAIN]: Environment variable MONO_THREADS_PER_CPU is {0}", monoThreadsPerCpu ?? "unset");
104 104
105 // Verify the Threadpool allocates or uses enough worker and IO completion threads 105 // Verify the Threadpool allocates or uses enough worker and IO completion threads
106 // .NET 2.0 workerthreads default to 50 * numcores 106 // .NET 2.0, workerthreads default to 50 * numcores
107 // .NET 3.0 workerthreads defaults to 250 * numcores 107 // .NET 3.0, workerthreads defaults to 250 * numcores
108 // .NET 4.0 workerthreads are dynamic based on bitness and OS resources 108 // .NET 4.0, workerthreads are dynamic based on bitness and OS resources
109 // Max IO Completion threads are 1000 on all 3 CLRs. 109 // Max IO Completion threads are 1000 on all 3 CLRs
110 //
111 // Mono 2.10.9 to at least Mono 3.1, workerthreads default to 100 * numcores, iocp threads to 4 * numcores
110 int workerThreadsMin = 500; 112 int workerThreadsMin = 500;
111 int workerThreadsMax = 1000; // may need further adjustment to match other CLR 113 int workerThreadsMax = 1000; // may need further adjustment to match other CLR
112 int iocpThreadsMin = 1000; 114 int iocpThreadsMin = 1000;
113 int iocpThreadsMax = 2000; // may need further adjustment to match other CLR 115 int iocpThreadsMax = 2000; // may need further adjustment to match other CLR
116
117 {
118 int currentMinWorkerThreads, currentMinIocpThreads;
119 System.Threading.ThreadPool.GetMinThreads(out currentMinWorkerThreads, out currentMinIocpThreads);
120 m_log.InfoFormat(
121 "[OPENSIM MAIN]: Runtime gave us {0} min worker threads and {1} min IOCP threads",
122 currentMinWorkerThreads, currentMinIocpThreads);
123 }
124
114 int workerThreads, iocpThreads; 125 int workerThreads, iocpThreads;
115 System.Threading.ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads); 126 System.Threading.ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads);
116 m_log.InfoFormat("[OPENSIM MAIN]: Runtime gave us {0} worker threads and {1} IOCP threads", workerThreads, iocpThreads); 127 m_log.InfoFormat("[OPENSIM MAIN]: Runtime gave us {0} max worker threads and {1} max IOCP threads", workerThreads, iocpThreads);
128
117 if (workerThreads < workerThreadsMin) 129 if (workerThreads < workerThreadsMin)
118 { 130 {
119 workerThreads = workerThreadsMin; 131 workerThreads = workerThreadsMin;
120 m_log.InfoFormat("[OPENSIM MAIN]: Bumping up to worker threads to {0}",workerThreads); 132 m_log.InfoFormat("[OPENSIM MAIN]: Bumping up to max worker threads to {0}",workerThreads);
121 } 133 }
122 if (workerThreads > workerThreadsMax) 134 if (workerThreads > workerThreadsMax)
123 { 135 {
124 workerThreads = workerThreadsMax; 136 workerThreads = workerThreadsMax;
125 m_log.InfoFormat("[OPENSIM MAIN]: Limiting worker threads to {0}",workerThreads); 137 m_log.InfoFormat("[OPENSIM MAIN]: Limiting max worker threads to {0}",workerThreads);
126 } 138 }
127 139
128 // Increase the number of IOCP threads available. 140 // Increase the number of IOCP threads available.
@@ -130,22 +142,24 @@ namespace OpenSim
130 if (iocpThreads < iocpThreadsMin) 142 if (iocpThreads < iocpThreadsMin)
131 { 143 {
132 iocpThreads = iocpThreadsMin; 144 iocpThreads = iocpThreadsMin;
133 m_log.InfoFormat("[OPENSIM MAIN]: Bumping up IO completion threads to {0}",iocpThreads); 145 m_log.InfoFormat("[OPENSIM MAIN]: Bumping up max IO completion threads to {0}",iocpThreads);
134 } 146 }
135 // Make sure we don't overallocate IOCP threads and thrash system resources 147 // Make sure we don't overallocate IOCP threads and thrash system resources
136 if ( iocpThreads > iocpThreadsMax ) 148 if ( iocpThreads > iocpThreadsMax )
137 { 149 {
138 iocpThreads = iocpThreadsMax; 150 iocpThreads = iocpThreadsMax;
139 m_log.InfoFormat("[OPENSIM MAIN]: Limiting IO completion threads to {0}",iocpThreads); 151 m_log.InfoFormat("[OPENSIM MAIN]: Limiting max IO completion threads to {0}",iocpThreads);
140 } 152 }
141 // set the resulting worker and IO completion thread counts back to ThreadPool 153 // set the resulting worker and IO completion thread counts back to ThreadPool
142 if ( System.Threading.ThreadPool.SetMaxThreads(workerThreads, iocpThreads) ) 154 if ( System.Threading.ThreadPool.SetMaxThreads(workerThreads, iocpThreads) )
143 { 155 {
144 m_log.InfoFormat("[OPENSIM MAIN]: Threadpool set to {0} worker threads and {1} IO completion threads", workerThreads, iocpThreads); 156 m_log.InfoFormat(
157 "[OPENSIM MAIN]: Threadpool set to {0} max worker threads and {1} max IO completion threads",
158 workerThreads, iocpThreads);
145 } 159 }
146 else 160 else
147 { 161 {
148 m_log.Info("[OPENSIM MAIN]: Threadpool reconfiguration failed, runtime defaults still in effect."); 162 m_log.Warn("[OPENSIM MAIN]: Threadpool reconfiguration failed, runtime defaults still in effect.");
149 } 163 }
150 164
151 // Check if the system is compatible with OpenSimulator. 165 // Check if the system is compatible with OpenSimulator.
@@ -153,17 +167,16 @@ namespace OpenSim
153 string supported = String.Empty; 167 string supported = String.Empty;
154 if (Util.IsEnvironmentSupported(ref supported)) 168 if (Util.IsEnvironmentSupported(ref supported))
155 { 169 {
156 m_log.Info("Environment is compatible.\n"); 170 m_log.Info("[OPENSIM MAIN]: Environment is supported by OpenSimulator.");
157 } 171 }
158 else 172 else
159 { 173 {
160 m_log.Warn("Environment is unsupported (" + supported + ")\n"); 174 m_log.Warn("[OPENSIM MAIN]: Environment is not supported by OpenSimulator (" + supported + ")\n");
161 } 175 }
162 176
163 // Configure nIni aliases and localles 177 // Configure nIni aliases and localles
164 Culture.SetCurrentCulture(); 178 Culture.SetCurrentCulture();
165 179
166
167 // Validate that the user has the most basic configuration done 180 // Validate that the user has the most basic configuration done
168 // If not, offer to do the most basic configuration for them warning them along the way of the importance of 181 // If not, offer to do the most basic configuration for them warning them along the way of the importance of
169 // reading these files. 182 // reading these files.
diff --git a/OpenSim/Region/Application/ConfigurationLoader.cs b/OpenSim/Region/Application/ConfigurationLoader.cs
index fc3999f..3e93638 100644
--- a/OpenSim/Region/Application/ConfigurationLoader.cs
+++ b/OpenSim/Region/Application/ConfigurationLoader.cs
@@ -337,7 +337,6 @@ namespace OpenSim
337 config.Set("physics", "OpenDynamicsEngine"); 337 config.Set("physics", "OpenDynamicsEngine");
338 config.Set("meshing", "Meshmerizer"); 338 config.Set("meshing", "Meshmerizer");
339 config.Set("physical_prim", true); 339 config.Set("physical_prim", true);
340 config.Set("see_into_this_sim_from_neighbor", true);
341 config.Set("serverside_object_permissions", true); 340 config.Set("serverside_object_permissions", true);
342 config.Set("storage_plugin", "OpenSim.Data.SQLite.dll"); 341 config.Set("storage_plugin", "OpenSim.Data.SQLite.dll");
343 config.Set("storage_connection_string", "URI=file:OpenSim.db,version=3"); 342 config.Set("storage_connection_string", "URI=file:OpenSim.db,version=3");
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs
index 83144e3..575e54c 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs
@@ -29,6 +29,7 @@ using System;
29using System.IO; 29using System.IO;
30using System.Net; 30using System.Net;
31using System.Reflection; 31using System.Reflection;
32using System.Threading;
32using log4net.Config; 33using log4net.Config;
33using Nini.Config; 34using Nini.Config;
34using NUnit.Framework; 35using NUnit.Framework;
@@ -53,6 +54,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
53 [TestFixtureSetUp] 54 [TestFixtureSetUp]
54 public void FixtureInit() 55 public void FixtureInit()
55 { 56 {
57 // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
58 Util.FireAndForgetMethod = FireAndForgetMethod.None;
59
56 using ( 60 using (
57 Stream resource 61 Stream resource
58 = GetType().Assembly.GetManifestResourceStream( 62 = GetType().Assembly.GetManifestResourceStream(
@@ -72,6 +76,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
72 } 76 }
73 } 77 }
74 78
79 [TestFixtureTearDown]
80 public void TearDown()
81 {
82 // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
83 // threads. Possibly, later tests should be rewritten not to worry about such things.
84 Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
85 }
86
75 [SetUp] 87 [SetUp]
76 public override void SetUp() 88 public override void SetUp()
77 { 89 {
diff --git a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
index 3764685..d9b0eff 100644
--- a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
@@ -166,7 +166,7 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
166 166
167 // Do Decode! 167 // Do Decode!
168 if (decode) 168 if (decode)
169 Decode(assetID, j2kData); 169 Util.FireAndForget(delegate { Decode(assetID, j2kData); });
170 } 170 }
171 } 171 }
172 172
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index e1ca6cd..62b25d0 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -54,8 +54,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
54 public int DebugLevel { get; set; } 54 public int DebugLevel { get; set; }
55 55
56 /// <summary> 56 /// <summary>
57 /// Period to sleep per 100 prims in order to avoid CPU spikes when an avatar with many attachments logs in 57 /// Period to sleep per 100 prims in order to avoid CPU spikes when an avatar with many attachments logs in/changes
58 /// or many avatars with a medium levels of attachments login simultaneously. 58 /// outfit or many avatars with a medium levels of attachments login/change outfit simultaneously.
59 /// </summary> 59 /// </summary>
60 /// <remarks> 60 /// <remarks>
61 /// A value of 0 will apply no pause. The pause is specified in milliseconds. 61 /// A value of 0 will apply no pause. The pause is specified in milliseconds.
@@ -1094,7 +1094,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
1094 } 1094 }
1095 1095
1096 if (tainted) 1096 if (tainted)
1097 objatt.HasGroupChanged = true; 1097 objatt.HasGroupChanged = true;
1098
1099 if (ThrottlePer100PrimsRezzed > 0)
1100 {
1101 int throttleMs = (int)Math.Round((float)objatt.PrimCount / 100 * ThrottlePer100PrimsRezzed);
1102
1103 if (DebugLevel > 0)
1104 m_log.DebugFormat(
1105 "[ATTACHMENTS MODULE]: Throttling by {0}ms after rez of {1} with {2} prims for attachment to {3} on point {4} in {5}",
1106 throttleMs, objatt.Name, objatt.PrimCount, sp.Name, attachmentPt, m_scene.Name);
1107
1108 Thread.Sleep(throttleMs);
1109 }
1098 1110
1099 return objatt; 1111 return objatt;
1100 } 1112 }
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index df95bf0..4286eef 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -693,8 +693,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
693 if (version.Equals("SIMULATION/0.2")) 693 if (version.Equals("SIMULATION/0.2"))
694 TransferAgent_V2(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason); 694 TransferAgent_V2(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason);
695 else 695 else
696 TransferAgent_V1(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason); 696 TransferAgent_V1(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason);
697
698 } 697 }
699 698
700 private void TransferAgent_V1(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination, 699 private void TransferAgent_V1(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination,
@@ -703,7 +702,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
703 ulong destinationHandle = finalDestination.RegionHandle; 702 ulong destinationHandle = finalDestination.RegionHandle;
704 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); 703 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
705 704
706 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Using TP V1"); 705 m_log.DebugFormat(
706 "[ENTITY TRANSFER MODULE]: Using TP V1 for {0} going from {1} to {2}",
707 sp.Name, Scene.Name, finalDestination.RegionName);
708
707 // Let's create an agent there if one doesn't exist yet. 709 // Let's create an agent there if one doesn't exist yet.
708 // NOTE: logout will always be false for a non-HG teleport. 710 // NOTE: logout will always be false for a non-HG teleport.
709 bool logout = false; 711 bool logout = false;
@@ -961,6 +963,27 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
961 return; 963 return;
962 } 964 }
963 965
966 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling)
967 {
968 m_interRegionTeleportCancels.Value++;
969
970 m_log.DebugFormat(
971 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request",
972 sp.Name, finalDestination.RegionName, sp.Scene.Name);
973
974 return;
975 }
976 else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
977 {
978 m_interRegionTeleportAborts.Value++;
979
980 m_log.DebugFormat(
981 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.",
982 sp.Name, finalDestination.RegionName, sp.Scene.Name);
983
984 return;
985 }
986
964 // Past this point we have to attempt clean up if the teleport fails, so update transfer state. 987 // Past this point we have to attempt clean up if the teleport fails, so update transfer state.
965 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); 988 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
966 989
@@ -1063,20 +1086,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1063 if (!sp.DoNotCloseAfterTeleport) 1086 if (!sp.DoNotCloseAfterTeleport)
1064 { 1087 {
1065 // OK, it got this agent. Let's close everything 1088 // OK, it got this agent. Let's close everything
1066 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Closing in agent {0} in region {1}", sp.Name, Scene.RegionInfo.RegionName); 1089 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Closing in agent {0} in region {1}", sp.Name, Scene.Name);
1067 sp.CloseChildAgents(newRegionX, newRegionY); 1090 sp.CloseChildAgents(newRegionX, newRegionY);
1068 sp.Scene.IncomingCloseAgent(sp.UUID, false); 1091 sp.Scene.IncomingCloseAgent(sp.UUID, false);
1069 1092
1070 } 1093 }
1071 else 1094 else
1072 { 1095 {
1073 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Not closing agent {0}, user is back in {0}", sp.Name, Scene.RegionInfo.RegionName); 1096 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Not closing agent {0}, user is back in {0}", sp.Name, Scene.Name);
1074 sp.DoNotCloseAfterTeleport = false; 1097 sp.DoNotCloseAfterTeleport = false;
1075 } 1098 }
1076 } 1099 }
1077 else 1100 else
1101 {
1078 // now we have a child agent in this region. 1102 // now we have a child agent in this region.
1079 sp.Reset(); 1103 sp.Reset();
1104 }
1080 } 1105 }
1081 1106
1082 /// <summary> 1107 /// <summary>
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
index 8f9800f..ce7ed26 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
@@ -62,6 +62,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
62 private string m_ThisGatekeeper; 62 private string m_ThisGatekeeper;
63 private bool m_RestrictInventoryAccessAbroad; 63 private bool m_RestrictInventoryAccessAbroad;
64 64
65 private bool m_bypassPermissions = true;
66
65// private bool m_Initialized = false; 67// private bool m_Initialized = false;
66 68
67 #region INonSharedRegionModule 69 #region INonSharedRegionModule
@@ -100,6 +102,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
100 } 102 }
101 else 103 else
102 m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!"); 104 m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!");
105
106 m_bypassPermissions = !Util.GetConfigVarFromSections<bool>(source, "serverside_object_permissions",
107 new string[] { "Startup", "Permissions" }, true);
108
103 } 109 }
104 } 110 }
105 } 111 }
@@ -114,6 +120,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
114 scene.EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem; 120 scene.EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem;
115 scene.EventManager.OnTeleportStart += TeleportStart; 121 scene.EventManager.OnTeleportStart += TeleportStart;
116 scene.EventManager.OnTeleportFail += TeleportFail; 122 scene.EventManager.OnTeleportFail += TeleportFail;
123
124 // We're fgoing to enforce some stricter permissions if Outbound is false
125 scene.Permissions.OnTakeObject += CanTakeObject;
126 scene.Permissions.OnTakeCopyObject += CanTakeObject;
127 scene.Permissions.OnTransferUserInventory += OnTransferUserInventory;
117 } 128 }
118 129
119 #endregion 130 #endregion
@@ -417,5 +428,36 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
417 } 428 }
418 429
419 #endregion 430 #endregion
431
432 #region Permissions
433
434 private bool CanTakeObject(UUID objectID, UUID stealer, Scene scene)
435 {
436 if (m_bypassPermissions) return true;
437
438 if (!m_OutboundPermission && !UserManagementModule.IsLocalGridUser(stealer))
439 {
440 SceneObjectGroup sog = null;
441 if (m_Scene.TryGetSceneObjectGroup(objectID, out sog) && sog.OwnerID == stealer)
442 return true;
443
444 return false;
445 }
446
447 return true;
448 }
449
450 private bool OnTransferUserInventory(UUID itemID, UUID userID, UUID recipientID)
451 {
452 if (m_bypassPermissions) return true;
453
454 if (!m_OutboundPermission && !UserManagementModule.IsLocalGridUser(recipientID))
455 return false;
456
457 return true;
458 }
459
460
461 #endregion
420 } 462 }
421} \ No newline at end of file 463} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index aa00145..89bb037 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -809,7 +809,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
809 } 809 }
810 810
811 objlist.Add(g); 811 objlist.Add(g);
812 veclist.Add(new Vector3(0, 0, 0)); 812 veclist.Add(Vector3.Zero);
813 813
814 float offsetHeight = 0; 814 float offsetHeight = 0;
815 pos = m_Scene.GetNewRezLocation( 815 pos = m_Scene.GetNewRezLocation(
diff --git a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
index fccf053..bb304df 100644
--- a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
@@ -163,7 +163,7 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
163 163
164 public void RegisterScriptInvocation(object target, MethodInfo mi) 164 public void RegisterScriptInvocation(object target, MethodInfo mi)
165 { 165 {
166 m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}", mi.Name, (target is Type) ? ((Type)target).Name : target.GetType().Name); 166// m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}", mi.Name, (target is Type) ? ((Type)target).Name : target.GetType().Name);
167 167
168 Type delegateType; 168 Type delegateType;
169 List<Type> typeArgs = mi.GetParameters() 169 List<Type> typeArgs = mi.GetParameters()
@@ -325,7 +325,7 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
325 /// </summary> 325 /// </summary>
326 public void RegisterConstant(string cname, object value) 326 public void RegisterConstant(string cname, object value)
327 { 327 {
328 m_log.DebugFormat("[MODULE COMMANDS] register constant <{0}> with value {1}",cname,value.ToString()); 328// m_log.DebugFormat("[MODULE COMMANDS] register constant <{0}> with value {1}",cname,value.ToString());
329 lock (m_constants) 329 lock (m_constants)
330 { 330 {
331 m_constants.Add(cname,value); 331 m_constants.Add(cname,value);
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
index a5adc29..a9aa73c 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
@@ -63,35 +63,41 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
63 /// </summary> 63 /// </summary>
64 private bool m_ModuleEnabled = false; 64 private bool m_ModuleEnabled = false;
65 65
66 public LocalSimulationConnectorModule()
67 {
68 ServiceVersion = "SIMULATION/0.2";
69 }
70
71 #region Region Module interface 66 #region Region Module interface
72 67
73 public void Initialise(IConfigSource config) 68 public void Initialise(IConfigSource configSource)
74 { 69 {
75 IConfig moduleConfig = config.Configs["Modules"]; 70 IConfig moduleConfig = configSource.Configs["Modules"];
76 if (moduleConfig != null) 71 if (moduleConfig != null)
77 { 72 {
78 string name = moduleConfig.GetString("SimulationServices", ""); 73 string name = moduleConfig.GetString("SimulationServices", "");
79 if (name == Name) 74 if (name == Name)
80 { 75 {
81 //IConfig userConfig = config.Configs["SimulationService"]; 76 InitialiseService(configSource);
82 //if (userConfig == null)
83 //{
84 // m_log.Error("[AVATAR CONNECTOR]: SimulationService missing from OpenSim.ini");
85 // return;
86 //}
87 77
88 m_ModuleEnabled = true; 78 m_ModuleEnabled = true;
89 79
90 m_log.Info("[SIMULATION CONNECTOR]: Local simulation enabled"); 80 m_log.Info("[LOCAL SIMULATION CONNECTOR]: Local simulation enabled.");
91 } 81 }
92 } 82 }
93 } 83 }
94 84
85 public void InitialiseService(IConfigSource configSource)
86 {
87 ServiceVersion = "SIMULATION/0.2";
88 IConfig config = configSource.Configs["SimulationService"];
89 if (config != null)
90 {
91 ServiceVersion = config.GetString("ConnectorProtocolVersion", ServiceVersion);
92
93 if (ServiceVersion != "SIMULATION/0.1" && ServiceVersion != "SIMULATION/0.2")
94 throw new Exception(string.Format("Invalid ConnectorProtocolVersion {0}", ServiceVersion));
95
96 m_log.InfoFormat(
97 "[LOCAL SIMULATION CONNECTOR]: Initialzied with connector protocol version {0}", ServiceVersion);
98 }
99 }
100
95 public void PostInitialise() 101 public void PostInitialise()
96 { 102 {
97 } 103 }
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
index a1ab3e3..8bd1d10 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
@@ -50,9 +50,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
50 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RemoteSimulationConnectorModule")] 50 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RemoteSimulationConnectorModule")]
51 public class RemoteSimulationConnectorModule : ISharedRegionModule, ISimulationService 51 public class RemoteSimulationConnectorModule : ISharedRegionModule, ISimulationService
52 { 52 {
53 private bool initialized = false;
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 53 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55 54
55 private bool initialized = false;
56 protected bool m_enabled = false; 56 protected bool m_enabled = false;
57 protected Scene m_aScene; 57 protected Scene m_aScene;
58 // RemoteSimulationConnector does not care about local regions; it delegates that to the Local module 58 // RemoteSimulationConnector does not care about local regions; it delegates that to the Local module
@@ -64,27 +64,23 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
64 64
65 #region Region Module interface 65 #region Region Module interface
66 66
67 public virtual void Initialise(IConfigSource config) 67 public virtual void Initialise(IConfigSource configSource)
68 { 68 {
69 69 IConfig moduleConfig = configSource.Configs["Modules"];
70 IConfig moduleConfig = config.Configs["Modules"];
71 if (moduleConfig != null) 70 if (moduleConfig != null)
72 { 71 {
73 string name = moduleConfig.GetString("SimulationServices", ""); 72 string name = moduleConfig.GetString("SimulationServices", "");
74 if (name == Name) 73 if (name == Name)
75 { 74 {
76 //IConfig userConfig = config.Configs["SimulationService"]; 75 m_localBackend = new LocalSimulationConnectorModule();
77 //if (userConfig == null) 76
78 //{ 77 m_localBackend.InitialiseService(configSource);
79 // m_log.Error("[AVATAR CONNECTOR]: SimulationService missing from OpenSim.ini");
80 // return;
81 //}
82 78
83 m_remoteConnector = new SimulationServiceConnector(); 79 m_remoteConnector = new SimulationServiceConnector();
84 80
85 m_enabled = true; 81 m_enabled = true;
86 82
87 m_log.Info("[SIMULATION CONNECTOR]: Remote simulation enabled"); 83 m_log.Info("[REMOTE SIMULATION CONNECTOR]: Remote simulation enabled.");
88 } 84 }
89 } 85 }
90 } 86 }
@@ -142,8 +138,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
142 } 138 }
143 139
144 protected virtual void InitOnce(Scene scene) 140 protected virtual void InitOnce(Scene scene)
145 { 141 {
146 m_localBackend = new LocalSimulationConnectorModule();
147 m_aScene = scene; 142 m_aScene = scene;
148 //m_regionClient = new RegionToRegionClient(m_aScene, m_hyperlinkService); 143 //m_regionClient = new RegionToRegionClient(m_aScene, m_hyperlinkService);
149 m_thisIP = Util.GetHostFromDNS(scene.RegionInfo.ExternalHostName); 144 m_thisIP = Util.GetHostFromDNS(scene.RegionInfo.ExternalHostName);
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 8f6073a..550ab87 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -551,6 +551,9 @@ namespace OpenSim.Region.Framework.Scenes
551 { 551 {
552 //Console.WriteLine("Scene.Inventory.cs: GiveInventoryItem"); 552 //Console.WriteLine("Scene.Inventory.cs: GiveInventoryItem");
553 553
554 if (!Permissions.CanTransferUserInventory(itemId, senderId, recipient))
555 return null;
556
554 InventoryItemBase item = new InventoryItemBase(itemId, senderId); 557 InventoryItemBase item = new InventoryItemBase(itemId, senderId);
555 item = InventoryService.GetItem(item); 558 item = InventoryService.GetItem(item);
556 559
@@ -2127,7 +2130,10 @@ namespace OpenSim.Region.Framework.Scenes
2127 { 2130 {
2128 // If we don't have permission, stop right here 2131 // If we don't have permission, stop right here
2129 if (!permissionToTakeCopy) 2132 if (!permissionToTakeCopy)
2133 {
2134 remoteClient.SendAlertMessage("You don't have permission to take the object");
2130 return; 2135 return;
2136 }
2131 2137
2132 permissionToTake = true; 2138 permissionToTake = true;
2133 // Don't delete 2139 // Don't delete
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 0d9028c..aa09092 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -4174,28 +4174,29 @@ namespace OpenSim.Region.Framework.Scenes
4174 } 4174 }
4175 } 4175 }
4176 4176
4177 if (RegionInfo.EstateSettings != null)
4178 {
4179 if (RegionInfo.EstateSettings.IsBanned(agent.AgentID, 0))
4180 {
4181 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist",
4182 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
4183 reason = String.Format("Denied access to region {0}: You have been banned from that region.",
4184 RegionInfo.RegionName);
4185 return false;
4186 }
4187 }
4188 else
4189 {
4190 m_log.ErrorFormat("[CONNECTION BEGIN]: Estate Settings is null!");
4191 }
4192
4193 // We only test the things below when we want to cut off 4177 // We only test the things below when we want to cut off
4194 // child agents from being present in the scene for which their root 4178 // child agents from being present in the scene for which their root
4195 // agent isn't allowed. Otherwise, we allow child agents. The test for 4179 // agent isn't allowed. Otherwise, we allow child agents. The test for
4196 // the root is done elsewhere (QueryAccess) 4180 // the root is done elsewhere (QueryAccess)
4197 if (!bypassAccessControl) 4181 if (!bypassAccessControl)
4198 { 4182 {
4183 if (RegionInfo.EstateSettings != null)
4184 {
4185 int flags = GetUserFlags(agent.AgentID);
4186 if (RegionInfo.EstateSettings.IsBanned(agent.AgentID, flags))
4187 {
4188 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist",
4189 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
4190 reason = String.Format("Denied access to region {0}: You have been banned from that region.",
4191 RegionInfo.RegionName);
4192 return false;
4193 }
4194 }
4195 else
4196 {
4197 m_log.ErrorFormat("[CONNECTION BEGIN]: Estate Settings is null!");
4198 }
4199
4199 List<UUID> agentGroups = new List<UUID>(); 4200 List<UUID> agentGroups = new List<UUID>();
4200 4201
4201 if (m_groupsModule != null) 4202 if (m_groupsModule != null)
@@ -4392,36 +4393,42 @@ namespace OpenSim.Region.Framework.Scenes
4392 } 4393 }
4393 4394
4394 // We have to wait until the viewer contacts this region 4395 // We have to wait until the viewer contacts this region
4395 // after receiving the EnableSimulator HTTP Event Queue message. This triggers the viewer to send 4396 // after receiving the EnableSimulator HTTP Event Queue message (for the v1 teleport protocol)
4397 // or TeleportFinish (for the v2 teleport protocol). This triggers the viewer to send
4396 // a UseCircuitCode packet which in turn calls AddNewClient which finally creates the ScenePresence. 4398 // a UseCircuitCode packet which in turn calls AddNewClient which finally creates the ScenePresence.
4397 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); 4399 ScenePresence sp = WaitGetScenePresence(cAgentData.AgentID);
4398 4400
4399 if (childAgentUpdate != null) 4401 if (sp != null)
4400 { 4402 {
4401 if (cAgentData.SessionID != childAgentUpdate.ControllingClient.SessionId) 4403 if (cAgentData.SessionID != sp.ControllingClient.SessionId)
4402 { 4404 {
4403 m_log.WarnFormat("[SCENE]: Attempt to update agent {0} with invalid session id {1} (possibly from simulator in older version; tell them to update).", childAgentUpdate.UUID, cAgentData.SessionID); 4405 m_log.WarnFormat(
4406 "[SCENE]: Attempt to update agent {0} with invalid session id {1} (possibly from simulator in older version; tell them to update).",
4407 sp.UUID, cAgentData.SessionID);
4408
4404 Console.WriteLine(String.Format("[SCENE]: Attempt to update agent {0} ({1}) with invalid session id {2}", 4409 Console.WriteLine(String.Format("[SCENE]: Attempt to update agent {0} ({1}) with invalid session id {2}",
4405 childAgentUpdate.UUID, childAgentUpdate.ControllingClient.SessionId, cAgentData.SessionID)); 4410 sp.UUID, sp.ControllingClient.SessionId, cAgentData.SessionID));
4406 } 4411 }
4407 4412
4408 childAgentUpdate.ChildAgentDataUpdate(cAgentData); 4413 sp.ChildAgentDataUpdate(cAgentData);
4409 4414
4410 int ntimes = 20; 4415 int ntimes = 20;
4411 if (cAgentData.SenderWantsToWaitForRoot) 4416 if (cAgentData.SenderWantsToWaitForRoot)
4412 { 4417 {
4413 while (childAgentUpdate.IsChildAgent && ntimes-- > 0) 4418 while (sp.IsChildAgent && ntimes-- > 0)
4414 Thread.Sleep(1000); 4419 Thread.Sleep(1000);
4415 4420
4416 m_log.DebugFormat( 4421 m_log.DebugFormat(
4417 "[SCENE]: Found presence {0} {1} {2} in {3} after {4} waits", 4422 "[SCENE]: Found presence {0} {1} {2} in {3} after {4} waits",
4418 childAgentUpdate.Name, childAgentUpdate.UUID, childAgentUpdate.IsChildAgent ? "child" : "root", RegionInfo.RegionName, 20 - ntimes); 4423 sp.Name, sp.UUID, sp.IsChildAgent ? "child" : "root", Name, 20 - ntimes);
4419 4424
4420 if (childAgentUpdate.IsChildAgent) 4425 if (sp.IsChildAgent)
4421 return false; 4426 return false;
4422 } 4427 }
4428
4423 return true; 4429 return true;
4424 } 4430 }
4431
4425 return false; 4432 return false;
4426 } 4433 }
4427 4434
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index c4876b3..48bf6f3 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -294,10 +294,24 @@ namespace OpenSim.Region.Framework.Scenes
294 /// </summary> 294 /// </summary>
295 private Vector3 posLastSignificantMove; 295 private Vector3 posLastSignificantMove;
296 296
297 // For teleports and crossings callbacks 297 #region For teleports and crossings callbacks
298
299 /// <summary>
300 /// In the V1 teleport protocol, the destination simulator sends ReleaseAgent to this address.
301 /// </summary>
298 string m_callbackURI; 302 string m_callbackURI;
303
299 UUID m_originRegionID; 304 UUID m_originRegionID;
300 305
306 /// <summary>
307 /// Used by the entity transfer module to signal when the presence should not be closed because a subsequent
308 /// teleport is reusing the connection.
309 /// </summary>
310 /// <remarks>May be refactored or move somewhere else soon.</remarks>
311 public bool DoNotCloseAfterTeleport { get; set; }
312
313 #endregion
314
301 /// <value> 315 /// <value>
302 /// Script engines present in the scene 316 /// Script engines present in the scene
303 /// </value> 317 /// </value>
@@ -764,13 +778,6 @@ namespace OpenSim.Region.Framework.Scenes
764 } 778 }
765 } 779 }
766 780
767 /// <summary>
768 /// Used by the entity transfer module to signal when the presence should not be closed because a subsequent
769 /// teleport is reusing the connection.
770 /// </summary>
771 /// <remarks>May be refactored or move somewhere else soon.</remarks>
772 public bool DoNotCloseAfterTeleport { get; set; }
773
774 private float m_speedModifier = 1.0f; 781 private float m_speedModifier = 1.0f;
775 782
776 public float SpeedModifier 783 public float SpeedModifier
@@ -1516,14 +1523,14 @@ namespace OpenSim.Region.Framework.Scenes
1516 int count = 20; 1523 int count = 20;
1517 while (m_originRegionID.Equals(UUID.Zero) && count-- > 0) 1524 while (m_originRegionID.Equals(UUID.Zero) && count-- > 0)
1518 { 1525 {
1519 m_log.DebugFormat("[SCENE PRESENCE]: Agent {0} waiting for update in {1}", client.Name, Scene.RegionInfo.RegionName); 1526 m_log.DebugFormat("[SCENE PRESENCE]: Agent {0} waiting for update in {1}", client.Name, Scene.Name);
1520 Thread.Sleep(200); 1527 Thread.Sleep(200);
1521 } 1528 }
1522 1529
1523 if (m_originRegionID.Equals(UUID.Zero)) 1530 if (m_originRegionID.Equals(UUID.Zero))
1524 { 1531 {
1525 // Movement into region will fail 1532 // Movement into region will fail
1526 m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} never arrived", client.Name); 1533 m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} never arrived in {1}", client.Name, Scene.Name);
1527 return false; 1534 return false;
1528 } 1535 }
1529 1536
@@ -1829,8 +1836,14 @@ namespace OpenSim.Region.Framework.Scenes
1829 // Here's where you get them. 1836 // Here's where you get them.
1830 m_AgentControlFlags = flags; 1837 m_AgentControlFlags = flags;
1831 m_headrotation = agentData.HeadRotation; 1838 m_headrotation = agentData.HeadRotation;
1839 byte oldState = State;
1832 State = agentData.State; 1840 State = agentData.State;
1833 1841
1842 // We need to send this back to the client in order to stop the edit beams
1843 if ((oldState & (uint)AgentState.Editing) != 0 && State == (uint)AgentState.None)
1844 ControllingClient.SendAgentTerseUpdate(this);
1845
1846
1834 PhysicsActor actor = PhysicsActor; 1847 PhysicsActor actor = PhysicsActor;
1835 if (actor == null) 1848 if (actor == null)
1836 { 1849 {
@@ -3199,8 +3212,7 @@ namespace OpenSim.Region.Framework.Scenes
3199 } 3212 }
3200 3213
3201 // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m 3214 // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m
3202 if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance || 3215 if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance)
3203 Util.GetDistanceTo(CameraPosition, m_lastChildAgentUpdateCamPosition) >= Scene.ChildReprioritizationDistance)
3204 { 3216 {
3205 m_lastChildAgentUpdatePosition = AbsolutePosition; 3217 m_lastChildAgentUpdatePosition = AbsolutePosition;
3206 m_lastChildAgentUpdateCamPosition = CameraPosition; 3218 m_lastChildAgentUpdateCamPosition = CameraPosition;
diff --git a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs
index 0cbc5f9..d1d318c 100755
--- a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs
@@ -49,10 +49,20 @@ public class ExtendedPhysics : INonSharedRegionModule
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50 private static string LogHeader = "[EXTENDED PHYSICS]"; 50 private static string LogHeader = "[EXTENDED PHYSICS]";
51 51
52 // =============================================================
52 // Since BulletSim is a plugin, this these values aren't defined easily in one place. 53 // Since BulletSim is a plugin, this these values aren't defined easily in one place.
53 // This table must coorespond to an identical table in BSScene. 54 // This table must correspond to an identical table in BSScene.
55
56 // Per scene functions. See BSScene.
57
58 // Per avatar functions. See BSCharacter.
59
60 // Per prim functions. See BSPrim.
61 public const string PhysFunctGetLinksetType = "BulletSim.GetLinksetType";
54 public const string PhysFunctSetLinksetType = "BulletSim.SetLinksetType"; 62 public const string PhysFunctSetLinksetType = "BulletSim.SetLinksetType";
55 63
64 // =============================================================
65
56 private IConfig Configuration { get; set; } 66 private IConfig Configuration { get; set; }
57 private bool Enabled { get; set; } 67 private bool Enabled { get; set; }
58 private Scene BaseScene { get; set; } 68 private Scene BaseScene { get; set; }
@@ -123,6 +133,7 @@ public class ExtendedPhysics : INonSharedRegionModule
123 133
124 // Register as LSL functions all the [ScriptInvocation] marked methods. 134 // Register as LSL functions all the [ScriptInvocation] marked methods.
125 Comms.RegisterScriptInvocations(this); 135 Comms.RegisterScriptInvocations(this);
136 Comms.RegisterConstants(this);
126 137
127 // When an object is modified, we might need to update its extended physics parameters 138 // When an object is modified, we might need to update its extended physics parameters
128 BaseScene.EventManager.OnObjectAddedToScene += EventManager_OnObjectAddedToScene; 139 BaseScene.EventManager.OnObjectAddedToScene += EventManager_OnObjectAddedToScene;
@@ -136,7 +147,6 @@ public class ExtendedPhysics : INonSharedRegionModule
136 147
137 private void EventManager_OnObjectAddedToScene(SceneObjectGroup obj) 148 private void EventManager_OnObjectAddedToScene(SceneObjectGroup obj)
138 { 149 {
139 throw new NotImplementedException();
140 } 150 }
141 151
142 // Event generated when some property of a prim changes. 152 // Event generated when some property of a prim changes.
@@ -168,9 +178,11 @@ public class ExtendedPhysics : INonSharedRegionModule
168 public static int PHYS_LINKSET_TYPE_MANUAL = 2; 178 public static int PHYS_LINKSET_TYPE_MANUAL = 2;
169 179
170 [ScriptInvocation] 180 [ScriptInvocation]
171 public void physSetLinksetType(UUID hostID, UUID scriptID, int linksetType) 181 public int physSetLinksetType(UUID hostID, UUID scriptID, int linksetType)
172 { 182 {
173 if (!Enabled) return; 183 int ret = -1;
184
185 if (!Enabled) return ret;
174 186
175 // The part that is requesting the change. 187 // The part that is requesting the change.
176 SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID); 188 SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID);
@@ -186,7 +198,7 @@ public class ExtendedPhysics : INonSharedRegionModule
186 Physics.Manager.PhysicsActor rootPhysActor = rootPart.PhysActor; 198 Physics.Manager.PhysicsActor rootPhysActor = rootPart.PhysActor;
187 if (rootPhysActor != null) 199 if (rootPhysActor != null)
188 { 200 {
189 rootPhysActor.Extension(PhysFunctSetLinksetType, linksetType); 201 ret = (int)rootPhysActor.Extension(PhysFunctSetLinksetType, linksetType);
190 } 202 }
191 else 203 else
192 { 204 {
@@ -204,6 +216,49 @@ public class ExtendedPhysics : INonSharedRegionModule
204 { 216 {
205 m_log.WarnFormat("{0} physSetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID); 217 m_log.WarnFormat("{0} physSetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID);
206 } 218 }
219 return ret;
220 }
221
222 [ScriptInvocation]
223 public int physGetLinksetType(UUID hostID, UUID scriptID)
224 {
225 int ret = -1;
226
227 if (!Enabled) return ret;
228
229 // The part that is requesting the change.
230 SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID);
231
232 if (requestingPart != null)
233 {
234 // The type is is always on the root of a linkset.
235 SceneObjectGroup containingGroup = requestingPart.ParentGroup;
236 SceneObjectPart rootPart = containingGroup.RootPart;
237
238 if (rootPart != null)
239 {
240 Physics.Manager.PhysicsActor rootPhysActor = rootPart.PhysActor;
241 if (rootPhysActor != null)
242 {
243 ret = (int)rootPhysActor.Extension(PhysFunctGetLinksetType);
244 }
245 else
246 {
247 m_log.WarnFormat("{0} physGetLinksetType: root part does not have a physics actor. rootName={1}, hostID={2}",
248 LogHeader, rootPart.Name, hostID);
249 }
250 }
251 else
252 {
253 m_log.WarnFormat("{0} physGetLinksetType: root part does not exist. RequestingPartName={1}, hostID={2}",
254 LogHeader, requestingPart.Name, hostID);
255 }
256 }
257 else
258 {
259 m_log.WarnFormat("{0} physGetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID);
260 }
261 return ret;
207 } 262 }
208} 263}
209} 264}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index 7f94666..3afd52e 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -70,6 +70,17 @@ public abstract class BSLinkset
70 return ret; 70 return ret;
71 } 71 }
72 72
73 public class BSLinkInfo
74 {
75 public BSPrimLinkable member;
76 public BSLinkInfo(BSPrimLinkable pMember)
77 {
78 member = pMember;
79 }
80 }
81
82 public LinksetImplementation LinksetImpl { get; protected set; }
83
73 public BSPrimLinkable LinksetRoot { get; protected set; } 84 public BSPrimLinkable LinksetRoot { get; protected set; }
74 85
75 protected BSScene m_physicsScene { get; private set; } 86 protected BSScene m_physicsScene { get; private set; }
@@ -78,7 +89,8 @@ public abstract class BSLinkset
78 public int LinksetID { get; private set; } 89 public int LinksetID { get; private set; }
79 90
80 // The children under the root in this linkset. 91 // The children under the root in this linkset.
81 protected HashSet<BSPrimLinkable> m_children; 92 // protected HashSet<BSPrimLinkable> m_children;
93 protected Dictionary<BSPrimLinkable, BSLinkInfo> m_children;
82 94
83 // We lock the diddling of linkset classes to prevent any badness. 95 // We lock the diddling of linkset classes to prevent any badness.
84 // This locks the modification of the instances of this class. Changes 96 // This locks the modification of the instances of this class. Changes
@@ -109,7 +121,7 @@ public abstract class BSLinkset
109 m_nextLinksetID = 1; 121 m_nextLinksetID = 1;
110 m_physicsScene = scene; 122 m_physicsScene = scene;
111 LinksetRoot = parent; 123 LinksetRoot = parent;
112 m_children = new HashSet<BSPrimLinkable>(); 124 m_children = new Dictionary<BSPrimLinkable, BSLinkInfo>();
113 LinksetMass = parent.RawMass; 125 LinksetMass = parent.RawMass;
114 Rebuilding = false; 126 Rebuilding = false;
115 127
@@ -170,17 +182,7 @@ public abstract class BSLinkset
170 bool ret = false; 182 bool ret = false;
171 lock (m_linksetActivityLock) 183 lock (m_linksetActivityLock)
172 { 184 {
173 ret = m_children.Contains(child); 185 ret = m_children.ContainsKey(child);
174 /* Safer version but the above should work
175 foreach (BSPrimLinkable bp in m_children)
176 {
177 if (child.LocalID == bp.LocalID)
178 {
179 ret = true;
180 break;
181 }
182 }
183 */
184 } 186 }
185 return ret; 187 return ret;
186 } 188 }
@@ -194,7 +196,24 @@ public abstract class BSLinkset
194 lock (m_linksetActivityLock) 196 lock (m_linksetActivityLock)
195 { 197 {
196 action(LinksetRoot); 198 action(LinksetRoot);
197 foreach (BSPrimLinkable po in m_children) 199 foreach (BSPrimLinkable po in m_children.Keys)
200 {
201 if (action(po))
202 break;
203 }
204 }
205 return ret;
206 }
207
208 // Perform an action on each member of the linkset including root prim.
209 // Depends on the action on whether this should be done at taint time.
210 public delegate bool ForEachLinkInfoAction(BSLinkInfo obj);
211 public virtual bool ForEachLinkInfo(ForEachLinkInfoAction action)
212 {
213 bool ret = false;
214 lock (m_linksetActivityLock)
215 {
216 foreach (BSLinkInfo po in m_children.Values)
198 { 217 {
199 if (action(po)) 218 if (action(po))
200 break; 219 break;
@@ -364,7 +383,7 @@ public abstract class BSLinkset
364 { 383 {
365 lock (m_linksetActivityLock) 384 lock (m_linksetActivityLock)
366 { 385 {
367 foreach (BSPrimLinkable bp in m_children) 386 foreach (BSPrimLinkable bp in m_children.Keys)
368 { 387 {
369 mass += bp.RawMass; 388 mass += bp.RawMass;
370 } 389 }
@@ -382,7 +401,7 @@ public abstract class BSLinkset
382 com = LinksetRoot.Position * LinksetRoot.RawMass; 401 com = LinksetRoot.Position * LinksetRoot.RawMass;
383 float totalMass = LinksetRoot.RawMass; 402 float totalMass = LinksetRoot.RawMass;
384 403
385 foreach (BSPrimLinkable bp in m_children) 404 foreach (BSPrimLinkable bp in m_children.Keys)
386 { 405 {
387 com += bp.Position * bp.RawMass; 406 com += bp.Position * bp.RawMass;
388 totalMass += bp.RawMass; 407 totalMass += bp.RawMass;
@@ -401,7 +420,7 @@ public abstract class BSLinkset
401 { 420 {
402 com = LinksetRoot.Position; 421 com = LinksetRoot.Position;
403 422
404 foreach (BSPrimLinkable bp in m_children) 423 foreach (BSPrimLinkable bp in m_children.Keys)
405 { 424 {
406 com += bp.Position; 425 com += bp.Position;
407 } 426 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
index 6359046..085d195 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
@@ -42,6 +42,7 @@ public sealed class BSLinksetCompound : BSLinkset
42 public BSLinksetCompound(BSScene scene, BSPrimLinkable parent) 42 public BSLinksetCompound(BSScene scene, BSPrimLinkable parent)
43 : base(scene, parent) 43 : base(scene, parent)
44 { 44 {
45 LinksetImpl = LinksetImplementation.Compound;
45 } 46 }
46 47
47 // ================================================================ 48 // ================================================================
@@ -257,7 +258,7 @@ public sealed class BSLinksetCompound : BSLinkset
257 { 258 {
258 if (!HasChild(child)) 259 if (!HasChild(child))
259 { 260 {
260 m_children.Add(child); 261 m_children.Add(child, new BSLinkInfo(child));
261 262
262 DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); 263 DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID);
263 264
@@ -353,7 +354,7 @@ public sealed class BSLinksetCompound : BSLinkset
353 354
354 // Add the shapes of all the components of the linkset 355 // Add the shapes of all the components of the linkset
355 int memberIndex = 1; 356 int memberIndex = 1;
356 ForEachMember(delegate(BSPrimLinkable cPrim) 357 ForEachMember((cPrim) =>
357 { 358 {
358 if (IsRoot(cPrim)) 359 if (IsRoot(cPrim))
359 { 360 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
index f17d698..4bac222 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
@@ -36,8 +36,78 @@ public sealed class BSLinksetConstraints : BSLinkset
36{ 36{
37 // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]"; 37 // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]";
38 38
39 public class BSLinkInfoConstraint : BSLinkInfo
40 {
41 public ConstraintType constraintType;
42 public BSConstraint constraint;
43 public OMV.Vector3 linearLimitLow;
44 public OMV.Vector3 linearLimitHigh;
45 public OMV.Vector3 angularLimitLow;
46 public OMV.Vector3 angularLimitHigh;
47 public bool useFrameOffset;
48 public bool enableTransMotor;
49 public float transMotorMaxVel;
50 public float transMotorMaxForce;
51 public float cfm;
52 public float erp;
53 public float solverIterations;
54
55 public BSLinkInfoConstraint(BSPrimLinkable pMember)
56 : base(pMember)
57 {
58 constraint = null;
59 ResetToFixedConstraint();
60 }
61
62 // Set all the parameters for this constraint to a fixed, non-movable constraint.
63 public void ResetToFixedConstraint()
64 {
65 constraintType = ConstraintType.D6_CONSTRAINT_TYPE;
66 linearLimitLow = OMV.Vector3.Zero;
67 linearLimitHigh = OMV.Vector3.Zero;
68 angularLimitLow = OMV.Vector3.Zero;
69 angularLimitHigh = OMV.Vector3.Zero;
70 useFrameOffset = BSParam.LinkConstraintUseFrameOffset;
71 enableTransMotor = BSParam.LinkConstraintEnableTransMotor;
72 transMotorMaxVel = BSParam.LinkConstraintTransMotorMaxVel;
73 transMotorMaxForce = BSParam.LinkConstraintTransMotorMaxForce;
74 cfm = BSParam.LinkConstraintCFM;
75 erp = BSParam.LinkConstraintERP;
76 solverIterations = BSParam.LinkConstraintSolverIterations;
77 }
78
79 // Given a constraint, apply the current constraint parameters to same.
80 public void SetConstraintParameters(BSConstraint constrain)
81 {
82 switch (constraintType)
83 {
84 case ConstraintType.D6_CONSTRAINT_TYPE:
85 BSConstraint6Dof constrain6dof = constrain as BSConstraint6Dof;
86 if (constrain6dof != null)
87 {
88 // zero linear and angular limits makes the objects unable to move in relation to each other
89 constrain6dof.SetLinearLimits(linearLimitLow, linearLimitHigh);
90 constrain6dof.SetAngularLimits(angularLimitLow, angularLimitHigh);
91
92 // tweek the constraint to increase stability
93 constrain6dof.UseFrameOffset(useFrameOffset);
94 constrain6dof.TranslationalLimitMotor(enableTransMotor, transMotorMaxVel, transMotorMaxForce);
95 constrain6dof.SetCFMAndERP(cfm, erp);
96 if (solverIterations != 0f)
97 {
98 constrain6dof.SetSolverIterations(solverIterations);
99 }
100 }
101 break;
102 default:
103 break;
104 }
105 }
106 }
107
39 public BSLinksetConstraints(BSScene scene, BSPrimLinkable parent) : base(scene, parent) 108 public BSLinksetConstraints(BSScene scene, BSPrimLinkable parent) : base(scene, parent)
40 { 109 {
110 LinksetImpl = LinksetImplementation.Constraint;
41 } 111 }
42 112
43 // When physical properties are changed the linkset needs to recalculate 113 // When physical properties are changed the linkset needs to recalculate
@@ -142,7 +212,7 @@ public sealed class BSLinksetConstraints : BSLinkset
142 { 212 {
143 if (!HasChild(child)) 213 if (!HasChild(child))
144 { 214 {
145 m_children.Add(child); 215 m_children.Add(child, new BSLinkInfoConstraint(child));
146 216
147 DetailLog("{0},BSLinksetConstraints.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); 217 DetailLog("{0},BSLinksetConstraints.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID);
148 218
@@ -190,73 +260,74 @@ public sealed class BSLinksetConstraints : BSLinkset
190 } 260 }
191 261
192 // Create a static constraint between the two passed objects 262 // Create a static constraint between the two passed objects
193 private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSPrimLinkable childPrim) 263 private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSLinkInfo li)
194 { 264 {
265 BSLinkInfoConstraint liConstraint = li as BSLinkInfoConstraint;
266 if (liConstraint == null)
267 return null;
268
195 // Zero motion for children so they don't interpolate 269 // Zero motion for children so they don't interpolate
196 childPrim.ZeroMotion(true); 270 li.member.ZeroMotion(true);
197
198 // Relative position normalized to the root prim
199 // Essentually a vector pointing from center of rootPrim to center of childPrim
200 OMV.Vector3 childRelativePosition = childPrim.Position - rootPrim.Position;
201
202 // real world coordinate of midpoint between the two objects
203 OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2);
204
205 DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}",
206 rootPrim.LocalID,
207 rootPrim.LocalID, rootPrim.PhysBody.AddrString,
208 childPrim.LocalID, childPrim.PhysBody.AddrString,
209 rootPrim.Position, childPrim.Position, midPoint);
210
211 // create a constraint that allows no freedom of movement between the two objects
212 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
213
214 BSConstraint6Dof constrain = new BSConstraint6Dof(
215 m_physicsScene.World, rootPrim.PhysBody, childPrim.PhysBody, midPoint, true, true );
216 // PhysicsScene.World, childPrim.BSBody, rootPrim.BSBody, midPoint, true, true );
217
218 /* NOTE: below is an attempt to build constraint with full frame computation, etc.
219 * Using the midpoint is easier since it lets the Bullet code manipulate the transforms
220 * of the objects.
221 * Code left for future programmers.
222 // ==================================================================================
223 // relative position normalized to the root prim
224 OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation);
225 OMV.Vector3 childRelativePosition = (childPrim.Position - rootPrim.Position) * invThisOrientation;
226
227 // relative rotation of the child to the parent
228 OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation;
229 OMV.Quaternion inverseChildRelativeRotation = OMV.Quaternion.Inverse(childRelativeRotation);
230
231 DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
232 BS6DofConstraint constrain = new BS6DofConstraint(
233 PhysicsScene.World, rootPrim.Body, childPrim.Body,
234 OMV.Vector3.Zero,
235 OMV.Quaternion.Inverse(rootPrim.Orientation),
236 OMV.Vector3.Zero,
237 OMV.Quaternion.Inverse(childPrim.Orientation),
238 true,
239 true
240 );
241 // ==================================================================================
242 */
243 271
244 m_physicsScene.Constraints.AddConstraint(constrain); 272 BSConstraint constrain = null;
245 273
246 // zero linear and angular limits makes the objects unable to move in relation to each other 274 switch (liConstraint.constraintType)
247 constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
248 constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
249
250 // tweek the constraint to increase stability
251 constrain.UseFrameOffset(BSParam.LinkConstraintUseFrameOffset);
252 constrain.TranslationalLimitMotor(BSParam.LinkConstraintEnableTransMotor,
253 BSParam.LinkConstraintTransMotorMaxVel,
254 BSParam.LinkConstraintTransMotorMaxForce);
255 constrain.SetCFMAndERP(BSParam.LinkConstraintCFM, BSParam.LinkConstraintERP);
256 if (BSParam.LinkConstraintSolverIterations != 0f)
257 { 275 {
258 constrain.SetSolverIterations(BSParam.LinkConstraintSolverIterations); 276 case ConstraintType.D6_CONSTRAINT_TYPE:
277 // Relative position normalized to the root prim
278 // Essentually a vector pointing from center of rootPrim to center of li.member
279 OMV.Vector3 childRelativePosition = liConstraint.member.Position - rootPrim.Position;
280
281 // real world coordinate of midpoint between the two objects
282 OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2);
283
284 DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}",
285 rootPrim.LocalID,
286 rootPrim.LocalID, rootPrim.PhysBody.AddrString,
287 liConstraint.member.LocalID, liConstraint.member.PhysBody.AddrString,
288 rootPrim.Position, liConstraint.member.Position, midPoint);
289
290 // create a constraint that allows no freedom of movement between the two objects
291 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
292
293 constrain = new BSConstraint6Dof(
294 m_physicsScene.World, rootPrim.PhysBody, liConstraint.member.PhysBody, midPoint, true, true );
295
296 /* NOTE: below is an attempt to build constraint with full frame computation, etc.
297 * Using the midpoint is easier since it lets the Bullet code manipulate the transforms
298 * of the objects.
299 * Code left for future programmers.
300 // ==================================================================================
301 // relative position normalized to the root prim
302 OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation);
303 OMV.Vector3 childRelativePosition = (liConstraint.member.Position - rootPrim.Position) * invThisOrientation;
304
305 // relative rotation of the child to the parent
306 OMV.Quaternion childRelativeRotation = invThisOrientation * liConstraint.member.Orientation;
307 OMV.Quaternion inverseChildRelativeRotation = OMV.Quaternion.Inverse(childRelativeRotation);
308
309 DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, liConstraint.member.LocalID);
310 constrain = new BS6DofConstraint(
311 PhysicsScene.World, rootPrim.Body, liConstraint.member.Body,
312 OMV.Vector3.Zero,
313 OMV.Quaternion.Inverse(rootPrim.Orientation),
314 OMV.Vector3.Zero,
315 OMV.Quaternion.Inverse(liConstraint.member.Orientation),
316 true,
317 true
318 );
319 // ==================================================================================
320 */
321
322 break;
323 default:
324 break;
259 } 325 }
326
327 liConstraint.SetConstraintParameters(constrain);
328
329 m_physicsScene.Constraints.AddConstraint(constrain);
330
260 return constrain; 331 return constrain;
261 } 332 }
262 333
@@ -317,23 +388,24 @@ public sealed class BSLinksetConstraints : BSLinkset
317 return; // Note the 'finally' clause at the botton which will get executed. 388 return; // Note the 'finally' clause at the botton which will get executed.
318 } 389 }
319 390
320 foreach (BSPrimLinkable child in m_children) 391 ForEachLinkInfo((li) =>
321 { 392 {
322 // A child in the linkset physically shows the mass of the whole linkset. 393 // A child in the linkset physically shows the mass of the whole linkset.
323 // This allows Bullet to apply enough force on the child to move the whole linkset. 394 // This allows Bullet to apply enough force on the child to move the whole linkset.
324 // (Also do the mass stuff before recomputing the constraint so mass is not zero.) 395 // (Also do the mass stuff before recomputing the constraint so mass is not zero.)
325 child.UpdatePhysicalMassProperties(linksetMass, true); 396 li.member.UpdatePhysicalMassProperties(linksetMass, true);
326 397
327 BSConstraint constrain; 398 BSConstraint constrain;
328 if (!m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, child.PhysBody, out constrain)) 399 if (!m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, li.member.PhysBody, out constrain))
329 { 400 {
330 // If constraint doesn't exist yet, create it. 401 // If constraint doesn't exist yet, create it.
331 constrain = BuildConstraint(LinksetRoot, child); 402 constrain = BuildConstraint(LinksetRoot, li);
332 } 403 }
333 constrain.RecomputeConstraintVariables(linksetMass); 404 constrain.RecomputeConstraintVariables(linksetMass);
334 405
335 // PhysicsScene.PE.DumpConstraint(PhysicsScene.World, constrain.Constraint); // DEBUG DEBUG 406 // PhysicsScene.PE.DumpConstraint(PhysicsScene.World, constrain.Constraint); // DEBUG DEBUG
336 } 407 return false; // 'false' says to keep processing other members
408 });
337 } 409 }
338 finally 410 finally
339 { 411 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index e92a1d2..a0b6abc 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -1541,6 +1541,50 @@ public class BSPrim : BSPhysObject
1541 PhysicalActors.RemoveDependencies(); 1541 PhysicalActors.RemoveDependencies();
1542 } 1542 }
1543 1543
1544 #region Extension
1545 public override object Extension(string pFunct, params object[] pParams)
1546 {
1547 object ret = null;
1548 switch (pFunct)
1549 {
1550 case BSScene.PhysFunctGetLinksetType:
1551 {
1552 BSPrimLinkable myHandle = this as BSPrimLinkable;
1553 if (myHandle != null)
1554 {
1555 ret = (object)myHandle.LinksetType;
1556 }
1557 m_log.DebugFormat("{0} Extension.physGetLinksetType, type={1}", LogHeader, ret);
1558 break;
1559 }
1560 case BSScene.PhysFunctSetLinksetType:
1561 {
1562 if (pParams.Length > 0)
1563 {
1564 BSLinkset.LinksetImplementation linksetType = (BSLinkset.LinksetImplementation)pParams[0];
1565 BSPrimLinkable myHandle = this as BSPrimLinkable;
1566 if (myHandle != null && myHandle.Linkset.IsRoot(myHandle))
1567 {
1568 PhysScene.TaintedObject("BSPrim.PhysFunctSetLinksetType", delegate()
1569 {
1570 // Cause the linkset type to change
1571 m_log.DebugFormat("{0} Extension.physSetLinksetType, oldType={1}, newType={2}",
1572 LogHeader, myHandle.Linkset.LinksetImpl, linksetType);
1573 myHandle.ConvertLinkset(linksetType);
1574 });
1575 }
1576 ret = (object)(int)linksetType;
1577 }
1578 break;
1579 }
1580 default:
1581 ret = base.Extension(pFunct, pParams);
1582 break;
1583 }
1584 return ret;
1585 }
1586 #endregion // Extension
1587
1544 // The physics engine says that properties have updated. Update same and inform 1588 // The physics engine says that properties have updated. Update same and inform
1545 // the world that things have changed. 1589 // the world that things have changed.
1546 // NOTE: BSPrim.UpdateProperties is overloaded by BSPrimLinkable which modifies updates from root and children prims. 1590 // NOTE: BSPrim.UpdateProperties is overloaded by BSPrimLinkable which modifies updates from root and children prims.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs
index 2f392da..7179a6d 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs
@@ -233,5 +233,46 @@ public class BSPrimLinkable : BSPrimDisplaced
233 base.HasSomeCollision = value; 233 base.HasSomeCollision = value;
234 } 234 }
235 } 235 }
236
237 // Convert the existing linkset of this prim into a new type.
238 public bool ConvertLinkset(BSLinkset.LinksetImplementation newType)
239 {
240 bool ret = false;
241 if (LinksetType != newType)
242 {
243 // Set the implementation type first so the call to BSLinkset.Factory gets the new type.
244 this.LinksetType = newType;
245
246 BSLinkset oldLinkset = this.Linkset;
247 BSLinkset newLinkset = BSLinkset.Factory(PhysScene, this);
248
249 this.Linkset = newLinkset;
250
251 // Pick up any physical dependencies this linkset might have in the physics engine.
252 oldLinkset.RemoveDependencies(this);
253
254 // Create a list of the children (mainly because can't interate through a list that's changing)
255 List<BSPrimLinkable> children = new List<BSPrimLinkable>();
256 oldLinkset.ForEachMember((child) =>
257 {
258 if (!oldLinkset.IsRoot(child))
259 children.Add(child);
260 return false; // 'false' says to continue to next member
261 });
262
263 // Remove the children from the old linkset and add to the new (will be a new instance from the factory)
264 foreach (BSPrimLinkable child in children)
265 {
266 oldLinkset.RemoveMeFromLinkset(child);
267 newLinkset.AddMeToLinkset(child);
268 child.Linkset = newLinkset;
269 }
270
271 // Force the shape and linkset to get reconstructed
272 newLinkset.Refresh(this);
273 this.ForceBodyShapeRebuild(true /* inTaintTime */);
274 }
275 return ret;
276 }
236} 277}
237} 278}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index 41aca3b..79ac5a5 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -862,6 +862,23 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
862 862
863 public override bool IsThreaded { get { return false; } } 863 public override bool IsThreaded { get { return false; } }
864 864
865 #region Extensions
866 // =============================================================
867 // Per scene functions. See below.
868
869 // Per avatar functions. See BSCharacter.
870
871 // Per prim functions. See BSPrim.
872 public const string PhysFunctGetLinksetType = "BulletSim.GetLinksetType";
873 public const string PhysFunctSetLinksetType = "BulletSim.SetLinksetType";
874 // =============================================================
875
876 public override object Extension(string pFunct, params object[] pParams)
877 {
878 return base.Extension(pFunct, pParams);
879 }
880 #endregion // Extensions
881
865 #region Taints 882 #region Taints
866 // The simulation execution order is: 883 // The simulation execution order is:
867 // Simulate() 884 // Simulate()
diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
index 739e984..44bfd42 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
@@ -418,7 +418,8 @@ namespace OpenSim.Region.Physics.Manager
418 // Extendable interface for new, physics engine specific operations 418 // Extendable interface for new, physics engine specific operations
419 public virtual object Extension(string pFunct, params object[] pParams) 419 public virtual object Extension(string pFunct, params object[] pParams)
420 { 420 {
421 throw new NotImplementedException(); 421 // A NOP of the physics engine does not implement this feature
422 return null;
422 } 423 }
423 } 424 }
424 425
diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
index 52f2809..dd9bbc1 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
@@ -393,7 +393,8 @@ namespace OpenSim.Region.Physics.Manager
393 // Extendable interface for new, physics engine specific operations 393 // Extendable interface for new, physics engine specific operations
394 public virtual object Extension(string pFunct, params object[] pParams) 394 public virtual object Extension(string pFunct, params object[] pParams)
395 { 395 {
396 throw new NotImplementedException(); 396 // A NOP if the extension thing is not implemented by the physics engine
397 return null;
397 } 398 }
398 } 399 }
399} 400}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
index bd776b6..edcdfbc 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
@@ -319,7 +319,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
319 319
320 object[] convertedParms = new object[parms.Length]; 320 object[] convertedParms = new object[parms.Length];
321 for (int i = 0; i < parms.Length; i++) 321 for (int i = 0; i < parms.Length; i++)
322 convertedParms[i] = ConvertFromLSL(parms[i],signature[i], fname); 322 convertedParms[i] = ConvertFromLSL(parms[i], signature[i], fname);
323 323
324 // now call the function, the contract with the function is that it will always return 324 // now call the function, the contract with the function is that it will always return
325 // non-null but don't trust it completely 325 // non-null but don't trust it completely
@@ -448,7 +448,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
448 } 448 }
449 } 449 }
450 450
451 MODError(String.Format("{1}: parameter type mismatch; expecting {0}",type.Name, fname)); 451 MODError(String.Format("{0}: parameter type mismatch; expecting {1}, type(parm)={2}", fname, type.Name, lslparm.GetType()));
452 return null; 452 return null;
453 } 453 }
454 454
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
index 9e32f40..6aa717d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
@@ -937,7 +937,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
937 { 937 {
938 string retval = null; 938 string retval = null;
939 if (value is int) 939 if (value is int)
940 retval = ((int)value).ToString(); 940 retval = String.Format("new LSL_Types.LSLInteger({0})",((int)value).ToString());
941 else if (value is float) 941 else if (value is float)
942 retval = String.Format("new LSL_Types.LSLFloat({0})",((float)value).ToString()); 942 retval = String.Format("new LSL_Types.LSLFloat({0})",((float)value).ToString());
943 else if (value is string) 943 else if (value is string)