aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs5
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs18
-rw-r--r--OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs121
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs13
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs11
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs119
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs28
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs13
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs72
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs4
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSParam.cs41
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs108
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs48
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs23
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt13
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs150
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTests.cs56
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs95
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdeScene.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs30
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs165
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs2
23 files changed, 974 insertions, 166 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index bae41fb..0a39ded 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -4963,8 +4963,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4963 // in that direction, even though we don't model this on the server. Implementing this in the future 4963 // in that direction, even though we don't model this on the server. Implementing this in the future
4964 // may improve movement smoothness. 4964 // may improve movement smoothness.
4965// acceleration = new Vector3(1, 0, 0); 4965// acceleration = new Vector3(1, 0, 0);
4966 4966
4967 angularVelocity = Vector3.Zero; 4967 angularVelocity = presence.AngularVelocity;
4968 rotation = presence.Rotation;
4968 4969
4969 if (sendTexture) 4970 if (sendTexture)
4970 textureEntry = presence.Appearance.Texture.GetBytes(); 4971 textureEntry = presence.Appearance.Texture.GetBytes();
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
index 7332415..faee189 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
@@ -214,9 +214,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
214 public void HandleTaskItemUpdateFromTransaction( 214 public void HandleTaskItemUpdateFromTransaction(
215 IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item) 215 IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item)
216 { 216 {
217 m_log.DebugFormat( 217// m_log.DebugFormat(
218 "[ASSET TRANSACTION MODULE] Called HandleTaskItemUpdateFromTransaction with item {0} in {1} for {2} in {3}", 218// "[ASSET TRANSACTION MODULE]: Called HandleTaskItemUpdateFromTransaction with item {0} in {1} for {2} in {3}",
219 item.Name, part.Name, remoteClient.Name, m_Scene.RegionInfo.RegionName); 219// item.Name, part.Name, remoteClient.Name, m_Scene.RegionInfo.RegionName);
220 220
221 AgentAssetTransactions transactions = 221 AgentAssetTransactions transactions =
222 GetUserTransactions(remoteClient.AgentId); 222 GetUserTransactions(remoteClient.AgentId);
@@ -230,15 +230,17 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
230 /// </summary> 230 /// </summary>
231 /// <param name="remoteClient"></param> 231 /// <param name="remoteClient"></param>
232 /// <param name="assetID"></param> 232 /// <param name="assetID"></param>
233 /// <param name="transaction"></param> 233 /// <param name="transactionID"></param>
234 /// <param name="type"></param> 234 /// <param name="type"></param>
235 /// <param name="data"></param></param> 235 /// <param name="data"></param></param>
236 /// <param name="tempFile"></param> 236 /// <param name="tempFile"></param>
237 public void HandleUDPUploadRequest(IClientAPI remoteClient, 237 public void HandleUDPUploadRequest(IClientAPI remoteClient,
238 UUID assetID, UUID transaction, sbyte type, byte[] data, 238 UUID assetID, UUID transactionID, sbyte type, byte[] data,
239 bool storeLocal, bool tempFile) 239 bool storeLocal, bool tempFile)
240 { 240 {
241// m_log.Debug("HandleUDPUploadRequest - assetID: " + assetID.ToString() + " transaction: " + transaction.ToString() + " type: " + type.ToString() + " storelocal: " + storeLocal + " tempFile: " + tempFile); 241// m_log.DebugFormat(
242// "[ASSET TRANSACTION MODULE]: HandleUDPUploadRequest - assetID: {0}, transaction {1}, type {2}, storeLocal {3}, tempFile {4}, data.Length {5}",
243// assetID, transactionID, type, storeLocal, tempFile, data.Length);
242 244
243 if (((AssetType)type == AssetType.Texture || 245 if (((AssetType)type == AssetType.Texture ||
244 (AssetType)type == AssetType.Sound || 246 (AssetType)type == AssetType.Sound ||
@@ -274,8 +276,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
274 } 276 }
275 277
276 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); 278 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
277 AssetXferUploader uploader = transactions.RequestXferUploader(transaction); 279 AssetXferUploader uploader = transactions.RequestXferUploader(transactionID);
278 uploader.StartUpload(remoteClient, assetID, transaction, type, data, storeLocal, tempFile); 280 uploader.StartUpload(remoteClient, assetID, transactionID, type, data, storeLocal, tempFile);
279 } 281 }
280 282
281 /// <summary> 283 /// <summary>
diff --git a/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs b/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs
index da39e95..0bb4567 100644
--- a/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs
@@ -37,6 +37,7 @@ namespace OpenSim.Region.Framework.Interfaces
37 { 37 {
38 bool CreateStore(string value, ref UUID result); 38 bool CreateStore(string value, ref UUID result);
39 bool DestroyStore(UUID storeID); 39 bool DestroyStore(UUID storeID);
40 bool TestStore(UUID storeID);
40 bool TestPath(UUID storeID, string path, bool useJson); 41 bool TestPath(UUID storeID, string path, bool useJson);
41 bool SetValue(UUID storeID, string path, string value, bool useJson); 42 bool SetValue(UUID storeID, string path, string value, bool useJson);
42 bool RemoveValue(UUID storeID, string path); 43 bool RemoveValue(UUID storeID, string path);
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index f024f52..6005f07 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -204,6 +204,11 @@ namespace OpenSim.Region.Framework.Scenes
204 204
205 private const int LAND_VELOCITYMAG_MAX = 12; 205 private const int LAND_VELOCITYMAG_MAX = 12;
206 206
207 private const float FLY_ROLL_MAX_RADIANS = 1.1f;
208
209 private const float FLY_ROLL_RADIANS_PER_UPDATE = 0.06f;
210 private const float FLY_ROLL_RESET_RADIANS_PER_UPDATE = 0.02f;
211
207 private float m_health = 100f; 212 private float m_health = 100f;
208 213
209 protected ulong crossingFromRegion; 214 protected ulong crossingFromRegion;
@@ -604,6 +609,14 @@ namespace OpenSim.Region.Framework.Scenes
604 } 609 }
605 } 610 }
606 611
612 // Used for limited viewer 'fake' user rotations.
613 private Vector3 m_AngularVelocity = Vector3.Zero;
614
615 public Vector3 AngularVelocity
616 {
617 get { return m_AngularVelocity; }
618 }
619
607 public bool IsChildAgent { get; set; } 620 public bool IsChildAgent { get; set; }
608 public bool IsLoggingIn { get; set; } 621 public bool IsLoggingIn { get; set; }
609 622
@@ -734,6 +747,8 @@ namespace OpenSim.Region.Framework.Scenes
734 747
735 #endregion 748 #endregion
736 749
750
751
737 #region Constructor(s) 752 #region Constructor(s)
738 753
739 public ScenePresence( 754 public ScenePresence(
@@ -1223,6 +1238,85 @@ namespace OpenSim.Region.Framework.Scenes
1223 ControllingClient.StopFlying(this); 1238 ControllingClient.StopFlying(this);
1224 } 1239 }
1225 1240
1241 /// <summary>
1242 /// Applies a roll accumulator to the avatar's angular velocity for the avatar fly roll effect.
1243 /// </summary>
1244 /// <param name="amount">Postive or negative roll amount in radians</param>
1245 private void ApplyFlyingRoll(float amount, bool PressingUp, bool PressingDown)
1246 {
1247
1248 float rollAmount = Util.Clamp(m_AngularVelocity.Z + amount, -FLY_ROLL_MAX_RADIANS, FLY_ROLL_MAX_RADIANS);
1249 m_AngularVelocity.Z = rollAmount;
1250
1251 // APPLY EXTRA consideration for flying up and flying down during this time.
1252 // if we're turning left
1253 if (amount > 0)
1254 {
1255
1256 // If we're at the max roll and pressing up, we want to swing BACK a bit
1257 // Automatically adds noise
1258 if (PressingUp)
1259 {
1260 if (m_AngularVelocity.Z >= FLY_ROLL_MAX_RADIANS - 0.04f)
1261 m_AngularVelocity.Z -= 0.9f;
1262 }
1263 // If we're at the max roll and pressing down, we want to swing MORE a bit
1264 if (PressingDown)
1265 {
1266 if (m_AngularVelocity.Z >= FLY_ROLL_MAX_RADIANS && m_AngularVelocity.Z < FLY_ROLL_MAX_RADIANS + 0.6f)
1267 m_AngularVelocity.Z += 0.6f;
1268 }
1269 }
1270 else // we're turning right.
1271 {
1272 // If we're at the max roll and pressing up, we want to swing BACK a bit
1273 // Automatically adds noise
1274 if (PressingUp)
1275 {
1276 if (m_AngularVelocity.Z <= (-FLY_ROLL_MAX_RADIANS))
1277 m_AngularVelocity.Z += 0.6f;
1278 }
1279 // If we're at the max roll and pressing down, we want to swing MORE a bit
1280 if (PressingDown)
1281 {
1282 if (m_AngularVelocity.Z >= -FLY_ROLL_MAX_RADIANS - 0.6f)
1283 m_AngularVelocity.Z -= 0.6f;
1284 }
1285 }
1286 }
1287
1288 /// <summary>
1289 /// incrementally sets roll amount to zero
1290 /// </summary>
1291 /// <param name="amount">Positive roll amount in radians</param>
1292 /// <returns></returns>
1293 private float CalculateFlyingRollResetToZero(float amount)
1294 {
1295 const float rollMinRadians = 0f;
1296
1297 if (m_AngularVelocity.Z > 0)
1298 {
1299
1300 float leftOverToMin = m_AngularVelocity.Z - rollMinRadians;
1301 if (amount > leftOverToMin)
1302 return -leftOverToMin;
1303 else
1304 return -amount;
1305
1306 }
1307 else
1308 {
1309
1310 float leftOverToMin = -m_AngularVelocity.Z - rollMinRadians;
1311 if (amount > leftOverToMin)
1312 return leftOverToMin;
1313 else
1314 return amount;
1315 }
1316 }
1317
1318
1319
1226 // neighbouring regions we have enabled a child agent in 1320 // neighbouring regions we have enabled a child agent in
1227 // holds the seed cap for the child agent in that region 1321 // holds the seed cap for the child agent in that region
1228 private Dictionary<ulong, string> m_knownChildRegions = new Dictionary<ulong, string>(); 1322 private Dictionary<ulong, string> m_knownChildRegions = new Dictionary<ulong, string>();
@@ -1739,6 +1833,33 @@ namespace OpenSim.Region.Framework.Scenes
1739 bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || 1833 bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) ||
1740 ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); 1834 ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
1741 1835
1836
1837 //m_log.Debug("[CONTROL]: " +flags);
1838 // Applies a satisfying roll effect to the avatar when flying.
1839 if (((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) != 0) && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0))
1840 {
1841
1842 ApplyFlyingRoll(FLY_ROLL_RADIANS_PER_UPDATE, ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0), ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0));
1843
1844
1845 }
1846 else if (((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) != 0) &&
1847 ((flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0))
1848 {
1849 ApplyFlyingRoll(-FLY_ROLL_RADIANS_PER_UPDATE, ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0), ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0));
1850
1851
1852 }
1853 else
1854 {
1855 if (m_AngularVelocity.Z != 0)
1856 m_AngularVelocity.Z += CalculateFlyingRollResetToZero(FLY_ROLL_RESET_RADIANS_PER_UPDATE);
1857
1858 }
1859
1860
1861
1862
1742 if (Flying && IsColliding && controlland) 1863 if (Flying && IsColliding && controlland)
1743 { 1864 {
1744 // nesting this check because LengthSquared() is expensive and we don't 1865 // nesting this check because LengthSquared() is expensive and we don't
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
index e68764a..b9b3ebc 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
@@ -221,6 +221,19 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
221 /// 221 ///
222 /// </summary> 222 /// </summary>
223 // ----------------------------------------------------------------- 223 // -----------------------------------------------------------------
224 public bool TestStore(UUID storeID)
225 {
226 if (! m_enabled) return false;
227
228 lock (m_JsonValueStore)
229 return m_JsonValueStore.ContainsKey(storeID);
230 }
231
232 // -----------------------------------------------------------------
233 /// <summary>
234 ///
235 /// </summary>
236 // -----------------------------------------------------------------
224 public bool TestPath(UUID storeID, string path, bool useJson) 237 public bool TestPath(UUID storeID, string path, bool useJson)
225 { 238 {
226 if (! m_enabled) return false; 239 if (! m_enabled) return false;
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
index b9dcfea..29955af 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
@@ -167,6 +167,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
167 { 167 {
168 m_comms.RegisterScriptInvocation(this, "JsonCreateStore"); 168 m_comms.RegisterScriptInvocation(this, "JsonCreateStore");
169 m_comms.RegisterScriptInvocation(this, "JsonDestroyStore"); 169 m_comms.RegisterScriptInvocation(this, "JsonDestroyStore");
170 m_comms.RegisterScriptInvocation(this, "JsonTestStore");
170 171
171 m_comms.RegisterScriptInvocation(this, "JsonReadNotecard"); 172 m_comms.RegisterScriptInvocation(this, "JsonReadNotecard");
172 m_comms.RegisterScriptInvocation(this, "JsonWriteNotecard"); 173 m_comms.RegisterScriptInvocation(this, "JsonWriteNotecard");
@@ -248,6 +249,16 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
248 /// 249 ///
249 /// </summary> 250 /// </summary>
250 // ----------------------------------------------------------------- 251 // -----------------------------------------------------------------
252 protected int JsonTestStore(UUID hostID, UUID scriptID, UUID storeID)
253 {
254 return m_store.TestStore(storeID) ? 1 : 0;
255 }
256
257 // -----------------------------------------------------------------
258 /// <summary>
259 ///
260 /// </summary>
261 // -----------------------------------------------------------------
251 protected UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, UUID assetID) 262 protected UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, UUID assetID)
252 { 263 {
253 UUID reqID = UUID.Random(); 264 UUID reqID = UUID.Random();
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
index 397dd93..8042a93 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
@@ -48,7 +48,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
48 /// Tests for inventory functions in LSL 48 /// Tests for inventory functions in LSL
49 /// </summary> 49 /// </summary>
50 [TestFixture] 50 [TestFixture]
51 public class LSL_ApiInventoryTests : OpenSimTestCase 51 public class JsonStoreScriptModuleTests : OpenSimTestCase
52 { 52 {
53 private Scene m_scene; 53 private Scene m_scene;
54 private MockScriptEngine m_engine; 54 private MockScriptEngine m_engine;
@@ -59,8 +59,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
59 { 59 {
60 base.SetUp(); 60 base.SetUp();
61 61
62 TestHelpers.EnableLogging();
63
64 IConfigSource configSource = new IniConfigSource(); 62 IConfigSource configSource = new IniConfigSource();
65 IConfig jsonStoreConfig = configSource.AddConfig("JsonStore"); 63 IConfig jsonStoreConfig = configSource.AddConfig("JsonStore");
66 jsonStoreConfig.Set("Enabled", "true"); 64 jsonStoreConfig.Set("Enabled", "true");
@@ -72,74 +70,129 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
72 70
73 m_scene = new SceneHelpers().SetupScene(); 71 m_scene = new SceneHelpers().SetupScene();
74 SceneHelpers.SetupSceneModules(m_scene, configSource, m_engine, m_smcm, jsm, jssm); 72 SceneHelpers.SetupSceneModules(m_scene, configSource, m_engine, m_smcm, jsm, jssm);
73
74 try
75 {
76 m_smcm.RegisterScriptInvocation(this, "DummyTestMethod");
77 }
78 catch (ArgumentException)
79 {
80 Assert.Ignore("Ignoring test since running on .NET 3.5 or earlier.");
81 }
82
83 // XXX: Unfortunately, ICommsModule currently has no way of deregistering methods.
75 } 84 }
76 85
77// [Test] 86 private object InvokeOp(string name, params object[] args)
87 {
88 return m_smcm.InvokeOperation(UUID.Zero, UUID.Zero, name, args);
89 }
90
91 [Test]
78 public void TestJsonCreateStore() 92 public void TestJsonCreateStore()
79 { 93 {
80 TestHelpers.InMethod(); 94 TestHelpers.InMethod();
81// TestHelpers.EnableLogging(); 95// TestHelpers.EnableLogging();
82 96
83 UUID storeId = (UUID)m_smcm.InvokeOperation(UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{}" }); 97 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
84
85 Assert.That(storeId, Is.Not.EqualTo(UUID.Zero)); 98 Assert.That(storeId, Is.Not.EqualTo(UUID.Zero));
86 } 99 }
87 100
88// [Test] 101 [Test]
89 public void TestJsonGetValue() 102 public void TestJsonDestroyStore()
90 { 103 {
91 TestHelpers.InMethod(); 104 TestHelpers.InMethod();
92// TestHelpers.EnableLogging(); 105// TestHelpers.EnableLogging();
93 106
94 UUID storeId 107 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }");
95 = (UUID)m_smcm.InvokeOperation( 108 int dsrv = (int)InvokeOp("JsonDestroyStore", storeId);
96 UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{ 'Hello' : 'World' }" }); 109
110 Assert.That(dsrv, Is.EqualTo(1));
111
112 int tprv = (int)InvokeOp("JsonTestPath", storeId, "Hello");
113 Assert.That(tprv, Is.EqualTo(0));
114 }
115
116 [Test]
117 public void TestJsonGetValue()
118 {
119 TestHelpers.InMethod();
120// TestHelpers.EnableLogging();
97 121
98 string value 122 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }");
99 = (string)m_smcm.InvokeOperation(
100 UUID.Zero, UUID.Zero, "JsonGetValue", new object[] { storeId, "Hello" });
101 123
124 string value = (string)InvokeOp("JsonGetValue", storeId, "Hello");
102 Assert.That(value, Is.EqualTo("World")); 125 Assert.That(value, Is.EqualTo("World"));
103 } 126 }
104 127
105// [Test] 128// [Test]
106 public void TestJsonTestPath() 129// public void TestJsonTakeValue()
130// {
131// TestHelpers.InMethod();
132//// TestHelpers.EnableLogging();
133//
134// UUID storeId
135// = (UUID)m_smcm.InvokeOperation(
136// UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{ 'Hello' : 'World' }" });
137//
138// string value
139// = (string)m_smcm.InvokeOperation(
140// UUID.Zero, UUID.Zero, "JsonTakeValue", new object[] { storeId, "Hello" });
141//
142// Assert.That(value, Is.EqualTo("World"));
143//
144// string value2
145// = (string)m_smcm.InvokeOperation(
146// UUID.Zero, UUID.Zero, "JsonGetValue", new object[] { storeId, "Hello" });
147//
148// Assert.That(value, Is.Null);
149// }
150
151 [Test]
152 public void TestJsonRemoveValue()
107 { 153 {
108 TestHelpers.InMethod(); 154 TestHelpers.InMethod();
109// TestHelpers.EnableLogging(); 155// TestHelpers.EnableLogging();
110 156
111 UUID storeId 157 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }");
112 = (UUID)m_smcm.InvokeOperation( 158
113 UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{ 'Hello' : 'World' }" }); 159 int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello");
160 Assert.That(returnValue, Is.EqualTo(1));
161
162 int result = (int)InvokeOp("JsonTestPath", storeId, "Hello");
163 Assert.That(result, Is.EqualTo(0));
164
165 string returnValue2 = (string)InvokeOp("JsonGetValue", storeId, "Hello");
166 Assert.That(returnValue2, Is.EqualTo(""));
167 }
168
169 [Test]
170 public void TestJsonTestPath()
171 {
172 TestHelpers.InMethod();
173// TestHelpers.EnableLogging();
114 174
115 int result 175 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }");
116 = (int)m_smcm.InvokeOperation(
117 UUID.Zero, UUID.Zero, "JsonTestPath", new object[] { storeId, "Hello" });
118 176
177 int result = (int)InvokeOp("JsonTestPath", storeId, "Hello");
119 Assert.That(result, Is.EqualTo(1)); 178 Assert.That(result, Is.EqualTo(1));
120 } 179 }
121 180
122// [Test] 181 [Test]
123 public void TestJsonSetValue() 182 public void TestJsonSetValue()
124 { 183 {
125 TestHelpers.InMethod(); 184 TestHelpers.InMethod();
126// TestHelpers.EnableLogging(); 185// TestHelpers.EnableLogging();
127 186
128 UUID storeId 187 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
129 = (UUID)m_smcm.InvokeOperation(
130 UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{ }" });
131
132 int result
133 = (int)m_smcm.InvokeOperation(
134 UUID.Zero, UUID.Zero, "JsonSetValue", new object[] { storeId, "Hello", "World" });
135 188
189 int result = (int)InvokeOp("JsonSetValue", storeId, "Hello", "World");
136 Assert.That(result, Is.EqualTo(1)); 190 Assert.That(result, Is.EqualTo(1));
137 191
138 string value 192 string value = (string)InvokeOp("JsonGetValue", storeId, "Hello");
139 = (string)m_smcm.InvokeOperation(
140 UUID.Zero, UUID.Zero, "JsonGetValue", new object[] { storeId, "Hello" });
141
142 Assert.That(value, Is.EqualTo("World")); 193 Assert.That(value, Is.EqualTo("World"));
143 } 194 }
195
196 public object DummyTestMethod(object o1, object o2, object o3, object o4, object o5) { return null; }
144 } 197 }
145} \ No newline at end of file 198} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs
index f25b447..abbd22c 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs
@@ -87,7 +87,7 @@ public enum FixedShapeKey : ulong
87[StructLayout(LayoutKind.Sequential)] 87[StructLayout(LayoutKind.Sequential)]
88public struct ShapeData 88public struct ShapeData
89{ 89{
90 public uint ID; 90 public UInt32 ID;
91 public BSPhysicsShapeType Type; 91 public BSPhysicsShapeType Type;
92 public Vector3 Position; 92 public Vector3 Position;
93 public Quaternion Rotation; 93 public Quaternion Rotation;
@@ -111,7 +111,7 @@ public struct ShapeData
111[StructLayout(LayoutKind.Sequential)] 111[StructLayout(LayoutKind.Sequential)]
112public struct SweepHit 112public struct SweepHit
113{ 113{
114 public uint ID; 114 public UInt32 ID;
115 public float Fraction; 115 public float Fraction;
116 public Vector3 Normal; 116 public Vector3 Normal;
117 public Vector3 Point; 117 public Vector3 Point;
@@ -119,15 +119,15 @@ public struct SweepHit
119[StructLayout(LayoutKind.Sequential)] 119[StructLayout(LayoutKind.Sequential)]
120public struct RaycastHit 120public struct RaycastHit
121{ 121{
122 public uint ID; 122 public UInt32 ID;
123 public float Fraction; 123 public float Fraction;
124 public Vector3 Normal; 124 public Vector3 Normal;
125} 125}
126[StructLayout(LayoutKind.Sequential)] 126[StructLayout(LayoutKind.Sequential)]
127public struct CollisionDesc 127public struct CollisionDesc
128{ 128{
129 public uint aID; 129 public UInt32 aID;
130 public uint bID; 130 public UInt32 bID;
131 public Vector3 point; 131 public Vector3 point;
132 public Vector3 normal; 132 public Vector3 normal;
133 public float penetration; 133 public float penetration;
@@ -135,7 +135,7 @@ public struct CollisionDesc
135[StructLayout(LayoutKind.Sequential)] 135[StructLayout(LayoutKind.Sequential)]
136public struct EntityProperties 136public struct EntityProperties
137{ 137{
138 public uint ID; 138 public UInt32 ID;
139 public Vector3 Position; 139 public Vector3 Position;
140 public Quaternion Rotation; 140 public Quaternion Rotation;
141 public Vector3 Velocity; 141 public Vector3 Velocity;
@@ -325,7 +325,7 @@ public abstract BulletWorld Initialize(Vector3 maxPosition, ConfigurationParamet
325public abstract int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, 325public abstract int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep,
326 out int updatedEntityCount, out int collidersCount); 326 out int updatedEntityCount, out int collidersCount);
327 327
328public abstract bool UpdateParameter(BulletWorld world, uint localID, String parm, float value); 328public abstract bool UpdateParameter(BulletWorld world, UInt32 localID, String parm, float value);
329 329
330public abstract void Shutdown(BulletWorld sim); 330public abstract void Shutdown(BulletWorld sim);
331 331
@@ -366,24 +366,24 @@ public abstract void UpdateChildTransform(BulletShape pShape, int childIndex, Ve
366 366
367public abstract void RecalculateCompoundShapeLocalAabb(BulletShape cShape); 367public abstract void RecalculateCompoundShapeLocalAabb(BulletShape cShape);
368 368
369public abstract BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, uint id); 369public abstract BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, UInt32 id);
370 370
371public abstract bool DeleteCollisionShape(BulletWorld world, BulletShape shape); 371public abstract bool DeleteCollisionShape(BulletWorld world, BulletShape shape);
372 372
373public abstract CollisionObjectTypes GetBodyType(BulletBody obj); 373public abstract CollisionObjectTypes GetBodyType(BulletBody obj);
374 374
375public abstract BulletBody CreateBodyFromShape(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot); 375public abstract BulletBody CreateBodyFromShape(BulletWorld sim, BulletShape shape, UInt32 id, Vector3 pos, Quaternion rot);
376 376
377public abstract BulletBody CreateBodyWithDefaultMotionState(BulletShape shape, uint id, Vector3 pos, Quaternion rot); 377public abstract BulletBody CreateBodyWithDefaultMotionState(BulletShape shape, UInt32 id, Vector3 pos, Quaternion rot);
378 378
379public abstract BulletBody CreateGhostFromShape(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot); 379public abstract BulletBody CreateGhostFromShape(BulletWorld sim, BulletShape shape, UInt32 id, Vector3 pos, Quaternion rot);
380 380
381public abstract void DestroyObject(BulletWorld sim, BulletBody obj); 381public abstract void DestroyObject(BulletWorld sim, BulletBody obj);
382 382
383// ===================================================================================== 383// =====================================================================================
384public abstract BulletShape CreateGroundPlaneShape(uint id, float height, float collisionMargin); 384public abstract BulletShape CreateGroundPlaneShape(UInt32 id, float height, float collisionMargin);
385 385
386public abstract BulletShape CreateTerrainShape(uint id, Vector3 size, float minHeight, float maxHeight, float[] heightMap, 386public abstract BulletShape CreateTerrainShape(UInt32 id, Vector3 size, float minHeight, float maxHeight, float[] heightMap,
387 float scaleFactor, float collisionMargin); 387 float scaleFactor, float collisionMargin);
388 388
389// ===================================================================================== 389// =====================================================================================
@@ -629,7 +629,7 @@ public abstract BulletConstraint GetConstraintRef(BulletBody obj, int index);
629 629
630public abstract int GetNumConstraintRefs(BulletBody obj); 630public abstract int GetNumConstraintRefs(BulletBody obj);
631 631
632public abstract bool SetCollisionGroupMask(BulletBody body, uint filter, uint mask); 632public abstract bool SetCollisionGroupMask(BulletBody body, UInt32 filter, UInt32 mask);
633 633
634// ===================================================================================== 634// =====================================================================================
635// btCollisionShape entries 635// btCollisionShape entries
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index 7603254..3884a5d 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -56,7 +56,6 @@ public sealed class BSCharacter : BSPhysObject
56 private int _physicsActorType; 56 private int _physicsActorType;
57 private bool _isPhysical; 57 private bool _isPhysical;
58 private bool _flying; 58 private bool _flying;
59 private bool _wasWalking; // 'true' if the avatar was walking/moving last frame
60 private bool _setAlwaysRun; 59 private bool _setAlwaysRun;
61 private bool _throttleUpdates; 60 private bool _throttleUpdates;
62 private bool _floatOnWater; 61 private bool _floatOnWater;
@@ -84,7 +83,6 @@ public sealed class BSCharacter : BSPhysObject
84 _position = pos; 83 _position = pos;
85 84
86 _flying = isFlying; 85 _flying = isFlying;
87 _wasWalking = true; // causes first step to initialize standing
88 _orientation = OMV.Quaternion.Identity; 86 _orientation = OMV.Quaternion.Identity;
89 _velocity = OMV.Vector3.Zero; 87 _velocity = OMV.Vector3.Zero;
90 _buoyancy = ComputeBuoyancyFromFlying(isFlying); 88 _buoyancy = ComputeBuoyancyFromFlying(isFlying);
@@ -220,7 +218,13 @@ public sealed class BSCharacter : BSPhysObject
220 { 218 {
221 // The avatar shouldn't be moving 219 // The avatar shouldn't be moving
222 _velocityMotor.Zero(); 220 _velocityMotor.Zero();
223 ZeroMotion(true /* inTaintTime */); 221
222 // If we are colliding with a stationary object, presume we're standing and don't move around
223 if (!ColliderIsMoving)
224 {
225 DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", LocalID);
226 ZeroMotion(true /* inTaintTime */);
227 }
224 228
225 // Standing has more friction on the ground 229 // Standing has more friction on the ground
226 if (_currentFriction != BSParam.AvatarStandingFriction) 230 if (_currentFriction != BSParam.AvatarStandingFriction)
@@ -229,8 +233,6 @@ public sealed class BSCharacter : BSPhysObject
229 PhysicsScene.PE.SetFriction(PhysBody, _currentFriction); 233 PhysicsScene.PE.SetFriction(PhysBody, _currentFriction);
230 } 234 }
231 DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1}", LocalID, _velocityMotor.TargetValue); 235 DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1}", LocalID, _velocityMotor.TargetValue);
232
233 _wasWalking = false;
234 } 236 }
235 else 237 else
236 { 238 {
@@ -260,7 +262,6 @@ public sealed class BSCharacter : BSPhysObject
260 262
261 DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); 263 DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce);
262 PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce); 264 PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce);
263 _wasWalking = true;
264 } 265 }
265 }); 266 });
266 } 267 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 7ad7c89..05ab180 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -125,9 +125,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
125 static readonly float PIOverTwo = ((float)Math.PI) / 2f; 125 static readonly float PIOverTwo = ((float)Math.PI) / 2f;
126 126
127 // For debugging, flags to turn on and off individual corrections. 127 // For debugging, flags to turn on and off individual corrections.
128 private bool enableAngularVerticalAttraction; 128 public bool enableAngularVerticalAttraction;
129 private bool enableAngularDeflection; 129 public bool enableAngularDeflection;
130 private bool enableAngularBanking; 130 public bool enableAngularBanking;
131 131
132 public BSDynamics(BSScene myScene, BSPrim myPrim) 132 public BSDynamics(BSScene myScene, BSPrim myPrim)
133 { 133 {
@@ -146,7 +146,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
146 enableAngularBanking = false; 146 enableAngularBanking = false;
147 if (BSParam.VehicleDebuggingEnabled != ConfigurationParameters.numericFalse) 147 if (BSParam.VehicleDebuggingEnabled != ConfigurationParameters.numericFalse)
148 { 148 {
149 enableAngularVerticalAttraction = false; 149 enableAngularVerticalAttraction = true;
150 enableAngularDeflection = false; 150 enableAngularDeflection = false;
151 enableAngularBanking = false; 151 enableAngularBanking = false;
152 } 152 }
@@ -165,7 +165,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
165 } 165 }
166 166
167 #region Vehicle parameter setting 167 #region Vehicle parameter setting
168 internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) 168 public void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
169 { 169 {
170 VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue); 170 VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue);
171 switch (pParam) 171 switch (pParam)
@@ -591,14 +591,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin
591 m_vehicleMass = Prim.Linkset.LinksetMass; 591 m_vehicleMass = Prim.Linkset.LinksetMass;
592 592
593 // Friction affects are handled by this vehicle code 593 // Friction affects are handled by this vehicle code
594 float friction = 0f; 594 PhysicsScene.PE.SetFriction(Prim.PhysBody, BSParam.VehicleFriction);
595 PhysicsScene.PE.SetFriction(Prim.PhysBody, friction); 595 PhysicsScene.PE.SetRestitution(Prim.PhysBody, BSParam.VehicleRestitution);
596 596
597 // Moderate angular movement introduced by Bullet. 597 // Moderate angular movement introduced by Bullet.
598 // TODO: possibly set AngularFactor and LinearFactor for the type of vehicle. 598 // TODO: possibly set AngularFactor and LinearFactor for the type of vehicle.
599 // Maybe compute linear and angular factor and damping from params. 599 // Maybe compute linear and angular factor and damping from params.
600 float angularDamping = BSParam.VehicleAngularDamping; 600 PhysicsScene.PE.SetAngularDamping(Prim.PhysBody, BSParam.VehicleAngularDamping);
601 PhysicsScene.PE.SetAngularDamping(Prim.PhysBody, angularDamping); 601 PhysicsScene.PE.SetLinearFactor(Prim.PhysBody, BSParam.VehicleLinearFactorV);
602 PhysicsScene.PE.SetAngularFactorV(Prim.PhysBody, BSParam.VehicleAngularFactorV);
602 603
603 // Vehicles report collision events so we know when it's on the ground 604 // Vehicles report collision events so we know when it's on the ground
604 PhysicsScene.PE.AddToCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); 605 PhysicsScene.PE.AddToCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
@@ -613,8 +614,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
613 // The actual vehicle gravity is set to zero in Bullet so we can do all the application of same. 614 // The actual vehicle gravity is set to zero in Bullet so we can do all the application of same.
614 PhysicsScene.PE.SetGravity(Prim.PhysBody, Vector3.Zero); 615 PhysicsScene.PE.SetGravity(Prim.PhysBody, Vector3.Zero);
615 616
616 VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4},grav={5}", 617 VDetailLog("{0},BSDynamics.Refresh,mass={1},inert={2},grav={3},aDamp={4},frict={5},rest={6},lFact={7},aFact={8}",
617 Prim.LocalID, m_vehicleMass, friction, Prim.Inertia, angularDamping, m_VehicleGravity); 618 Prim.LocalID, m_vehicleMass, Prim.Inertia, m_VehicleGravity,
619 BSParam.VehicleAngularDamping, BSParam.VehicleFriction, BSParam.VehicleRestitution,
620 BSParam.VehicleLinearFactor, BSParam.VehicleAngularFactor
621 );
618 } 622 }
619 else 623 else
620 { 624 {
@@ -673,13 +677,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
673 private const int m_knownChangedWaterLevel = 1 << 9; 677 private const int m_knownChangedWaterLevel = 1 << 9;
674 private const int m_knownChangedForwardVelocity = 1 <<10; 678 private const int m_knownChangedForwardVelocity = 1 <<10;
675 679
676 private void ForgetKnownVehicleProperties() 680 public void ForgetKnownVehicleProperties()
677 { 681 {
678 m_knownHas = 0; 682 m_knownHas = 0;
679 m_knownChanged = 0; 683 m_knownChanged = 0;
680 } 684 }
681 // Push all the changed values back into the physics engine 685 // Push all the changed values back into the physics engine
682 private void PushKnownChanged() 686 public void PushKnownChanged()
683 { 687 {
684 if (m_knownChanged != 0) 688 if (m_knownChanged != 0)
685 { 689 {
@@ -799,7 +803,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
799 m_knownVelocity = Prim.ForceVelocity; 803 m_knownVelocity = Prim.ForceVelocity;
800 m_knownHas |= m_knownChangedVelocity; 804 m_knownHas |= m_knownChangedVelocity;
801 } 805 }
802 return (Vector3)m_knownVelocity; 806 return m_knownVelocity;
803 } 807 }
804 set 808 set
805 { 809 {
@@ -898,9 +902,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
898 { 902 {
899 if (!IsActive) return; 903 if (!IsActive) return;
900 904
901 if (PhysicsScene.VehiclePhysicalLoggingEnabled)
902 PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody);
903
904 ForgetKnownVehicleProperties(); 905 ForgetKnownVehicleProperties();
905 906
906 MoveLinear(pTimestep); 907 MoveLinear(pTimestep);
@@ -922,6 +923,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin
922 Prim.LocalID, VehiclePosition, m_knownForce, VehicleVelocity, VehicleRotationalVelocity); 923 Prim.LocalID, VehiclePosition, m_knownForce, VehicleVelocity, VehicleRotationalVelocity);
923 } 924 }
924 925
926 // Called after the simulation step
927 internal void PostStep(float pTimestep)
928 {
929 if (!IsActive) return;
930
931 if (PhysicsScene.VehiclePhysicalLoggingEnabled)
932 PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody);
933 }
934
925 // Apply the effect of the linear motor and other linear motions (like hover and float). 935 // Apply the effect of the linear motor and other linear motions (like hover and float).
926 private void MoveLinear(float pTimestep) 936 private void MoveLinear(float pTimestep)
927 { 937 {
@@ -953,10 +963,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
953 // ================================================================== 963 // ==================================================================
954 // Clamp high or low velocities 964 // Clamp high or low velocities
955 float newVelocityLengthSq = VehicleVelocity.LengthSquared(); 965 float newVelocityLengthSq = VehicleVelocity.LengthSquared();
956 if (newVelocityLengthSq > BSParam.VehicleMaxLinearVelocity) 966 if (newVelocityLengthSq > BSParam.VehicleMaxLinearVelocitySq)
957 { 967 {
968 Vector3 origVelW = VehicleVelocity; // DEBUG DEBUG
958 VehicleVelocity /= VehicleVelocity.Length(); 969 VehicleVelocity /= VehicleVelocity.Length();
959 VehicleVelocity *= BSParam.VehicleMaxLinearVelocity; 970 VehicleVelocity *= BSParam.VehicleMaxLinearVelocity;
971 VDetailLog("{0}, MoveLinear,clampMax,origVelW={1},lenSq={2},maxVelSq={3},,newVelW={4}",
972 Prim.LocalID, origVelW, newVelocityLengthSq, BSParam.VehicleMaxLinearVelocitySq, VehicleVelocity);
960 } 973 }
961 else if (newVelocityLengthSq < 0.001f) 974 else if (newVelocityLengthSq < 0.001f)
962 VehicleVelocity = Vector3.Zero; 975 VehicleVelocity = Vector3.Zero;
@@ -968,8 +981,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
968 public void ComputeLinearVelocity(float pTimestep) 981 public void ComputeLinearVelocity(float pTimestep)
969 { 982 {
970 // Step the motor from the current value. Get the correction needed this step. 983 // Step the motor from the current value. Get the correction needed this step.
971 Vector3 currentVel = VehicleVelocity * Quaternion.Inverse(VehicleOrientation); 984 Vector3 origVelW = VehicleVelocity; // DEBUG
972 Vector3 linearMotorCorrectionV = m_linearMotor.Step(pTimestep, currentVel); 985 Vector3 currentVelV = VehicleVelocity * Quaternion.Inverse(VehicleOrientation);
986 Vector3 linearMotorCorrectionV = m_linearMotor.Step(pTimestep, currentVelV);
973 987
974 // Motor is vehicle coordinates. Rotate it to world coordinates 988 // Motor is vehicle coordinates. Rotate it to world coordinates
975 Vector3 linearMotorVelocityW = linearMotorCorrectionV * VehicleOrientation; 989 Vector3 linearMotorVelocityW = linearMotorCorrectionV * VehicleOrientation;
@@ -984,8 +998,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
984 // Add this correction to the velocity to make it faster/slower. 998 // Add this correction to the velocity to make it faster/slower.
985 VehicleVelocity += linearMotorVelocityW; 999 VehicleVelocity += linearMotorVelocityW;
986 1000
987 VDetailLog("{0}, MoveLinear,velocity,vehVel={1},correction={2},force={3}", 1001 VDetailLog("{0}, MoveLinear,velocity,origVelW={1},velV={2},correctV={3},correctW={4},newVelW={5}",
988 Prim.LocalID, VehicleVelocity, linearMotorCorrectionV, linearMotorVelocityW); 1002 Prim.LocalID, origVelW, currentVelV, linearMotorCorrectionV, linearMotorVelocityW, VehicleVelocity);
989 } 1003 }
990 1004
991 public void ComputeLinearTerrainHeightCorrection(float pTimestep) 1005 public void ComputeLinearTerrainHeightCorrection(float pTimestep)
@@ -1185,12 +1199,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1185 1199
1186 // Hack to reduce downward force if the vehicle is probably sitting on the ground 1200 // Hack to reduce downward force if the vehicle is probably sitting on the ground
1187 if (Prim.IsColliding && IsGroundVehicle) 1201 if (Prim.IsColliding && IsGroundVehicle)
1188 appliedGravity *= 0.2f; 1202 appliedGravity *= BSParam.VehicleGroundGravityFudge;
1189 1203
1190 VehicleAddForce(appliedGravity); 1204 VehicleAddForce(appliedGravity);
1191 1205
1192 VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},appliedForce-{2}", 1206 VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},collid={2},appliedForce={3}",
1193 Prim.LocalID, m_VehicleGravity, appliedGravity); 1207 Prim.LocalID, m_VehicleGravity, Prim.IsColliding, appliedGravity);
1194 } 1208 }
1195 1209
1196 // ======================================================================= 1210 // =======================================================================
@@ -1292,6 +1306,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1292 if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff) 1306 if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
1293 { 1307 {
1294 Vector3 vertContributionV = Vector3.Zero; 1308 Vector3 vertContributionV = Vector3.Zero;
1309 Vector3 origRotVelW = VehicleRotationalVelocity; // DEBUG DEBUG
1295 1310
1296 // Take a vector pointing up and convert it from world to vehicle relative coords. 1311 // Take a vector pointing up and convert it from world to vehicle relative coords.
1297 Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; 1312 Vector3 verticalError = Vector3.UnitZ * VehicleOrientation;
@@ -1319,13 +1334,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1319 1334
1320 // 'vertContrbution' is now the necessary angular correction to correct tilt in one second. 1335 // 'vertContrbution' is now the necessary angular correction to correct tilt in one second.
1321 // Correction happens over a number of seconds. 1336 // Correction happens over a number of seconds.
1322 Vector3 unscaledContrib = vertContributionV; // DEBUG DEBUG 1337 Vector3 unscaledContribVerticalErrorV = vertContributionV; // DEBUG DEBUG
1323 vertContributionV /= m_verticalAttractionTimescale; 1338 vertContributionV /= m_verticalAttractionTimescale;
1324 1339
1325 VehicleRotationalVelocity += vertContributionV * VehicleOrientation; 1340 VehicleRotationalVelocity += vertContributionV * VehicleOrientation;
1326 1341
1327 VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},eff={3},ts={4},vertAttr={5}", 1342 VDetailLog("{0}, MoveAngular,verticalAttraction,,origRotVW={1},vertError={2},unscaledV={3},eff={4},ts={5},vertContribV={6}",
1328 Prim.LocalID, verticalError, unscaledContrib, m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContributionV); 1343 Prim.LocalID, origRotVelW, verticalError, unscaledContribVerticalErrorV,
1344 m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContributionV);
1329 } 1345 }
1330 } 1346 }
1331 1347
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
index 2c8dd23..54dc458 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
@@ -232,7 +232,7 @@ public sealed class BSLinksetCompound : BSLinkset
232 newLsi.OffsetFromCenterOfMass, 232 newLsi.OffsetFromCenterOfMass,
233 newLsi.OffsetRot, 233 newLsi.OffsetRot,
234 true /* shouldRecalculateLocalAabb */); 234 true /* shouldRecalculateLocalAabb */);
235 DetailLog("{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1}newLsi={2}", 235 DetailLog("{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1},newLsi={2}",
236 updated.LocalID, whichUpdated, newLsi); 236 updated.LocalID, whichUpdated, newLsi);
237 updated.LinksetInfo = newLsi; 237 updated.LinksetInfo = newLsi;
238 updatedChild = true; 238 updatedChild = true;
@@ -377,7 +377,7 @@ public sealed class BSLinksetCompound : BSLinkset
377 // Constraint linksets are rebuilt every time. 377 // Constraint linksets are rebuilt every time.
378 // Note that this works for rebuilding just the root after a linkset is taken apart. 378 // Note that this works for rebuilding just the root after a linkset is taken apart.
379 // Called at taint time!! 379 // Called at taint time!!
380 private bool disableCOM = false; // disable until we get this debugged 380 private bool disableCOM = true; // disable until we get this debugged
381 private void RecomputeLinksetCompound() 381 private void RecomputeLinksetCompound()
382 { 382 {
383 try 383 try
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
index 06186b0..8c098b2 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
@@ -82,9 +82,19 @@ public static class BSParam
82 public static float AvatarStepApproachFactor { get; private set; } 82 public static float AvatarStepApproachFactor { get; private set; }
83 public static float AvatarStepForceFactor { get; private set; } 83 public static float AvatarStepForceFactor { get; private set; }
84 84
85 // Vehicle parameters
85 public static float VehicleMaxLinearVelocity { get; private set; } 86 public static float VehicleMaxLinearVelocity { get; private set; }
87 public static float VehicleMaxLinearVelocitySq { get; private set; }
86 public static float VehicleMaxAngularVelocity { get; private set; } 88 public static float VehicleMaxAngularVelocity { get; private set; }
89 public static float VehicleMaxAngularVelocitySq { get; private set; }
87 public static float VehicleAngularDamping { get; private set; } 90 public static float VehicleAngularDamping { get; private set; }
91 public static float VehicleFriction { get; private set; }
92 public static float VehicleRestitution { get; private set; }
93 public static float VehicleLinearFactor { get; private set; }
94 public static Vector3 VehicleLinearFactorV { get; private set; }
95 public static float VehicleAngularFactor { get; private set; }
96 public static Vector3 VehicleAngularFactorV { get; private set; }
97 public static float VehicleGroundGravityFudge { get; private set; }
88 public static float VehicleDebuggingEnabled { get; private set; } 98 public static float VehicleDebuggingEnabled { get; private set; }
89 99
90 public static float LinksetImplementation { get; private set; } 100 public static float LinksetImplementation { get; private set; }
@@ -373,7 +383,7 @@ public static class BSParam
373 (s) => { return TerrainRestitution; }, 383 (s) => { return TerrainRestitution; },
374 (s,p,l,v) => { TerrainRestitution = v; /* TODO: set on real terrain */ } ), 384 (s,p,l,v) => { TerrainRestitution = v; /* TODO: set on real terrain */ } ),
375 new ParameterDefn("TerrainCollisionMargin", "Margin where collision checking starts" , 385 new ParameterDefn("TerrainCollisionMargin", "Margin where collision checking starts" ,
376 0.04f, 386 0.08f,
377 (s,cf,p,v) => { TerrainCollisionMargin = cf.GetFloat(p, v); }, 387 (s,cf,p,v) => { TerrainCollisionMargin = cf.GetFloat(p, v); },
378 (s) => { return TerrainCollisionMargin; }, 388 (s) => { return TerrainCollisionMargin; },
379 (s,p,l,v) => { TerrainCollisionMargin = v; /* TODO: set on real terrain */ } ), 389 (s,p,l,v) => { TerrainCollisionMargin = v; /* TODO: set on real terrain */ } ),
@@ -443,17 +453,42 @@ public static class BSParam
443 1000.0f, 453 1000.0f,
444 (s,cf,p,v) => { VehicleMaxLinearVelocity = cf.GetFloat(p, v); }, 454 (s,cf,p,v) => { VehicleMaxLinearVelocity = cf.GetFloat(p, v); },
445 (s) => { return (float)VehicleMaxLinearVelocity; }, 455 (s) => { return (float)VehicleMaxLinearVelocity; },
446 (s,p,l,v) => { VehicleMaxLinearVelocity = v; } ), 456 (s,p,l,v) => { VehicleMaxLinearVelocity = v; VehicleMaxLinearVelocitySq = v * v; } ),
447 new ParameterDefn("VehicleMaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to a vehicle", 457 new ParameterDefn("VehicleMaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to a vehicle",
448 12.0f, 458 12.0f,
449 (s,cf,p,v) => { VehicleMaxAngularVelocity = cf.GetFloat(p, v); }, 459 (s,cf,p,v) => { VehicleMaxAngularVelocity = cf.GetFloat(p, v); },
450 (s) => { return (float)VehicleMaxAngularVelocity; }, 460 (s) => { return (float)VehicleMaxAngularVelocity; },
451 (s,p,l,v) => { VehicleMaxAngularVelocity = v; } ), 461 (s,p,l,v) => { VehicleMaxAngularVelocity = v; VehicleMaxAngularVelocitySq = v * v; } ),
452 new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)", 462 new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)",
453 0.0f, 463 0.0f,
454 (s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); }, 464 (s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); },
455 (s) => { return VehicleAngularDamping; }, 465 (s) => { return VehicleAngularDamping; },
456 (s,p,l,v) => { VehicleAngularDamping = v; } ), 466 (s,p,l,v) => { VehicleAngularDamping = v; } ),
467 new ParameterDefn("VehicleLinearFactor", "Fraction of physical linear changes applied to vehicle (0.0 - 1.0)",
468 1.0f,
469 (s,cf,p,v) => { VehicleLinearFactor = cf.GetFloat(p, v); },
470 (s) => { return VehicleLinearFactor; },
471 (s,p,l,v) => { VehicleLinearFactor = v; VehicleLinearFactorV = new Vector3(v, v, v); } ),
472 new ParameterDefn("VehicleAngularFactor", "Fraction of physical angular changes applied to vehicle (0.0 - 1.0)",
473 1.0f,
474 (s,cf,p,v) => { VehicleAngularFactor = cf.GetFloat(p, v); },
475 (s) => { return VehicleAngularFactor; },
476 (s,p,l,v) => { VehicleAngularFactor = v; VehicleAngularFactorV = new Vector3(v, v, v); } ),
477 new ParameterDefn("VehicleFriction", "Friction of vehicle on the ground (0.0 - 1.0)",
478 0.0f,
479 (s,cf,p,v) => { VehicleFriction = cf.GetFloat(p, v); },
480 (s) => { return VehicleFriction; },
481 (s,p,l,v) => { VehicleFriction = v; } ),
482 new ParameterDefn("VehicleRestitution", "Bouncyness factor for vehicles (0.0 - 1.0)",
483 0.0f,
484 (s,cf,p,v) => { VehicleRestitution = cf.GetFloat(p, v); },
485 (s) => { return VehicleRestitution; },
486 (s,p,l,v) => { VehicleRestitution = v; } ),
487 new ParameterDefn("VehicleGroundGravityFudge", "Factor to multiple gravity if a ground vehicle is probably on the ground (0.0 - 1.0)",
488 0.2f,
489 (s,cf,p,v) => { VehicleGroundGravityFudge = cf.GetFloat(p, v); },
490 (s) => { return VehicleGroundGravityFudge; },
491 (s,p,l,v) => { VehicleGroundGravityFudge = v; } ),
457 new ParameterDefn("VehicleDebuggingEnable", "Turn on/off vehicle debugging", 492 new ParameterDefn("VehicleDebuggingEnable", "Turn on/off vehicle debugging",
458 ConfigurationParameters.numericFalse, 493 ConfigurationParameters.numericFalse,
459 (s,cf,p,v) => { VehicleDebuggingEnabled = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, 494 (s,cf,p,v) => { VehicleDebuggingEnabled = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index 027c786..a113530 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -95,12 +95,16 @@ public abstract class BSPhysObject : PhysicsActor
95 SubscribedEventsMs = 0; 95 SubscribedEventsMs = 0;
96 CollidingStep = 0; 96 CollidingStep = 0;
97 CollidingGroundStep = 0; 97 CollidingGroundStep = 0;
98 CollisionAccumulation = 0;
99 ColliderIsMoving = false;
100 CollisionScore = 0;
98 } 101 }
99 102
100 // Tell the object to clean up. 103 // Tell the object to clean up.
101 public virtual void Destroy() 104 public virtual void Destroy()
102 { 105 {
103 UnRegisterAllPreStepActions(); 106 UnRegisterAllPreStepActions();
107 UnRegisterAllPostStepActions();
104 } 108 }
105 109
106 public BSScene PhysicsScene { get; protected set; } 110 public BSScene PhysicsScene { get; protected set; }
@@ -174,13 +178,14 @@ public abstract class BSPhysObject : PhysicsActor
174 public abstract OMV.Vector3 RawPosition { get; set; } 178 public abstract OMV.Vector3 RawPosition { get; set; }
175 public abstract OMV.Vector3 ForcePosition { get; set; } 179 public abstract OMV.Vector3 ForcePosition { get; set; }
176 180
177 // Position is what the simulator thinks the positions of the prim is. 181 // 'Position' and 'Orientation' is what the simulator thinks the positions of the prim is.
178 // Because Bullet needs the zero coordinate to be the center of mass of the linkset, 182 // Because Bullet needs the zero coordinate to be the center of mass of the linkset,
179 // sometimes it is necessary to displace the position the physics engine thinks 183 // sometimes it is necessary to displace the position the physics engine thinks
180 // the position is. PositionDisplacement must be added and removed from the 184 // the position is. PositionDisplacement must be added and removed from the
181 // position as the simulator position is stored and fetched from the physics 185 // position as the simulator position is stored and fetched from the physics
182 // engine. 186 // engine. Similar to OrientationDisplacement.
183 public virtual OMV.Vector3 PositionDisplacement { get; set; } 187 public virtual OMV.Vector3 PositionDisplacement { get; set; }
188 public virtual OMV.Quaternion OrientationDisplacement { get; set; }
184 189
185 public abstract OMV.Quaternion RawOrientation { get; set; } 190 public abstract OMV.Quaternion RawOrientation { get; set; }
186 public abstract OMV.Quaternion ForceOrientation { get; set; } 191 public abstract OMV.Quaternion ForceOrientation { get; set; }
@@ -237,6 +242,12 @@ public abstract class BSPhysObject : PhysicsActor
237 protected long CollidingObjectStep { get; set; } 242 protected long CollidingObjectStep { get; set; }
238 // The collision flags we think are set in Bullet 243 // The collision flags we think are set in Bullet
239 protected CollisionFlags CurrentCollisionFlags { get; set; } 244 protected CollisionFlags CurrentCollisionFlags { get; set; }
245 // On a collision, check the collider and remember if the last collider was moving
246 // Used to modify the standing of avatars (avatars on stationary things stand still)
247 protected bool ColliderIsMoving;
248
249 // Count of collisions for this object
250 protected long CollisionAccumulation { get; set; }
240 251
241 public override bool IsColliding { 252 public override bool IsColliding {
242 get { return (CollidingStep == PhysicsScene.SimulationStep); } 253 get { return (CollidingStep == PhysicsScene.SimulationStep); }
@@ -299,7 +310,12 @@ public abstract class BSPhysObject : PhysicsActor
299 return ret; 310 return ret;
300 } 311 }
301 312
302 // if someone has subscribed for collision events.... 313 CollisionAccumulation++;
314
315 // For movement tests, remember if we are colliding with an object that is moving.
316 ColliderIsMoving = collidee != null ? collidee.RawVelocity != OMV.Vector3.Zero : false;
317
318 // If someone has subscribed for collision events log the collision so it will be reported up
303 if (SubscribedEvents()) { 319 if (SubscribedEvents()) {
304 CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); 320 CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
305 DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5}", 321 DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5}",
@@ -385,6 +401,17 @@ public abstract class BSPhysObject : PhysicsActor
385 public override bool SubscribedEvents() { 401 public override bool SubscribedEvents() {
386 return (SubscribedEventsMs > 0); 402 return (SubscribedEventsMs > 0);
387 } 403 }
404 // Because 'CollisionScore' is called many times while sorting, it should not be recomputed
405 // each time called. So this is built to be light weight for each collision and to do
406 // all the processing when the user asks for the info.
407 public void ComputeCollisionScore()
408 {
409 // Scale the collision count by the time since the last collision.
410 // The "+1" prevents dividing by zero.
411 long timeAgo = PhysicsScene.SimulationStep - CollidingStep + 1;
412 CollisionScore = CollisionAccumulation / timeAgo;
413 }
414 public override float CollisionScore { get; set; }
388 415
389 #endregion // Collisions 416 #endregion // Collisions
390 417
@@ -393,52 +420,103 @@ public abstract class BSPhysObject : PhysicsActor
393 // These actions are optional so, rather than scanning all the physical objects and asking them 420 // These actions are optional so, rather than scanning all the physical objects and asking them
394 // if they have anything to do, a physical object registers for an event call before the step is performed. 421 // if they have anything to do, a physical object registers for an event call before the step is performed.
395 // This bookkeeping makes it easy to add, remove and clean up after all these registrations. 422 // This bookkeeping makes it easy to add, remove and clean up after all these registrations.
396 private Dictionary<string, BSScene.PreStepAction> RegisteredActions = new Dictionary<string, BSScene.PreStepAction>(); 423 private Dictionary<string, BSScene.PreStepAction> RegisteredPrestepActions = new Dictionary<string, BSScene.PreStepAction>();
424 private Dictionary<string, BSScene.PostStepAction> RegisteredPoststepActions = new Dictionary<string, BSScene.PostStepAction>();
397 protected void RegisterPreStepAction(string op, uint id, BSScene.PreStepAction actn) 425 protected void RegisterPreStepAction(string op, uint id, BSScene.PreStepAction actn)
398 { 426 {
399 string identifier = op + "-" + id.ToString(); 427 string identifier = op + "-" + id.ToString();
400 428
401 lock (RegisteredActions) 429 lock (RegisteredPrestepActions)
402 { 430 {
403 // Clean out any existing action 431 // Clean out any existing action
404 UnRegisterPreStepAction(op, id); 432 UnRegisterPreStepAction(op, id);
405 433
406 RegisteredActions[identifier] = actn; 434 RegisteredPrestepActions[identifier] = actn;
435
436 PhysicsScene.BeforeStep += actn;
407 } 437 }
408 PhysicsScene.BeforeStep += actn;
409 DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier); 438 DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier);
410 } 439 }
411 440
412 // Unregister a pre step action. Safe to call if the action has not been registered. 441 // Unregister a pre step action. Safe to call if the action has not been registered.
413 protected void UnRegisterPreStepAction(string op, uint id) 442 // Returns 'true' if an action was actually removed
443 protected bool UnRegisterPreStepAction(string op, uint id)
414 { 444 {
415 string identifier = op + "-" + id.ToString(); 445 string identifier = op + "-" + id.ToString();
416 bool removed = false; 446 bool removed = false;
417 lock (RegisteredActions) 447 lock (RegisteredPrestepActions)
418 { 448 {
419 if (RegisteredActions.ContainsKey(identifier)) 449 if (RegisteredPrestepActions.ContainsKey(identifier))
420 { 450 {
421 PhysicsScene.BeforeStep -= RegisteredActions[identifier]; 451 PhysicsScene.BeforeStep -= RegisteredPrestepActions[identifier];
422 RegisteredActions.Remove(identifier); 452 RegisteredPrestepActions.Remove(identifier);
423 removed = true; 453 removed = true;
424 } 454 }
425 } 455 }
426 DetailLog("{0},BSPhysObject.UnRegisterPreStepAction,id={1},removed={2}", LocalID, identifier, removed); 456 DetailLog("{0},BSPhysObject.UnRegisterPreStepAction,id={1},removed={2}", LocalID, identifier, removed);
457 return removed;
427 } 458 }
428 459
429 protected void UnRegisterAllPreStepActions() 460 protected void UnRegisterAllPreStepActions()
430 { 461 {
431 lock (RegisteredActions) 462 lock (RegisteredPrestepActions)
432 { 463 {
433 foreach (KeyValuePair<string, BSScene.PreStepAction> kvp in RegisteredActions) 464 foreach (KeyValuePair<string, BSScene.PreStepAction> kvp in RegisteredPrestepActions)
434 { 465 {
435 PhysicsScene.BeforeStep -= kvp.Value; 466 PhysicsScene.BeforeStep -= kvp.Value;
436 } 467 }
437 RegisteredActions.Clear(); 468 RegisteredPrestepActions.Clear();
438 } 469 }
439 DetailLog("{0},BSPhysObject.UnRegisterAllPreStepActions,", LocalID); 470 DetailLog("{0},BSPhysObject.UnRegisterAllPreStepActions,", LocalID);
440 } 471 }
472
473 protected void RegisterPostStepAction(string op, uint id, BSScene.PostStepAction actn)
474 {
475 string identifier = op + "-" + id.ToString();
441 476
477 lock (RegisteredPoststepActions)
478 {
479 // Clean out any existing action
480 UnRegisterPostStepAction(op, id);
481
482 RegisteredPoststepActions[identifier] = actn;
483
484 PhysicsScene.AfterStep += actn;
485 }
486 DetailLog("{0},BSPhysObject.RegisterPostStepAction,id={1}", LocalID, identifier);
487 }
488
489 // Unregister a pre step action. Safe to call if the action has not been registered.
490 // Returns 'true' if an action was actually removed.
491 protected bool UnRegisterPostStepAction(string op, uint id)
492 {
493 string identifier = op + "-" + id.ToString();
494 bool removed = false;
495 lock (RegisteredPoststepActions)
496 {
497 if (RegisteredPoststepActions.ContainsKey(identifier))
498 {
499 PhysicsScene.AfterStep -= RegisteredPoststepActions[identifier];
500 RegisteredPoststepActions.Remove(identifier);
501 removed = true;
502 }
503 }
504 DetailLog("{0},BSPhysObject.UnRegisterPostStepAction,id={1},removed={2}", LocalID, identifier, removed);
505 return removed;
506 }
507
508 protected void UnRegisterAllPostStepActions()
509 {
510 lock (RegisteredPoststepActions)
511 {
512 foreach (KeyValuePair<string, BSScene.PostStepAction> kvp in RegisteredPoststepActions)
513 {
514 PhysicsScene.AfterStep -= kvp.Value;
515 }
516 RegisteredPoststepActions.Clear();
517 }
518 DetailLog("{0},BSPhysObject.UnRegisterAllPostStepActions,", LocalID);
519 }
442 520
443 #endregion // Per Simulation Step actions 521 #endregion // Per Simulation Step actions
444 522
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 8b00a33..b5dd131 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -59,7 +59,6 @@ public sealed class BSPrim : BSPhysObject
59 private OMV.Vector3 _force; 59 private OMV.Vector3 _force;
60 private OMV.Vector3 _velocity; 60 private OMV.Vector3 _velocity;
61 private OMV.Vector3 _torque; 61 private OMV.Vector3 _torque;
62 private float _collisionScore;
63 private OMV.Vector3 _acceleration; 62 private OMV.Vector3 _acceleration;
64 private OMV.Quaternion _orientation; 63 private OMV.Quaternion _orientation;
65 private int _physicsActorType; 64 private int _physicsActorType;
@@ -74,7 +73,7 @@ public sealed class BSPrim : BSPhysObject
74 private bool _kinematic; 73 private bool _kinematic;
75 private float _buoyancy; 74 private float _buoyancy;
76 75
77 private BSDynamics _vehicle; 76 public BSDynamics VehicleController { get; private set; }
78 77
79 private BSVMotor _targetMotor; 78 private BSVMotor _targetMotor;
80 private OMV.Vector3 _PIDTarget; 79 private OMV.Vector3 _PIDTarget;
@@ -108,7 +107,7 @@ public sealed class BSPrim : BSPhysObject
108 _friction = PhysicsScene.Params.defaultFriction; 107 _friction = PhysicsScene.Params.defaultFriction;
109 _restitution = PhysicsScene.Params.defaultRestitution; 108 _restitution = PhysicsScene.Params.defaultRestitution;
110 109
111 _vehicle = new BSDynamics(PhysicsScene, this); // add vehicleness 110 VehicleController = new BSDynamics(PhysicsScene, this); // add vehicleness
112 111
113 _mass = CalculateMass(); 112 _mass = CalculateMass();
114 113
@@ -345,6 +344,10 @@ public sealed class BSPrim : BSPhysObject
345 { 344 {
346 bool ret = false; 345 bool ret = false;
347 346
347 // We don't care where non-physical items are placed
348 if (!IsPhysicallyActive)
349 return ret;
350
348 if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition)) 351 if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition))
349 { 352 {
350 // The physical object is out of the known/simulated area. 353 // The physical object is out of the known/simulated area.
@@ -513,7 +516,7 @@ public sealed class BSPrim : BSPhysObject
513 516
514 public override int VehicleType { 517 public override int VehicleType {
515 get { 518 get {
516 return (int)_vehicle.Type; // if we are a vehicle, return that type 519 return (int)VehicleController.Type; // if we are a vehicle, return that type
517 } 520 }
518 set { 521 set {
519 Vehicle type = (Vehicle)value; 522 Vehicle type = (Vehicle)value;
@@ -522,14 +525,20 @@ public sealed class BSPrim : BSPhysObject
522 { 525 {
523 // Done at taint time so we're sure the physics engine is not using the variables 526 // Done at taint time so we're sure the physics engine is not using the variables
524 // Vehicle code changes the parameters for this vehicle type. 527 // Vehicle code changes the parameters for this vehicle type.
525 _vehicle.ProcessTypeChange(type); 528 VehicleController.ProcessTypeChange(type);
526 ActivateIfPhysical(false); 529 ActivateIfPhysical(false);
527 530
528 // If an active vehicle, register the vehicle code to be called before each step 531 // If an active vehicle, register the vehicle code to be called before each step
529 if (_vehicle.Type == Vehicle.TYPE_NONE) 532 if (VehicleController.Type == Vehicle.TYPE_NONE)
533 {
530 UnRegisterPreStepAction("BSPrim.Vehicle", LocalID); 534 UnRegisterPreStepAction("BSPrim.Vehicle", LocalID);
535 PhysicsScene.AfterStep -= VehicleController.PostStep;
536 }
531 else 537 else
532 RegisterPreStepAction("BSPrim.Vehicle", LocalID, _vehicle.Step); 538 {
539 RegisterPreStepAction("BSPrim.Vehicle", LocalID, VehicleController.Step);
540 PhysicsScene.AfterStep += VehicleController.PostStep;
541 }
533 }); 542 });
534 } 543 }
535 } 544 }
@@ -537,7 +546,7 @@ public sealed class BSPrim : BSPhysObject
537 { 546 {
538 PhysicsScene.TaintedObject("BSPrim.VehicleFloatParam", delegate() 547 PhysicsScene.TaintedObject("BSPrim.VehicleFloatParam", delegate()
539 { 548 {
540 _vehicle.ProcessFloatVehicleParam((Vehicle)param, value); 549 VehicleController.ProcessFloatVehicleParam((Vehicle)param, value);
541 ActivateIfPhysical(false); 550 ActivateIfPhysical(false);
542 }); 551 });
543 } 552 }
@@ -545,7 +554,7 @@ public sealed class BSPrim : BSPhysObject
545 { 554 {
546 PhysicsScene.TaintedObject("BSPrim.VehicleVectorParam", delegate() 555 PhysicsScene.TaintedObject("BSPrim.VehicleVectorParam", delegate()
547 { 556 {
548 _vehicle.ProcessVectorVehicleParam((Vehicle)param, value); 557 VehicleController.ProcessVectorVehicleParam((Vehicle)param, value);
549 ActivateIfPhysical(false); 558 ActivateIfPhysical(false);
550 }); 559 });
551 } 560 }
@@ -553,7 +562,7 @@ public sealed class BSPrim : BSPhysObject
553 { 562 {
554 PhysicsScene.TaintedObject("BSPrim.VehicleRotationParam", delegate() 563 PhysicsScene.TaintedObject("BSPrim.VehicleRotationParam", delegate()
555 { 564 {
556 _vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation); 565 VehicleController.ProcessRotationVehicleParam((Vehicle)param, rotation);
557 ActivateIfPhysical(false); 566 ActivateIfPhysical(false);
558 }); 567 });
559 } 568 }
@@ -561,7 +570,7 @@ public sealed class BSPrim : BSPhysObject
561 { 570 {
562 PhysicsScene.TaintedObject("BSPrim.VehicleFlags", delegate() 571 PhysicsScene.TaintedObject("BSPrim.VehicleFlags", delegate()
563 { 572 {
564 _vehicle.ProcessVehicleFlags(param, remove); 573 VehicleController.ProcessVehicleFlags(param, remove);
565 }); 574 });
566 } 575 }
567 576
@@ -638,11 +647,6 @@ public sealed class BSPrim : BSPhysObject
638 // DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque); 647 // DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque);
639 } 648 }
640 } 649 }
641 public override float CollisionScore {
642 get { return _collisionScore; }
643 set { _collisionScore = value;
644 }
645 }
646 public override OMV.Vector3 Acceleration { 650 public override OMV.Vector3 Acceleration {
647 get { return _acceleration; } 651 get { return _acceleration; }
648 set { _acceleration = value; } 652 set { _acceleration = value; }
@@ -747,7 +751,7 @@ public sealed class BSPrim : BSPhysObject
747 // isSolid: other objects bounce off of this object 751 // isSolid: other objects bounce off of this object
748 // isVolumeDetect: other objects pass through but can generate collisions 752 // isVolumeDetect: other objects pass through but can generate collisions
749 // collisionEvents: whether this object returns collision events 753 // collisionEvents: whether this object returns collision events
750 private void UpdatePhysicalParameters() 754 public void UpdatePhysicalParameters()
751 { 755 {
752 // DetailLog("{0},BSPrim.UpdatePhysicalParameters,entry,body={1},shape={2}", LocalID, BSBody, BSShape); 756 // DetailLog("{0},BSPrim.UpdatePhysicalParameters,entry,body={1},shape={2}", LocalID, BSBody, BSShape);
753 757
@@ -759,7 +763,7 @@ public sealed class BSPrim : BSPhysObject
759 MakeDynamic(IsStatic); 763 MakeDynamic(IsStatic);
760 764
761 // Update vehicle specific parameters (after MakeDynamic() so can change physical parameters) 765 // Update vehicle specific parameters (after MakeDynamic() so can change physical parameters)
762 _vehicle.Refresh(); 766 VehicleController.Refresh();
763 767
764 // Arrange for collision events if the simulator wants them 768 // Arrange for collision events if the simulator wants them
765 EnableCollisions(SubscribedEvents()); 769 EnableCollisions(SubscribedEvents());
@@ -1601,7 +1605,7 @@ public sealed class BSPrim : BSPhysObject
1601 // Remove all the physical dependencies on the old body. 1605 // Remove all the physical dependencies on the old body.
1602 // (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...) 1606 // (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...)
1603 Linkset.RemoveBodyDependencies(this); 1607 Linkset.RemoveBodyDependencies(this);
1604 _vehicle.RemoveBodyDependencies(this); 1608 VehicleController.RemoveBodyDependencies(this);
1605 }); 1609 });
1606 1610
1607 // Make sure the properties are set on the new object 1611 // Make sure the properties are set on the new object
@@ -1618,9 +1622,9 @@ public sealed class BSPrim : BSPhysObject
1618 { 1622 {
1619 // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet 1623 // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet
1620 // TODO: handle physics introduced by Bullet with computed vehicle physics. 1624 // TODO: handle physics introduced by Bullet with computed vehicle physics.
1621 if (_vehicle.IsActive) 1625 if (VehicleController.IsActive)
1622 { 1626 {
1623 // entprop.RotationalVelocity = OMV.Vector3.Zero; 1627 entprop.RotationalVelocity = OMV.Vector3.Zero;
1624 } 1628 }
1625 1629
1626 // DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG 1630 // DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG
@@ -1643,7 +1647,7 @@ public sealed class BSPrim : BSPhysObject
1643 // DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG 1647 // DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG
1644 1648
1645 // The sanity check can change the velocity and/or position. 1649 // The sanity check can change the velocity and/or position.
1646 if (IsPhysical && PositionSanityCheck(true /* inTaintTime */ )) 1650 if (PositionSanityCheck(true /* inTaintTime */ ))
1647 { 1651 {
1648 entprop.Position = _position; 1652 entprop.Position = _position;
1649 entprop.Velocity = _velocity; 1653 entprop.Velocity = _velocity;
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index cb304b6..a4690ba 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27using System; 27using System;
28using System.Collections.Generic; 28using System.Collections.Generic;
29using System.Linq;
29using System.Reflection; 30using System.Reflection;
30using System.Runtime.InteropServices; 31using System.Runtime.InteropServices;
31using System.Text; 32using System.Text;
@@ -87,7 +88,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
87 public delegate void PreStepAction(float timeStep); 88 public delegate void PreStepAction(float timeStep);
88 public delegate void PostStepAction(float timeStep); 89 public delegate void PostStepAction(float timeStep);
89 public event PreStepAction BeforeStep; 90 public event PreStepAction BeforeStep;
90 public event PreStepAction AfterStep; 91 public event PostStepAction AfterStep;
91 92
92 // A value of the time now so all the collision and update routines do not have to get their own 93 // A value of the time now so all the collision and update routines do not have to get their own
93 // Set to 'now' just before all the prims and actors are called for collisions and updates 94 // Set to 'now' just before all the prims and actors are called for collisions and updates
@@ -697,7 +698,21 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
697 698
698 public override Dictionary<uint, float> GetTopColliders() 699 public override Dictionary<uint, float> GetTopColliders()
699 { 700 {
700 return new Dictionary<uint, float>(); 701 Dictionary<uint, float> topColliders;
702
703 lock (PhysObjects)
704 {
705 foreach (KeyValuePair<uint, BSPhysObject> kvp in PhysObjects)
706 {
707 kvp.Value.ComputeCollisionScore();
708 }
709
710 List<BSPhysObject> orderedPrims = new List<BSPhysObject>(PhysObjects.Values);
711 orderedPrims.OrderByDescending(p => p.CollisionScore);
712 topColliders = orderedPrims.Take(25).ToDictionary(p => p.LocalID, p => p.CollisionScore);
713 }
714
715 return topColliders;
701 } 716 }
702 717
703 public override bool IsThreaded { get { return false; } } 718 public override bool IsThreaded { get { return false; } }
@@ -748,7 +763,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
748 763
749 private void TriggerPostStepEvent(float timeStep) 764 private void TriggerPostStepEvent(float timeStep)
750 { 765 {
751 PreStepAction actions = AfterStep; 766 PostStepAction actions = AfterStep;
752 if (actions != null) 767 if (actions != null)
753 actions(timeStep); 768 actions(timeStep);
754 769
@@ -840,7 +855,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
840 { 855 {
841 DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom); 856 DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom);
842 m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom); 857 m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom);
843 Util.PrintCallStack(DetailLog); 858 // Util.PrintCallStack(DetailLog);
844 } 859 }
845 return InTaintTime; 860 return InTaintTime;
846 } 861 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
index 801f690..a95e169 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
@@ -1,8 +1,11 @@
1CURRENT PRIORITIES 1CURRENT PRIORITIES
2================================================= 2=================================================
3One sided meshes? Should terrain be built into a closed shape?
4 When meshes get partially wedged into the terrain, they cannot push themselves out.
5 It is possible that Bullet processes collisions whether entering or leaving a mesh.
6 Ref: http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4869
3Deleting a linkset while standing on the root will leave the physical shape of the root behind. 7Deleting a linkset while standing on the root will leave the physical shape of the root behind.
4 Not sure if it is because standing on it. Done with large prim linksets. 8 Not sure if it is because standing on it. Done with large prim linksets.
5Child movement in linkset (don't rebuild linkset)
6Vehicle angular vertical attraction 9Vehicle angular vertical attraction
7vehicle angular banking 10vehicle angular banking
8Center-of-gravity 11Center-of-gravity
@@ -12,6 +15,7 @@ when should angular and linear motor targets be zeroed? when selected?
12 Need a vehicle.clear()? Or an 'else' in prestep if not physical. 15 Need a vehicle.clear()? Or an 'else' in prestep if not physical.
13Teravus llMoveToTarget script debug 16Teravus llMoveToTarget script debug
14 Mixing of hover, buoyancy/gravity, moveToTarget, into one force 17 Mixing of hover, buoyancy/gravity, moveToTarget, into one force
18 Setting hover height to zero disables hover even if hover flags are on (from SL wiki)
15Nebadon vehicles turning funny in arena 19Nebadon vehicles turning funny in arena
16limitMotorUp calibration (more down?) 20limitMotorUp calibration (more down?)
17llRotLookAt 21llRotLookAt
@@ -72,7 +76,11 @@ Incorporate inter-relationship of angular corrections. For instance, angularDefl
72 76
73GENERAL TODO LIST: 77GENERAL TODO LIST:
74================================================= 78=================================================
79Avatar standing on a moving object should start to move with the object.
75llMoveToTarget objects are not effected by gravity until target is removed. 80llMoveToTarget objects are not effected by gravity until target is removed.
81Compute CCD parameters based on body size
82Can solver iterations be changed per body/shape? Can be for constraints but what
83 about regular vehicles?
76Implement llSetPhysicalMaterial. 84Implement llSetPhysicalMaterial.
77 extend it with Center-of-mass, rolling friction, density 85 extend it with Center-of-mass, rolling friction, density
78Implement llSetForceAndTorque. 86Implement llSetForceAndTorque.
@@ -321,4 +329,5 @@ Mantis 6040 script http://opensimulator.org/mantis/view.php?id=6040 (DONE)
321Boats float low in the water (DONE) 329Boats float low in the water (DONE)
322Boats floating at proper level (DONE) 330Boats floating at proper level (DONE)
323When is force introduced by SetForce removed? The prestep action could go forever. (DONE) 331When is force introduced by SetForce removed? The prestep action could go forever. (DONE)
324 (Resolution: setForce registers a prestep action which keeps applying the force) \ No newline at end of file 332 (Resolution: setForce registers a prestep action which keeps applying the force)
333Child movement in linkset (don't rebuild linkset) (DONE 20130122)) \ No newline at end of file
diff --git a/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs b/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs
new file mode 100755
index 0000000..33232bd
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs
@@ -0,0 +1,150 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Linq;
31using System.Text;
32
33using NUnit.Framework;
34using log4net;
35
36using OpenSim.Framework;
37using OpenSim.Region.Physics.BulletSPlugin;
38using OpenSim.Region.Physics.Manager;
39using OpenSim.Tests.Common;
40
41using OpenMetaverse;
42
43namespace OpenSim.Region.Physics.BulletSPlugin.Tests
44{
45[TestFixture]
46public class BasicVehicles : OpenSimTestCase
47{
48 // Documentation on attributes: http://www.nunit.org/index.php?p=attributes&r=2.6.1
49 // Documentation on assertions: http://www.nunit.org/index.php?p=assertions&r=2.6.1
50
51 BSScene PhysicsScene { get; set; }
52 BSPrim TestVehicle { get; set; }
53 Vector3 TestVehicleInitPosition { get; set; }
54 float simulationTimeStep = 0.089f;
55
56 [TestFixtureSetUp]
57 public void Init()
58 {
59 Dictionary<string, string> engineParams = new Dictionary<string, string>();
60 PhysicsScene = BulletSimTestsUtil.CreateBasicPhysicsEngine(engineParams);
61
62 PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateSphere();
63 Vector3 pos = new Vector3(100.0f, 100.0f, 0f);
64 pos.Z = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos) + 2f;
65 TestVehicleInitPosition = pos;
66 Vector3 size = new Vector3(1f, 1f, 1f);
67 pbs.Scale = size;
68 Quaternion rot = Quaternion.Identity;
69 bool isPhys = false;
70 uint localID = 123;
71
72 PhysicsScene.AddPrimShape("testPrim", pbs, pos, size, rot, isPhys, localID);
73 TestVehicle = (BSPrim)PhysicsScene.PhysObjects[localID];
74 // The actual prim shape creation happens at taint time
75 PhysicsScene.ProcessTaints();
76
77 }
78
79 [TestFixtureTearDown]
80 public void TearDown()
81 {
82 if (PhysicsScene != null)
83 {
84 // The Dispose() will also free any physical objects in the scene
85 PhysicsScene.Dispose();
86 PhysicsScene = null;
87 }
88 }
89
90 [TestCase(2f, 0.2f, 0.25f, 0.25f, 0.25f)]
91 [TestCase(2f, 0.2f, -0.25f, 0.25f, 0.25f)]
92 [TestCase(2f, 0.2f, 0.25f, -0.25f, 0.25f)]
93 [TestCase(2f, 0.2f, -0.25f, -0.25f, 0.25f)]
94 // [TestCase(2f, 0.2f, 0.785f, 0.0f, 0.25f) /*, "Leaning 45 degrees to the side" */]
95 // [TestCase(2f, 0.2f, 1.650f, 0.0f, 0.25f) /*, "Leaning more than 90 degrees to the side" */]
96 // [TestCase(2f, 0.2f, 2.750f, 0.0f, 0.25f) /*, "Almost upside down, tipped right" */]
97 // [TestCase(2f, 0.2f,-2.750f, 0.0f, 0.25f) /*, "Almost upside down, tipped left" */]
98 // [TestCase(2f, 0.2f, 0.0f, 0.785f, 0.25f) /*, "Tipped back 45 degrees" */]
99 // [TestCase(2f, 0.2f, 0.0f, 1.650f, 0.25f) /*, "Tipped back more than 90 degrees" */]
100 // [TestCase(2f, 0.2f, 0.0f, 2.750f, 0.25f) /*, "Almost upside down, tipped back" */]
101 // [TestCase(2f, 0.2f, 0.0f,-2.750f, 0.25f) /*, "Almost upside down, tipped forward" */]
102 public void AngularVerticalAttraction(float timeScale, float efficiency, float initRoll, float initPitch, float initYaw)
103 {
104 // Enough simulation steps to cover the timescale the operation should take
105 int simSteps = (int)(timeScale / simulationTimeStep) + 1;
106
107 // Tip the vehicle
108 Quaternion initOrientation = Quaternion.CreateFromEulers(initRoll, initPitch, initYaw);
109 TestVehicle.Orientation = initOrientation;
110
111 TestVehicle.Position = TestVehicleInitPosition;
112
113 // The vehicle controller is not enabled directly (by setting a vehicle type).
114 // Instead the appropriate values are set and calls are made just the parts of the
115 // controller we want to exercise. Stepping the physics engine then applies
116 // the actions of that one feature.
117 TestVehicle.VehicleController.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_EFFICIENCY, efficiency);
118 TestVehicle.VehicleController.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_TIMESCALE, timeScale);
119 TestVehicle.VehicleController.enableAngularVerticalAttraction = true;
120
121 TestVehicle.IsPhysical = true;
122 PhysicsScene.ProcessTaints();
123
124 // Step the simulator a bunch of times and vertical attraction should orient the vehicle up
125 for (int ii = 0; ii < simSteps; ii++)
126 {
127 TestVehicle.VehicleController.ForgetKnownVehicleProperties();
128 TestVehicle.VehicleController.ComputeAngularVerticalAttraction();
129 TestVehicle.VehicleController.PushKnownChanged();
130
131 PhysicsScene.Simulate(simulationTimeStep);
132 }
133
134 TestVehicle.IsPhysical = false;
135 PhysicsScene.ProcessTaints();
136
137 // After these steps, the vehicle should be upright
138 /*
139 float finalRoll, finalPitch, finalYaw;
140 TestVehicle.Orientation.GetEulerAngles(out finalRoll, out finalPitch, out finalYaw);
141 Assert.That(finalRoll, Is.InRange(-0.01f, 0.01f));
142 Assert.That(finalPitch, Is.InRange(-0.01f, 0.01f));
143 Assert.That(finalYaw, Is.InRange(initYaw - 0.1f, initYaw + 0.1f));
144 */
145
146 Vector3 upPointer = Vector3.UnitZ * TestVehicle.Orientation;
147 Assert.That(upPointer.Z, Is.GreaterThan(0.99f));
148 }
149}
150} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTests.cs b/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTests.cs
new file mode 100755
index 0000000..35cbc1d
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTests.cs
@@ -0,0 +1,56 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Linq;
31using System.Text;
32
33using NUnit.Framework;
34using log4net;
35
36using OpenSim.Tests.Common;
37
38namespace OpenSim.Region.Physics.BulletSPlugin.Tests
39{
40[TestFixture]
41public class BulletSimTests : OpenSimTestCase
42{
43 // Documentation on attributes: http://www.nunit.org/index.php?p=attributes&r=2.6.1
44 // Documentation on assertions: http://www.nunit.org/index.php?p=assertions&r=2.6.1
45
46 [TestFixtureSetUp]
47 public void Init()
48 {
49 }
50
51 [TestFixtureTearDown]
52 public void TearDown()
53 {
54 }
55}
56}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs b/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs
new file mode 100755
index 0000000..28207a4
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs
@@ -0,0 +1,95 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.IO;
30using System.Collections.Generic;
31using System.Linq;
32using System.Text;
33
34using Nini.Config;
35
36using OpenSim.Framework;
37using OpenSim.Region.Physics.BulletSPlugin;
38using OpenSim.Region.Physics.Meshing;
39
40namespace OpenSim.Region.Physics.BulletSPlugin.Tests
41{
42// Utility functions for building up and tearing down the sample physics environments
43public static class BulletSimTestsUtil
44{
45 // 'engineName' is the Bullet engine to use. Either null (for unmanaged), "BulletUnmanaged" or "BulletXNA"
46 // 'params' is a set of keyValue pairs to set in the engine's configuration file (override defaults)
47 // May be 'null' if there are no overrides.
48 public static BSScene CreateBasicPhysicsEngine(Dictionary<string,string> paramOverrides)
49 {
50 IConfigSource openSimINI = new IniConfigSource();
51 IConfig startupConfig = openSimINI.AddConfig("Startup");
52 startupConfig.Set("physics", "BulletSim");
53 startupConfig.Set("meshing", "Meshmerizer");
54 startupConfig.Set("cacheSculptMaps", "false"); // meshmerizer shouldn't save maps
55
56 IConfig bulletSimConfig = openSimINI.AddConfig("BulletSim");
57 // If the caller cares, specify the bullet engine otherwise it will default to "BulletUnmanaged".
58 // bulletSimConfig.Set("BulletEngine", "BulletUnmanaged");
59 // bulletSimConfig.Set("BulletEngine", "BulletXNA");
60 bulletSimConfig.Set("MeshSculptedPrim", "false");
61 bulletSimConfig.Set("ForceSimplePrimMeshing", "true");
62 if (paramOverrides != null)
63 {
64 foreach (KeyValuePair<string, string> kvp in paramOverrides)
65 {
66 bulletSimConfig.Set(kvp.Key, kvp.Value);
67 }
68 }
69
70 // If a special directory exists, put detailed logging therein.
71 // This allows local testing/debugging without having to worry that the build engine will output logs.
72 if (Directory.Exists("physlogs"))
73 {
74 bulletSimConfig.Set("PhysicsLoggingDir","./physlogs");
75 bulletSimConfig.Set("PhysicsLoggingEnabled","True");
76 bulletSimConfig.Set("PhysicsLoggingDoFlush","True");
77 bulletSimConfig.Set("VehicleLoggingEnabled","True");
78 }
79
80 BSPlugin bsPlugin = new BSPlugin();
81
82 BSScene bsScene = (BSScene)bsPlugin.GetScene("BSTestRegion");
83
84 // Since the asset requestor is not initialized, any mesh or sculptie will be a cube.
85 // In the future, add a fake asset fetcher to get meshes and sculpts.
86 // bsScene.RequestAssetMethod = ???;
87
88 Meshing.Meshmerizer mesher = new Meshmerizer(openSimINI);
89 bsScene.Initialise(mesher, openSimINI);
90
91 return bsScene;
92 }
93
94}
95}
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
index 02a0b15..6d7f079 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
@@ -4096,8 +4096,8 @@ namespace OpenSim.Region.Physics.OdePlugin
4096 lock (_prims) 4096 lock (_prims)
4097 { 4097 {
4098 List<OdePrim> orderedPrims = new List<OdePrim>(_prims); 4098 List<OdePrim> orderedPrims = new List<OdePrim>(_prims);
4099 orderedPrims.OrderByDescending(p => p.CollisionScore).Take(25); 4099 orderedPrims.OrderByDescending(p => p.CollisionScore);
4100 topColliders = orderedPrims.ToDictionary(p => p.LocalID, p => p.CollisionScore); 4100 topColliders = orderedPrims.Take(25).ToDictionary(p => p.LocalID, p => p.CollisionScore);
4101 4101
4102 foreach (OdePrim p in _prims) 4102 foreach (OdePrim p in _prims)
4103 p.CollisionScore = 0; 4103 p.CollisionScore = 0;
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
index 985e598..9e32f40 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
@@ -31,7 +31,6 @@ using System.Collections.Generic;
31using System.Reflection; 31using System.Reflection;
32using log4net; 32using log4net;
33using Tools; 33using Tools;
34
35using OpenSim.Region.Framework.Interfaces; 34using OpenSim.Region.Framework.Interfaces;
36 35
37namespace OpenSim.Region.ScriptEngine.Shared.CodeTools 36namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
@@ -479,20 +478,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
479 { 478 {
480 string retstr = String.Empty; 479 string retstr = String.Empty;
481 bool printSemicolon = true; 480 bool printSemicolon = true;
482 481 bool transformToBlock = false;
483 retstr += Indent();
484 482
485 if (m_insertCoopTerminationChecks) 483 if (m_insertCoopTerminationChecks)
486 { 484 {
487 // We have to check in event functions as well because the user can manually call these. 485 // A non-braced single line do while structure cannot contain multiple statements.
488 if (previousSymbol is GlobalFunctionDefinition 486 // So to insert the termination check we change this to a braced control structure instead.
489 || previousSymbol is WhileStatement 487 if (previousSymbol is WhileStatement
490 || previousSymbol is DoWhileStatement 488 || previousSymbol is DoWhileStatement
491 || previousSymbol is ForLoop 489 || previousSymbol is ForLoop)
492 || previousSymbol is StateEvent) 490 {
493 retstr += Generate(m_coopTerminationCheck); 491 transformToBlock = true;
492
493 // FIXME: This will be wrongly indented because the previous for/while/dowhile will have already indented.
494 retstr += GenerateIndentedLine("{");
495
496 retstr += GenerateIndentedLine(m_coopTerminationCheck);
497 }
494 } 498 }
495 499
500 retstr += Indent();
501
496 if (0 < s.kids.Count) 502 if (0 < s.kids.Count)
497 { 503 {
498 // Jump label prints its own colon, we don't need a semicolon. 504 // Jump label prints its own colon, we don't need a semicolon.
@@ -508,6 +514,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
508 if (printSemicolon) 514 if (printSemicolon)
509 retstr += GenerateLine(";"); 515 retstr += GenerateLine(";");
510 516
517 if (transformToBlock)
518 {
519 // FIXME: This will be wrongly indented because the for/while/dowhile is currently handling the unindent
520 retstr += GenerateIndentedLine("}");
521 }
522
511 return retstr; 523 return retstr;
512 } 524 }
513 525
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs
index 3b13386..7ea30bf1 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs
@@ -55,10 +55,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
55 55
56 private OSChatMessage m_osChatMessageReceived; 56 private OSChatMessage m_osChatMessageReceived;
57 57
58 /// <summary>
59 /// Number of chat messages received so far. Reset before each test.
60 /// </summary>
61 private int m_chatMessagesReceived;
62
63 /// <summary>
64 /// Number of chat messages expected. m_chatEvent is not fired until this number is reached or exceeded.
65 /// </summary>
66 private int m_chatMessagesThreshold;
67
58 [SetUp] 68 [SetUp]
59 public void Init() 69 public void Init()
60 { 70 {
61 m_osChatMessageReceived = null; 71 m_osChatMessageReceived = null;
72 m_chatMessagesReceived = 0;
73 m_chatMessagesThreshold = 0;
62 m_chatEvent = new AutoResetEvent(false); 74 m_chatEvent = new AutoResetEvent(false);
63 m_stoppedEvent = new AutoResetEvent(false); 75 m_stoppedEvent = new AutoResetEvent(false);
64 76
@@ -126,6 +138,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
126 } 138 }
127 139
128 [Test] 140 [Test]
141 public void TestNoStopOnSingleStatementForLoop()
142 {
143 TestHelpers.InMethod();
144// TestHelpers.EnableLogging();
145
146 string script =
147@"default
148{
149 state_entry()
150 {
151 integer i = 0;
152 for (i = 0; i <= 1; i++) llSay(0, ""Iter "" + (string)i);
153 }
154}";
155
156 TestSingleStatementNoStop(script);
157 }
158
159 [Test]
129 public void TestStopOnLongSingleStatementForLoop() 160 public void TestStopOnLongSingleStatementForLoop()
130 { 161 {
131 TestHelpers.InMethod(); 162 TestHelpers.InMethod();
@@ -139,8 +170,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
139 integer i = 0; 170 integer i = 0;
140 llSay(0, ""Thin Lizzy""); 171 llSay(0, ""Thin Lizzy"");
141 172
142 for (i = 0; i < 2147483647; i++) 173 for (i = 0; i < 2147483647; i++) llSay(0, ""Iter "" + (string)i);
143 llSay(0, ""Iter "" + (string)i);
144 } 174 }
145}"; 175}";
146 176
@@ -172,6 +202,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
172 } 202 }
173 203
174 [Test] 204 [Test]
205 public void TestNoStopOnSingleStatementWhileLoop()
206 {
207 TestHelpers.InMethod();
208// TestHelpers.EnableLogging();
209
210 string script =
211@"default
212{
213 state_entry()
214 {
215 integer i = 0;
216 while (i < 2) llSay(0, ""Iter "" + (string)i++);
217 }
218}";
219
220 TestSingleStatementNoStop(script);
221 }
222
223 [Test]
175 public void TestStopOnLongSingleStatementWhileLoop() 224 public void TestStopOnLongSingleStatementWhileLoop()
176 { 225 {
177 TestHelpers.InMethod(); 226 TestHelpers.InMethod();
@@ -218,7 +267,50 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
218 } 267 }
219 268
220 [Test] 269 [Test]
221 public void TestStopOnLongDoWhileLoop() 270 public void TestNoStopOnSingleStatementDoWhileLoop()
271 {
272 TestHelpers.InMethod();
273// TestHelpers.EnableLogging();
274
275 string script =
276@"default
277{
278 state_entry()
279 {
280 integer i = 0;
281
282 do llSay(0, ""Iter "" + (string)i++);
283 while (i < 2);
284 }
285}";
286
287 TestSingleStatementNoStop(script);
288 }
289
290 [Test]
291 public void TestStopOnLongSingleStatementDoWhileLoop()
292 {
293 TestHelpers.InMethod();
294// TestHelpers.EnableLogging();
295
296 string script =
297@"default
298{
299 state_entry()
300 {
301 integer i = 0;
302 llSay(0, ""Thin Lizzy"");
303
304 do llSay(0, ""Iter "" + (string)i++);
305 while (1 == 1);
306 }
307}";
308
309 TestStop(script);
310 }
311
312 [Test]
313 public void TestStopOnLongCompoundStatementDoWhileLoop()
222 { 314 {
223 TestHelpers.InMethod(); 315 TestHelpers.InMethod();
224// TestHelpers.EnableLogging(); 316// TestHelpers.EnableLogging();
@@ -234,7 +326,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
234 do 326 do
235 { 327 {
236 llSay(0, ""Iter "" + (string)i++); 328 llSay(0, ""Iter "" + (string)i++);
237} while (1 == 1); 329 } while (1 == 1);
238 } 330 }
239}"; 331}";
240 332
@@ -245,7 +337,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
245 public void TestStopOnInfiniteJumpLoop() 337 public void TestStopOnInfiniteJumpLoop()
246 { 338 {
247 TestHelpers.InMethod(); 339 TestHelpers.InMethod();
248 TestHelpers.EnableLogging(); 340// TestHelpers.EnableLogging();
249 341
250 string script = 342 string script =
251@"default 343@"default
@@ -320,14 +412,13 @@ default
320 TestStop(script); 412 TestStop(script);
321 } 413 }
322 414
323 private void TestStop(string script) 415 private SceneObjectPart CreateScript(string script, string itemName, UUID userId)
324 { 416 {
325 UUID userId = TestHelpers.ParseTail(0x1);
326// UUID objectId = TestHelpers.ParseTail(0x100); 417// UUID objectId = TestHelpers.ParseTail(0x100);
327// UUID itemId = TestHelpers.ParseTail(0x3); 418// UUID itemId = TestHelpers.ParseTail(0x3);
328 string itemName = "TestStop() Item";
329 419
330 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, "TestStop", 0x100); 420 SceneObjectGroup so
421 = SceneHelpers.CreateSceneObject(1, userId, string.Format("Object for {0}", itemName), 0x100);
331 m_scene.AddNewSceneObject(so, true); 422 m_scene.AddNewSceneObject(so, true);
332 423
333 InventoryItemBase itemTemplate = new InventoryItemBase(); 424 InventoryItemBase itemTemplate = new InventoryItemBase();
@@ -338,14 +429,57 @@ default
338 429
339 m_scene.EventManager.OnChatFromWorld += OnChatFromWorld; 430 m_scene.EventManager.OnChatFromWorld += OnChatFromWorld;
340 431
341 SceneObjectPart partWhereRezzed = m_scene.RezNewScript(userId, itemTemplate, script); 432 return m_scene.RezNewScript(userId, itemTemplate, script);
433 }
434
435 private void TestSingleStatementNoStop(string script)
436 {
437 // In these tests we expect to see at least 2 chat messages to confirm that the loop is working properly.
438 m_chatMessagesThreshold = 2;
439
440 UUID userId = TestHelpers.ParseTail(0x1);
441// UUID objectId = TestHelpers.ParseTail(0x100);
442// UUID itemId = TestHelpers.ParseTail(0x3);
443 string itemName = "TestNoStop";
444
445 SceneObjectPart partWhereRezzed = CreateScript(script, itemName, userId);
446 TaskInventoryItem rezzedItem = partWhereRezzed.Inventory.GetInventoryItem(itemName);
447
448 // Wait for the script to start the event before we try stopping it.
449 m_chatEvent.WaitOne(60000);
450
451 if (m_osChatMessageReceived == null)
452 Assert.Fail("Script did not start");
453 else
454 Assert.That(m_chatMessagesReceived, Is.EqualTo(2));
455
456 bool running;
457 TaskInventoryItem scriptItem = partWhereRezzed.Inventory.GetInventoryItem(itemName);
458 Assert.That(
459 SceneObjectPartInventory.TryGetScriptInstanceRunning(m_scene, scriptItem, out running), Is.True);
460 Assert.That(running, Is.True);
461 }
462
463 private void TestStop(string script)
464 {
465 // In these tests we're only interested in the first message to confirm that the script has started.
466 m_chatMessagesThreshold = 1;
342 467
468 UUID userId = TestHelpers.ParseTail(0x1);
469// UUID objectId = TestHelpers.ParseTail(0x100);
470// UUID itemId = TestHelpers.ParseTail(0x3);
471 string itemName = "TestStop";
472
473 SceneObjectPart partWhereRezzed = CreateScript(script, itemName, userId);
343 TaskInventoryItem rezzedItem = partWhereRezzed.Inventory.GetInventoryItem(itemName); 474 TaskInventoryItem rezzedItem = partWhereRezzed.Inventory.GetInventoryItem(itemName);
344 475
345 // Wait for the script to start the event before we try stopping it. 476 // Wait for the script to start the event before we try stopping it.
346 m_chatEvent.WaitOne(60000); 477 m_chatEvent.WaitOne(60000);
347 478
348 Console.WriteLine("Script started with message [{0}]", m_osChatMessageReceived.Message); 479 if (m_osChatMessageReceived != null)
480 Console.WriteLine("Script started with message [{0}]", m_osChatMessageReceived.Message);
481 else
482 Assert.Fail("Script did not start");
349 483
350 // FIXME: This is a very poor way of trying to avoid a low-probability race condition where the script 484 // FIXME: This is a very poor way of trying to avoid a low-probability race condition where the script
351 // executes llSay() but has not started the next statement before we try to stop it. 485 // executes llSay() but has not started the next statement before we try to stop it.
@@ -367,11 +501,14 @@ default
367 501
368 private void OnChatFromWorld(object sender, OSChatMessage oscm) 502 private void OnChatFromWorld(object sender, OSChatMessage oscm)
369 { 503 {
370 m_scene.EventManager.OnChatFromWorld -= OnChatFromWorld;
371 Console.WriteLine("Got chat [{0}]", oscm.Message); 504 Console.WriteLine("Got chat [{0}]", oscm.Message);
372
373 m_osChatMessageReceived = oscm; 505 m_osChatMessageReceived = oscm;
374 m_chatEvent.Set(); 506
507 if (++m_chatMessagesReceived >= m_chatMessagesThreshold)
508 {
509 m_scene.EventManager.OnChatFromWorld -= OnChatFromWorld;
510 m_chatEvent.Set();
511 }
375 } 512 }
376 } 513 }
377} \ No newline at end of file 514} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 6e04e79..17243ab 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -49,7 +49,6 @@ using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Interfaces; 49using OpenSim.Region.Framework.Interfaces;
50using OpenSim.Region.ScriptEngine.Interfaces; 50using OpenSim.Region.ScriptEngine.Interfaces;
51using OpenSim.Region.ScriptEngine.Shared; 51using OpenSim.Region.ScriptEngine.Shared;
52using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
53using OpenSim.Region.ScriptEngine.Shared.CodeTools; 52using OpenSim.Region.ScriptEngine.Shared.CodeTools;
54using OpenSim.Region.ScriptEngine.Shared.Instance; 53using OpenSim.Region.ScriptEngine.Shared.Instance;
55using OpenSim.Region.ScriptEngine.Shared.Api; 54using OpenSim.Region.ScriptEngine.Shared.Api;
@@ -698,7 +697,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine
698 } 697 }
699 698
700 StringBuilder sb = new StringBuilder(); 699 StringBuilder sb = new StringBuilder();
701 Queue eq = instance.EventQueue;
702 700
703 sb.AppendFormat("Script name : {0}\n", instance.ScriptName); 701 sb.AppendFormat("Script name : {0}\n", instance.ScriptName);
704 sb.AppendFormat("Status : {0}\n", status); 702 sb.AppendFormat("Status : {0}\n", status);