aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2013-02-09 01:11:41 +0000
committerJustin Clark-Casey (justincc)2013-02-09 01:11:41 +0000
commit6935bec0ab83f25f69ad08e9bbc4b8d98aac1b1b (patch)
tree647e2ce5747ad8992111e9e89aefa825bffbbef2 /OpenSim
parentChange TestDestroyStore() and TestJsonRemoveValue() to reflect the fact that ... (diff)
parentBulletSim: add parameter to set global contact breaking threshold. Update DLL... (diff)
downloadopensim-SC-6935bec0ab83f25f69ad08e9bbc4b8d98aac1b1b.zip
opensim-SC-6935bec0ab83f25f69ad08e9bbc4b8d98aac1b1b.tar.gz
opensim-SC-6935bec0ab83f25f69ad08e9bbc4b8d98aac1b1b.tar.bz2
opensim-SC-6935bec0ab83f25f69ad08e9bbc4b8d98aac1b1b.tar.xz
Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
Diffstat (limited to 'OpenSim')
-rwxr-xr-xOpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs171
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs82
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs17
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs1
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs51
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs2
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs52
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs32
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs30
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSParam.cs8
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs27
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs195
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs118
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs179
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs6
15 files changed, 712 insertions, 259 deletions
diff --git a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs
new file mode 100755
index 0000000..6009dc5
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs
@@ -0,0 +1,171 @@
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 copyrightD
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 */
27using System;
28using System.Collections.Generic;
29using System.Linq;
30using System.Reflection;
31using System.Text;
32
33using OpenSim.Framework;
34using OpenSim.Region.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes;
37using OpenSim.Region.CoreModules;
38
39using Mono.Addins;
40using Nini.Config;
41using log4net;
42using OpenMetaverse;
43
44namespace OpenSim.Region.OptionalModules.Scripting
45{
46[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
47public class ExtendedPhysics : INonSharedRegionModule
48{
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50 private static string LogHeader = "[EXTENDED PHYSICS]";
51
52 private IConfig Configuration { get; set; }
53 private bool Enabled { get; set; }
54 private Scene BaseScene { get; set; }
55 private IScriptModuleComms Comms { get; set; }
56
57 #region INonSharedRegionModule
58
59 public string Name { get { return this.GetType().Name; } }
60
61 public void Initialise(IConfigSource config)
62 {
63 BaseScene = null;
64 Enabled = false;
65 Configuration = null;
66 Comms = null;
67
68 try
69 {
70 if ((Configuration = config.Configs["ExtendedPhysics"]) != null)
71 {
72 Enabled = Configuration.GetBoolean("Enabled", Enabled);
73 }
74 }
75 catch (Exception e)
76 {
77 m_log.ErrorFormat("{0} Initialization error: {0}", LogHeader, e);
78 }
79
80 m_log.InfoFormat("{0} module {1} enabled", LogHeader, (Enabled ? "is" : "is not"));
81 }
82
83 public void Close()
84 {
85 if (BaseScene != null)
86 {
87 BaseScene.EventManager.OnObjectAddedToScene -= EventManager_OnObjectAddedToScene;
88 BaseScene.EventManager.OnSceneObjectPartUpdated -= EventManager_OnSceneObjectPartUpdated;
89 BaseScene = null;
90 }
91 }
92
93 public void AddRegion(Scene scene)
94 {
95 }
96
97 public void RemoveRegion(Scene scene)
98 {
99 if (BaseScene != null && BaseScene == scene)
100 {
101 Close();
102 }
103 }
104
105 public void RegionLoaded(Scene scene)
106 {
107 if (!Enabled) return;
108
109 BaseScene = scene;
110
111 Comms = BaseScene.RequestModuleInterface<IScriptModuleComms>();
112 if (Comms == null)
113 {
114 m_log.WarnFormat("{0} ScriptModuleComms interface not defined", LogHeader);
115 Enabled = false;
116
117 return;
118 }
119
120 // Register as LSL functions all the [ScriptInvocation] marked methods.
121 Comms.RegisterScriptInvocations(this);
122
123 // When an object is modified, we might need to update its extended physics parameters
124 BaseScene.EventManager.OnObjectAddedToScene += EventManager_OnObjectAddedToScene;
125 BaseScene.EventManager.OnSceneObjectPartUpdated += EventManager_OnSceneObjectPartUpdated;
126
127 }
128
129 public Type ReplaceableInterface { get { return null; } }
130
131 #endregion // INonSharedRegionModule
132
133 private void EventManager_OnObjectAddedToScene(SceneObjectGroup obj)
134 {
135 throw new NotImplementedException();
136 }
137
138 // Event generated when some property of a prim changes.
139 private void EventManager_OnSceneObjectPartUpdated(SceneObjectPart sop, bool isFullUpdate)
140 {
141 }
142
143 [ScriptConstant]
144 public static int PHYS_CENTER_OF_MASS = 1 << 0;
145
146 [ScriptConstant]
147 public static int PHYS_LINKSET_TYPE_CONSTRAINT = 1;
148 [ScriptConstant]
149 public static int PHYS_LINKSET_TYPE_COMPOUND = 2;
150 [ScriptConstant]
151 public static int PHYS_LINKSET_TYPE_MANUAL = 3;
152
153 [ScriptInvocation]
154 public string physGetEngineType(UUID hostID, UUID scriptID)
155 {
156 string ret = string.Empty;
157
158 if (BaseScene.PhysicsScene != null)
159 {
160 ret = BaseScene.PhysicsScene.EngineType;
161 }
162
163 return ret;
164 }
165
166 [ScriptInvocation]
167 public void physSetLinksetType(UUID hostID, UUID scriptID, int linksetType)
168 {
169 }
170}
171}
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs
index c7f0001..5c89717 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs
@@ -95,6 +95,15 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
95 95
96 // ----------------------------------------------------------------- 96 // -----------------------------------------------------------------
97 /// <summary> 97 /// <summary>
98 /// This is a simple estimator for the size of the stored data, it
99 /// is not precise, but should be close enough to implement reasonable
100 /// limits on the storage space used
101 /// </summary>
102 // -----------------------------------------------------------------
103 public int StringSpace { get; set; }
104
105 // -----------------------------------------------------------------
106 /// <summary>
98 /// 107 ///
99 /// </summary> 108 /// </summary>
100 // ----------------------------------------------------------------- 109 // -----------------------------------------------------------------
@@ -110,6 +119,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
110 // ----------------------------------------------------------------- 119 // -----------------------------------------------------------------
111 public JsonStore() 120 public JsonStore()
112 { 121 {
122 StringSpace = 0;
113 m_TakeStore = new List<TakeValueCallbackClass>(); 123 m_TakeStore = new List<TakeValueCallbackClass>();
114 m_ReadStore = new List<TakeValueCallbackClass>(); 124 m_ReadStore = new List<TakeValueCallbackClass>();
115 } 125 }
@@ -135,7 +145,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
135 if (result == null) 145 if (result == null)
136 return false; 146 return false;
137 147
138 if (useJson || result.Type == OSDType.String) 148 if (useJson || OSDBaseType(result.Type))
139 return true; 149 return true;
140 150
141 return false; 151 return false;
@@ -247,6 +257,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
247 if (path.Count == 0) 257 if (path.Count == 0)
248 { 258 {
249 ValueStore = ovalue; 259 ValueStore = ovalue;
260 StringSpace = 0;
250 return true; 261 return true;
251 } 262 }
252 263
@@ -278,8 +289,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
278 { 289 {
279 string npkey = String.Format("[{0}]",amap.Count); 290 string npkey = String.Format("[{0}]",amap.Count);
280 291
281 amap.Add(ovalue); 292 if (ovalue != null)
282 InvokeNextCallback(pexpr + npkey); 293 {
294 StringSpace += ComputeSizeOf(ovalue);
295
296 amap.Add(ovalue);
297 InvokeNextCallback(pexpr + npkey);
298 }
283 return true; 299 return true;
284 } 300 }
285 301
@@ -287,9 +303,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
287 if (0 <= aval && aval < amap.Count) 303 if (0 <= aval && aval < amap.Count)
288 { 304 {
289 if (ovalue == null) 305 if (ovalue == null)
306 {
307 StringSpace -= ComputeSizeOf(amap[aval]);
290 amap.RemoveAt(aval); 308 amap.RemoveAt(aval);
309 }
291 else 310 else
292 { 311 {
312 StringSpace -= ComputeSizeOf(amap[aval]);
313 StringSpace += ComputeSizeOf(ovalue);
293 amap[aval] = ovalue; 314 amap[aval] = ovalue;
294 InvokeNextCallback(pexpr + pkey); 315 InvokeNextCallback(pexpr + pkey);
295 } 316 }
@@ -313,6 +334,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
313 OSDMap hmap = result as OSDMap; 334 OSDMap hmap = result as OSDMap;
314 if (ovalue != null) 335 if (ovalue != null)
315 { 336 {
337 StringSpace -= ComputeSizeOf(hmap[hkey]);
338 StringSpace += ComputeSizeOf(ovalue);
339
316 hmap[hkey] = ovalue; 340 hmap[hkey] = ovalue;
317 InvokeNextCallback(pexpr + pkey); 341 InvokeNextCallback(pexpr + pkey);
318 return true; 342 return true;
@@ -321,6 +345,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
321 // this is the remove case 345 // this is the remove case
322 if (hmap.ContainsKey(hkey)) 346 if (hmap.ContainsKey(hkey))
323 { 347 {
348 StringSpace -= ComputeSizeOf(hmap[hkey]);
324 hmap.Remove(hkey); 349 hmap.Remove(hkey);
325 return true; 350 return true;
326 } 351 }
@@ -506,7 +531,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
506 return true; 531 return true;
507 } 532 }
508 533
509 if (result.Type == OSDType.String) 534 if (OSDBaseType(result.Type))
510 { 535 {
511 value = result.AsString(); 536 value = result.AsString();
512 return true; 537 return true;
@@ -531,8 +556,54 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
531 556
532 return pkey; 557 return pkey;
533 } 558 }
559
560 // -----------------------------------------------------------------
561 /// <summary>
562 ///
563 /// </summary>
564 // -----------------------------------------------------------------
565 protected static bool OSDBaseType(OSDType type)
566 {
567 // Should be the list of base types for which AsString() returns
568 // something useful
569 if (type == OSDType.Boolean)
570 return true;
571 if (type == OSDType.Integer)
572 return true;
573 if (type == OSDType.Real)
574 return true;
575 if (type == OSDType.String)
576 return true;
577 if (type == OSDType.UUID)
578 return true;
579 if (type == OSDType.Date)
580 return true;
581 if (type == OSDType.URI)
582 return true;
583
584 return false;
585 }
586
587 // -----------------------------------------------------------------
588 /// <summary>
589 ///
590 /// </summary>
591 // -----------------------------------------------------------------
592 protected static int ComputeSizeOf(OSD value)
593 {
594 string sval;
595
596 if (ConvertOutputValue(value,out sval,true))
597 return sval.Length;
598
599 return 0;
600 }
534 } 601 }
535 602
603 // -----------------------------------------------------------------
604 /// <summary>
605 /// </summary>
606 // -----------------------------------------------------------------
536 public class JsonObjectStore : JsonStore 607 public class JsonObjectStore : JsonStore
537 { 608 {
538 private static readonly ILog m_log = 609 private static readonly ILog m_log =
@@ -566,6 +637,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
566 { 637 {
567 m_scene = scene; 638 m_scene = scene;
568 m_objectID = oid; 639 m_objectID = oid;
640
641 // the size limit is imposed on whatever is already in the store
642 StringSpace = ComputeSizeOf(ValueStore);
569 } 643 }
570 } 644 }
571 645
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
index 3249aa3..f1ce856 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
@@ -54,6 +54,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
54 54
55 private IConfig m_config = null; 55 private IConfig m_config = null;
56 private bool m_enabled = false; 56 private bool m_enabled = false;
57 private bool m_enableObjectStore = false;
58 private int m_maxStringSpace = Int32.MaxValue;
59
57 private Scene m_scene = null; 60 private Scene m_scene = null;
58 61
59 private Dictionary<UUID,JsonStore> m_JsonValueStore; 62 private Dictionary<UUID,JsonStore> m_JsonValueStore;
@@ -90,6 +93,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
90 } 93 }
91 94
92 m_enabled = m_config.GetBoolean("Enabled", m_enabled); 95 m_enabled = m_config.GetBoolean("Enabled", m_enabled);
96 m_enableObjectStore = m_config.GetBoolean("EnableObjectStore", m_enableObjectStore);
97 m_maxStringSpace = m_config.GetInt("MaxStringSpace", m_maxStringSpace);
98 if (m_maxStringSpace == 0)
99 m_maxStringSpace = Int32.MaxValue;
93 } 100 }
94 catch (Exception e) 101 catch (Exception e)
95 { 102 {
@@ -178,6 +185,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
178 public bool AttachObjectStore(UUID objectID) 185 public bool AttachObjectStore(UUID objectID)
179 { 186 {
180 if (! m_enabled) return false; 187 if (! m_enabled) return false;
188 if (! m_enableObjectStore) return false;
181 189
182 SceneObjectPart sop = m_scene.GetSceneObjectPart(objectID); 190 SceneObjectPart sop = m_scene.GetSceneObjectPart(objectID);
183 if (sop == null) 191 if (sop == null)
@@ -311,7 +319,16 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
311 try 319 try
312 { 320 {
313 lock (map) 321 lock (map)
322 {
323 if (map.StringSpace > m_maxStringSpace)
324 {
325 m_log.WarnFormat("[JsonStore] {0} exceeded string size; {1} bytes used of {2} limit",
326 storeID,map.StringSpace,m_maxStringSpace);
327 return false;
328 }
329
314 return map.SetValue(path,value,useJson); 330 return map.SetValue(path,value,useJson);
331 }
315 } 332 }
316 catch (Exception e) 333 catch (Exception e)
317 { 334 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs
index 5e06c1e..7ab86d2 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs
@@ -183,6 +183,7 @@ public struct ConfigurationParameters
183 public float shouldEnableFrictionCaching; 183 public float shouldEnableFrictionCaching;
184 public float numberOfSolverIterations; 184 public float numberOfSolverIterations;
185 public float useSingleSidedMeshes; 185 public float useSingleSidedMeshes;
186 public float globalContactBreakingThreshold;
186 187
187 public float physicsLoggingFrames; 188 public float physicsLoggingFrames;
188 189
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index d694a6a..f781aea 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -45,7 +45,6 @@ public sealed class BSCharacter : BSPhysObject
45 private bool _selected; 45 private bool _selected;
46 private OMV.Vector3 _position; 46 private OMV.Vector3 _position;
47 private float _mass; 47 private float _mass;
48 private float _avatarDensity;
49 private float _avatarVolume; 48 private float _avatarVolume;
50 private OMV.Vector3 _force; 49 private OMV.Vector3 _force;
51 private OMV.Vector3 _velocity; 50 private OMV.Vector3 _velocity;
@@ -63,9 +62,6 @@ public sealed class BSCharacter : BSPhysObject
63 private bool _kinematic; 62 private bool _kinematic;
64 private float _buoyancy; 63 private float _buoyancy;
65 64
66 // The friction and velocity of the avatar is modified depending on whether walking or not.
67 private float _currentFriction; // the friction currently being used (changed by setVelocity).
68
69 private BSVMotor _velocityMotor; 65 private BSVMotor _velocityMotor;
70 66
71 private OMV.Vector3 _PIDTarget; 67 private OMV.Vector3 _PIDTarget;
@@ -86,8 +82,8 @@ public sealed class BSCharacter : BSPhysObject
86 _orientation = OMV.Quaternion.Identity; 82 _orientation = OMV.Quaternion.Identity;
87 _velocity = OMV.Vector3.Zero; 83 _velocity = OMV.Vector3.Zero;
88 _buoyancy = ComputeBuoyancyFromFlying(isFlying); 84 _buoyancy = ComputeBuoyancyFromFlying(isFlying);
89 _currentFriction = BSParam.AvatarStandingFriction; 85 Friction = BSParam.AvatarStandingFriction;
90 _avatarDensity = BSParam.AvatarDensity; 86 Density = BSParam.AvatarDensity;
91 87
92 // Old versions of ScenePresence passed only the height. If width and/or depth are zero, 88 // Old versions of ScenePresence passed only the height. If width and/or depth are zero,
93 // replace with the default values. 89 // replace with the default values.
@@ -104,7 +100,7 @@ public sealed class BSCharacter : BSPhysObject
104 SetupMovementMotor(); 100 SetupMovementMotor();
105 101
106 DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}", 102 DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}",
107 LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass); 103 LocalID, _size, Scale, Density, _avatarVolume, RawMass);
108 104
109 // do actual creation in taint time 105 // do actual creation in taint time
110 PhysicsScene.TaintedObject("BSCharacter.create", delegate() 106 PhysicsScene.TaintedObject("BSCharacter.create", delegate()
@@ -140,7 +136,7 @@ public sealed class BSCharacter : BSPhysObject
140 ZeroMotion(true); 136 ZeroMotion(true);
141 ForcePosition = _position; 137 ForcePosition = _position;
142 138
143 // Set the velocity and compute the proper friction 139 // Set the velocity
144 _velocityMotor.Reset(); 140 _velocityMotor.Reset();
145 _velocityMotor.SetTarget(_velocity); 141 _velocityMotor.SetTarget(_velocity);
146 _velocityMotor.SetCurrent(_velocity); 142 _velocityMotor.SetCurrent(_velocity);
@@ -214,35 +210,38 @@ public sealed class BSCharacter : BSPhysObject
214 _velocityMotor.Step(timeStep); 210 _velocityMotor.Step(timeStep);
215 211
216 // If we're not supposed to be moving, make sure things are zero. 212 // If we're not supposed to be moving, make sure things are zero.
217 if (_velocityMotor.ErrorIsZero() && _velocityMotor.TargetValue == OMV.Vector3.Zero && IsColliding) 213 if (_velocityMotor.ErrorIsZero() && _velocityMotor.TargetValue == OMV.Vector3.Zero)
218 { 214 {
219 // The avatar shouldn't be moving 215 // The avatar shouldn't be moving
220 _velocityMotor.Zero(); 216 _velocityMotor.Zero();
221 217
222 // If we are colliding with a stationary object, presume we're standing and don't move around 218 if (IsColliding)
223 if (!ColliderIsMoving)
224 { 219 {
225 DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", LocalID); 220 // If we are colliding with a stationary object, presume we're standing and don't move around
226 ZeroMotion(true /* inTaintTime */); 221 if (!ColliderIsMoving)
227 } 222 {
223 DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", LocalID);
224 ZeroMotion(true /* inTaintTime */);
225 }
228 226
229 // Standing has more friction on the ground 227 // Standing has more friction on the ground
230 if (_currentFriction != BSParam.AvatarStandingFriction) 228 if (Friction != BSParam.AvatarStandingFriction)
231 { 229 {
232 _currentFriction = BSParam.AvatarStandingFriction; 230 Friction = BSParam.AvatarStandingFriction;
233 PhysicsScene.PE.SetFriction(PhysBody, _currentFriction); 231 PhysicsScene.PE.SetFriction(PhysBody, Friction);
232 }
234 } 233 }
235 DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1}", LocalID, _velocityMotor.TargetValue); 234 DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1},colliding={2}", LocalID, _velocityMotor.TargetValue, IsColliding);
236 } 235 }
237 else 236 else
238 { 237 {
239 OMV.Vector3 stepVelocity = _velocityMotor.CurrentValue; 238 OMV.Vector3 stepVelocity = _velocityMotor.CurrentValue;
240 239
241 if (_currentFriction != BSParam.AvatarFriction) 240 if (Friction != BSParam.AvatarFriction)
242 { 241 {
243 // Probably starting up walking. Set friction to moving friction. 242 // Probably starting up walking. Set friction to moving friction.
244 _currentFriction = BSParam.AvatarFriction; 243 Friction = BSParam.AvatarFriction;
245 PhysicsScene.PE.SetFriction(PhysBody, _currentFriction); 244 PhysicsScene.PE.SetFriction(PhysBody, Friction);
246 } 245 }
247 246
248 // If falling, we keep the world's downward vector no matter what the other axis specify. 247 // If falling, we keep the world's downward vector no matter what the other axis specify.
@@ -342,7 +341,7 @@ public sealed class BSCharacter : BSPhysObject
342 Scale = ComputeAvatarScale(_size); 341 Scale = ComputeAvatarScale(_size);
343 ComputeAvatarVolumeAndMass(); 342 ComputeAvatarVolumeAndMass();
344 DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}", 343 DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}",
345 LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass); 344 LocalID, _size, Scale, Density, _avatarVolume, RawMass);
346 345
347 PhysicsScene.TaintedObject("BSCharacter.setSize", delegate() 346 PhysicsScene.TaintedObject("BSCharacter.setSize", delegate()
348 { 347 {
@@ -870,7 +869,7 @@ public sealed class BSCharacter : BSPhysObject
870 * Math.Min(Size.X, Size.Y) / 2 869 * Math.Min(Size.X, Size.Y) / 2
871 * Size.Y / 2f // plus the volume of the capsule end caps 870 * Size.Y / 2f // plus the volume of the capsule end caps
872 ); 871 );
873 _mass = _avatarDensity * _avatarVolume; 872 _mass = Density * _avatarVolume;
874 } 873 }
875 874
876 // The physics engine says that properties have updated. Update same and inform 875 // The physics engine says that properties have updated. Update same and inform
@@ -901,7 +900,7 @@ public sealed class BSCharacter : BSPhysObject
901 CurrentEntityProperties = entprop; 900 CurrentEntityProperties = entprop;
902 901
903 // Tell the linkset about value changes 902 // Tell the linkset about value changes
904 Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this); 903 // Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);
905 904
906 // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. 905 // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
907 // base.RequestPhysicsterseUpdate(); 906 // base.RequestPhysicsterseUpdate();
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index b51e9fd..41d353a 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -597,7 +597,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
597 if (IsActive) 597 if (IsActive)
598 { 598 {
599 // Remember the mass so we don't have to fetch it every step 599 // Remember the mass so we don't have to fetch it every step
600 m_vehicleMass = Prim.Linkset.LinksetMass; 600 m_vehicleMass = Prim.TotalMass;
601 601
602 // Friction affects are handled by this vehicle code 602 // Friction affects are handled by this vehicle code
603 PhysicsScene.PE.SetFriction(Prim.PhysBody, BSParam.VehicleFriction); 603 PhysicsScene.PE.SetFriction(Prim.PhysBody, BSParam.VehicleFriction);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index 1e3e5d8..e35311f 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -52,7 +52,7 @@ public abstract class BSLinkset
52 Manual = 2 // linkset tied together manually (code moves all the pieces) 52 Manual = 2 // linkset tied together manually (code moves all the pieces)
53 } 53 }
54 // Create the correct type of linkset for this child 54 // Create the correct type of linkset for this child
55 public static BSLinkset Factory(BSScene physScene, BSPhysObject parent) 55 public static BSLinkset Factory(BSScene physScene, BSPrimLinkable parent)
56 { 56 {
57 BSLinkset ret = null; 57 BSLinkset ret = null;
58 58
@@ -71,10 +71,14 @@ public abstract class BSLinkset
71 ret = new BSLinksetCompound(physScene, parent); 71 ret = new BSLinksetCompound(physScene, parent);
72 break; 72 break;
73 } 73 }
74 if (ret == null)
75 {
76 physScene.Logger.ErrorFormat("[BULLETSIM LINKSET] Factory could not create linkset. Parent name={1}, ID={2}", parent.Name, parent.LocalID);
77 }
74 return ret; 78 return ret;
75 } 79 }
76 80
77 public BSPhysObject LinksetRoot { get; protected set; } 81 public BSPrimLinkable LinksetRoot { get; protected set; }
78 82
79 public BSScene PhysicsScene { get; private set; } 83 public BSScene PhysicsScene { get; private set; }
80 84
@@ -82,7 +86,7 @@ public abstract class BSLinkset
82 public int LinksetID { get; private set; } 86 public int LinksetID { get; private set; }
83 87
84 // The children under the root in this linkset. 88 // The children under the root in this linkset.
85 protected HashSet<BSPhysObject> m_children; 89 protected HashSet<BSPrimLinkable> m_children;
86 90
87 // We lock the diddling of linkset classes to prevent any badness. 91 // We lock the diddling of linkset classes to prevent any badness.
88 // This locks the modification of the instances of this class. Changes 92 // This locks the modification of the instances of this class. Changes
@@ -91,7 +95,7 @@ public abstract class BSLinkset
91 95
92 // Some linksets have a preferred physical shape. 96 // Some linksets have a preferred physical shape.
93 // Returns SHAPE_UNKNOWN if there is no preference. Causes the correct shape to be selected. 97 // Returns SHAPE_UNKNOWN if there is no preference. Causes the correct shape to be selected.
94 public virtual BSPhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor) 98 public virtual BSPhysicsShapeType PreferredPhysicalShape(BSPrimLinkable requestor)
95 { 99 {
96 return BSPhysicsShapeType.SHAPE_UNKNOWN; 100 return BSPhysicsShapeType.SHAPE_UNKNOWN;
97 } 101 }
@@ -111,7 +115,7 @@ public abstract class BSLinkset
111 get { return ComputeLinksetGeometricCenter(); } 115 get { return ComputeLinksetGeometricCenter(); }
112 } 116 }
113 117
114 protected BSLinkset(BSScene scene, BSPhysObject parent) 118 protected BSLinkset(BSScene scene, BSPrimLinkable parent)
115 { 119 {
116 // A simple linkset of one (no children) 120 // A simple linkset of one (no children)
117 LinksetID = m_nextLinksetID++; 121 LinksetID = m_nextLinksetID++;
@@ -120,7 +124,7 @@ public abstract class BSLinkset
120 m_nextLinksetID = 1; 124 m_nextLinksetID = 1;
121 PhysicsScene = scene; 125 PhysicsScene = scene;
122 LinksetRoot = parent; 126 LinksetRoot = parent;
123 m_children = new HashSet<BSPhysObject>(); 127 m_children = new HashSet<BSPrimLinkable>();
124 LinksetMass = parent.RawMass; 128 LinksetMass = parent.RawMass;
125 Rebuilding = false; 129 Rebuilding = false;
126 } 130 }
@@ -129,7 +133,7 @@ public abstract class BSLinkset
129 // Parent changing should not happen so do some sanity checking. 133 // Parent changing should not happen so do some sanity checking.
130 // We return the parent's linkset so the child can track its membership. 134 // We return the parent's linkset so the child can track its membership.
131 // Called at runtime. 135 // Called at runtime.
132 public BSLinkset AddMeToLinkset(BSPhysObject child) 136 public BSLinkset AddMeToLinkset(BSPrimLinkable child)
133 { 137 {
134 lock (m_linksetActivityLock) 138 lock (m_linksetActivityLock)
135 { 139 {
@@ -145,14 +149,13 @@ public abstract class BSLinkset
145 // Returns a new linkset for the child which is a linkset of one (just the 149 // Returns a new linkset for the child which is a linkset of one (just the
146 // orphened child). 150 // orphened child).
147 // Called at runtime. 151 // Called at runtime.
148 public BSLinkset RemoveMeFromLinkset(BSPhysObject child) 152 public BSLinkset RemoveMeFromLinkset(BSPrimLinkable child)
149 { 153 {
150 lock (m_linksetActivityLock) 154 lock (m_linksetActivityLock)
151 { 155 {
152 if (IsRoot(child)) 156 if (IsRoot(child))
153 { 157 {
154 // Cannot remove the root from a linkset. 158 // Cannot remove the root from a linkset.
155 child.PositionDisplacement = OMV.Vector3.Zero;
156 return this; 159 return this;
157 } 160 }
158 RemoveChildFromLinkset(child); 161 RemoveChildFromLinkset(child);
@@ -160,12 +163,11 @@ public abstract class BSLinkset
160 } 163 }
161 164
162 // The child is down to a linkset of just itself 165 // The child is down to a linkset of just itself
163 child.PositionDisplacement = OMV.Vector3.Zero;
164 return BSLinkset.Factory(PhysicsScene, child); 166 return BSLinkset.Factory(PhysicsScene, child);
165 } 167 }
166 168
167 // Return 'true' if the passed object is the root object of this linkset 169 // Return 'true' if the passed object is the root object of this linkset
168 public bool IsRoot(BSPhysObject requestor) 170 public bool IsRoot(BSPrimLinkable requestor)
169 { 171 {
170 return (requestor.LocalID == LinksetRoot.LocalID); 172 return (requestor.LocalID == LinksetRoot.LocalID);
171 } 173 }
@@ -176,14 +178,14 @@ public abstract class BSLinkset
176 public bool HasAnyChildren { get { return (m_children.Count > 0); } } 178 public bool HasAnyChildren { get { return (m_children.Count > 0); } }
177 179
178 // Return 'true' if this child is in this linkset 180 // Return 'true' if this child is in this linkset
179 public bool HasChild(BSPhysObject child) 181 public bool HasChild(BSPrimLinkable child)
180 { 182 {
181 bool ret = false; 183 bool ret = false;
182 lock (m_linksetActivityLock) 184 lock (m_linksetActivityLock)
183 { 185 {
184 ret = m_children.Contains(child); 186 ret = m_children.Contains(child);
185 /* Safer version but the above should work 187 /* Safer version but the above should work
186 foreach (BSPhysObject bp in m_children) 188 foreach (BSPrimLinkable bp in m_children)
187 { 189 {
188 if (child.LocalID == bp.LocalID) 190 if (child.LocalID == bp.LocalID)
189 { 191 {
@@ -198,14 +200,14 @@ public abstract class BSLinkset
198 200
199 // Perform an action on each member of the linkset including root prim. 201 // Perform an action on each member of the linkset including root prim.
200 // Depends on the action on whether this should be done at taint time. 202 // Depends on the action on whether this should be done at taint time.
201 public delegate bool ForEachMemberAction(BSPhysObject obj); 203 public delegate bool ForEachMemberAction(BSPrimLinkable obj);
202 public virtual bool ForEachMember(ForEachMemberAction action) 204 public virtual bool ForEachMember(ForEachMemberAction action)
203 { 205 {
204 bool ret = false; 206 bool ret = false;
205 lock (m_linksetActivityLock) 207 lock (m_linksetActivityLock)
206 { 208 {
207 action(LinksetRoot); 209 action(LinksetRoot);
208 foreach (BSPhysObject po in m_children) 210 foreach (BSPrimLinkable po in m_children)
209 { 211 {
210 if (action(po)) 212 if (action(po))
211 break; 213 break;
@@ -216,16 +218,16 @@ public abstract class BSLinkset
216 218
217 // I am the root of a linkset and a new child is being added 219 // I am the root of a linkset and a new child is being added
218 // Called while LinkActivity is locked. 220 // Called while LinkActivity is locked.
219 protected abstract void AddChildToLinkset(BSPhysObject child); 221 protected abstract void AddChildToLinkset(BSPrimLinkable child);
220 222
221 // I am the root of a linkset and one of my children is being removed. 223 // I am the root of a linkset and one of my children is being removed.
222 // Safe to call even if the child is not really in my linkset. 224 // Safe to call even if the child is not really in my linkset.
223 protected abstract void RemoveChildFromLinkset(BSPhysObject child); 225 protected abstract void RemoveChildFromLinkset(BSPrimLinkable child);
224 226
225 // When physical properties are changed the linkset needs to recalculate 227 // When physical properties are changed the linkset needs to recalculate
226 // its internal properties. 228 // its internal properties.
227 // May be called at runtime or taint-time. 229 // May be called at runtime or taint-time.
228 public virtual void Refresh(BSPhysObject requestor) 230 public virtual void Refresh(BSPrimLinkable requestor)
229 { 231 {
230 LinksetMass = ComputeLinksetMass(); 232 LinksetMass = ComputeLinksetMass();
231 } 233 }
@@ -240,26 +242,26 @@ public abstract class BSLinkset
240 // has not yet been fully constructed. 242 // has not yet been fully constructed.
241 // Return 'true' if any properties updated on the passed object. 243 // Return 'true' if any properties updated on the passed object.
242 // Called at taint-time! 244 // Called at taint-time!
243 public abstract bool MakeDynamic(BSPhysObject child); 245 public abstract bool MakeDynamic(BSPrimLinkable child);
244 246
245 // The object is going static (non-physical). Do any setup necessary 247 // The object is going static (non-physical). Do any setup necessary
246 // for a static linkset. 248 // for a static linkset.
247 // Return 'true' if any properties updated on the passed object. 249 // Return 'true' if any properties updated on the passed object.
248 // Called at taint-time! 250 // Called at taint-time!
249 public abstract bool MakeStatic(BSPhysObject child); 251 public abstract bool MakeStatic(BSPrimLinkable child);
250 252
251 // Called when a parameter update comes from the physics engine for any object 253 // Called when a parameter update comes from the physics engine for any object
252 // of the linkset is received. 254 // of the linkset is received.
253 // Passed flag is update came from physics engine (true) or the user (false). 255 // Passed flag is update came from physics engine (true) or the user (false).
254 // Called at taint-time!! 256 // Called at taint-time!!
255 public abstract void UpdateProperties(UpdatedProperties whichUpdated, BSPhysObject physObject); 257 public abstract void UpdateProperties(UpdatedProperties whichUpdated, BSPrimLinkable physObject);
256 258
257 // Routine used when rebuilding the body of the root of the linkset 259 // Routine used when rebuilding the body of the root of the linkset
258 // Destroy all the constraints have have been made to root. 260 // Destroy all the constraints have have been made to root.
259 // This is called when the root body is changing. 261 // This is called when the root body is changing.
260 // Returns 'true' of something was actually removed and would need restoring 262 // Returns 'true' of something was actually removed and would need restoring
261 // Called at taint-time!! 263 // Called at taint-time!!
262 public abstract bool RemoveBodyDependencies(BSPrim child); 264 public abstract bool RemoveBodyDependencies(BSPrimLinkable child);
263 265
264 // ================================================================ 266 // ================================================================
265 protected virtual float ComputeLinksetMass() 267 protected virtual float ComputeLinksetMass()
@@ -269,7 +271,7 @@ public abstract class BSLinkset
269 { 271 {
270 lock (m_linksetActivityLock) 272 lock (m_linksetActivityLock)
271 { 273 {
272 foreach (BSPhysObject bp in m_children) 274 foreach (BSPrimLinkable bp in m_children)
273 { 275 {
274 mass += bp.RawMass; 276 mass += bp.RawMass;
275 } 277 }
@@ -286,7 +288,7 @@ public abstract class BSLinkset
286 com = LinksetRoot.Position * LinksetRoot.RawMass; 288 com = LinksetRoot.Position * LinksetRoot.RawMass;
287 float totalMass = LinksetRoot.RawMass; 289 float totalMass = LinksetRoot.RawMass;
288 290
289 foreach (BSPhysObject bp in m_children) 291 foreach (BSPrimLinkable bp in m_children)
290 { 292 {
291 com += bp.Position * bp.RawMass; 293 com += bp.Position * bp.RawMass;
292 totalMass += bp.RawMass; 294 totalMass += bp.RawMass;
@@ -305,7 +307,7 @@ public abstract class BSLinkset
305 { 307 {
306 com = LinksetRoot.Position; 308 com = LinksetRoot.Position;
307 309
308 foreach (BSPhysObject bp in m_children) 310 foreach (BSPrimLinkable bp in m_children)
309 { 311 {
310 com += bp.Position; 312 com += bp.Position;
311 } 313 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
index 0c4db40..36bae9b 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
@@ -52,7 +52,7 @@ sealed class BSLinksetCompoundInfo : BSLinksetInfo
52 OffsetRot = r; 52 OffsetRot = r;
53 } 53 }
54 // 'centerDisplacement' is the distance from the root the the center-of-mass (Bullet 'zero' of the shape) 54 // 'centerDisplacement' is the distance from the root the the center-of-mass (Bullet 'zero' of the shape)
55 public BSLinksetCompoundInfo(int indx, BSPhysObject root, BSPhysObject child, OMV.Vector3 centerDisplacement) 55 public BSLinksetCompoundInfo(int indx, BSPrimLinkable root, BSPrimLinkable child, OMV.Vector3 centerDisplacement)
56 { 56 {
57 // Each child position and rotation is given relative to the center-of-mass. 57 // Each child position and rotation is given relative to the center-of-mass.
58 OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(root.RawOrientation); 58 OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(root.RawOrientation);
@@ -93,12 +93,12 @@ public sealed class BSLinksetCompound : BSLinkset
93{ 93{
94 private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]"; 94 private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]";
95 95
96 public BSLinksetCompound(BSScene scene, BSPhysObject parent) : base(scene, parent) 96 public BSLinksetCompound(BSScene scene, BSPrimLinkable parent) : base(scene, parent)
97 { 97 {
98 } 98 }
99 99
100 // For compound implimented linksets, if there are children, use compound shape for the root. 100 // For compound implimented linksets, if there are children, use compound shape for the root.
101 public override BSPhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor) 101 public override BSPhysicsShapeType PreferredPhysicalShape(BSPrimLinkable requestor)
102 { 102 {
103 // Returning 'unknown' means we don't have a preference. 103 // Returning 'unknown' means we don't have a preference.
104 BSPhysicsShapeType ret = BSPhysicsShapeType.SHAPE_UNKNOWN; 104 BSPhysicsShapeType ret = BSPhysicsShapeType.SHAPE_UNKNOWN;
@@ -112,7 +112,7 @@ public sealed class BSLinksetCompound : BSLinkset
112 112
113 // When physical properties are changed the linkset needs to recalculate 113 // When physical properties are changed the linkset needs to recalculate
114 // its internal properties. 114 // its internal properties.
115 public override void Refresh(BSPhysObject requestor) 115 public override void Refresh(BSPrimLinkable requestor)
116 { 116 {
117 base.Refresh(requestor); 117 base.Refresh(requestor);
118 118
@@ -121,7 +121,7 @@ public sealed class BSLinksetCompound : BSLinkset
121 } 121 }
122 122
123 // Schedule a refresh to happen after all the other taint processing. 123 // Schedule a refresh to happen after all the other taint processing.
124 private void ScheduleRebuild(BSPhysObject requestor) 124 private void ScheduleRebuild(BSPrimLinkable requestor)
125 { 125 {
126 DetailLog("{0},BSLinksetCompound.ScheduleRebuild,,rebuilding={1},hasChildren={2},actuallyScheduling={3}", 126 DetailLog("{0},BSLinksetCompound.ScheduleRebuild,,rebuilding={1},hasChildren={2},actuallyScheduling={3}",
127 requestor.LocalID, Rebuilding, HasAnyChildren, (!Rebuilding && HasAnyChildren)); 127 requestor.LocalID, Rebuilding, HasAnyChildren, (!Rebuilding && HasAnyChildren));
@@ -143,7 +143,7 @@ public sealed class BSLinksetCompound : BSLinkset
143 // has not yet been fully constructed. 143 // has not yet been fully constructed.
144 // Return 'true' if any properties updated on the passed object. 144 // Return 'true' if any properties updated on the passed object.
145 // Called at taint-time! 145 // Called at taint-time!
146 public override bool MakeDynamic(BSPhysObject child) 146 public override bool MakeDynamic(BSPrimLinkable child)
147 { 147 {
148 bool ret = false; 148 bool ret = false;
149 DetailLog("{0},BSLinksetCompound.MakeDynamic,call,IsRoot={1}", child.LocalID, IsRoot(child)); 149 DetailLog("{0},BSLinksetCompound.MakeDynamic,call,IsRoot={1}", child.LocalID, IsRoot(child));
@@ -173,7 +173,7 @@ public sealed class BSLinksetCompound : BSLinkset
173 // This doesn't normally happen -- OpenSim removes the objects from the physical 173 // This doesn't normally happen -- OpenSim removes the objects from the physical
174 // world if it is a static linkset. 174 // world if it is a static linkset.
175 // Called at taint-time! 175 // Called at taint-time!
176 public override bool MakeStatic(BSPhysObject child) 176 public override bool MakeStatic(BSPrimLinkable child)
177 { 177 {
178 bool ret = false; 178 bool ret = false;
179 DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child)); 179 DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child));
@@ -197,7 +197,7 @@ public sealed class BSLinksetCompound : BSLinkset
197 197
198 // 'physicalUpdate' is true if these changes came directly from the physics engine. Don't need to rebuild then. 198 // 'physicalUpdate' is true if these changes came directly from the physics engine. Don't need to rebuild then.
199 // Called at taint-time. 199 // Called at taint-time.
200 public override void UpdateProperties(UpdatedProperties whichUpdated, BSPhysObject updated) 200 public override void UpdateProperties(UpdatedProperties whichUpdated, BSPrimLinkable updated)
201 { 201 {
202 // The user moving a child around requires the rebuilding of the linkset compound shape 202 // The user moving a child around requires the rebuilding of the linkset compound shape
203 // One problem is this happens when a border is crossed -- the simulator implementation 203 // One problem is this happens when a border is crossed -- the simulator implementation
@@ -222,7 +222,7 @@ public sealed class BSLinksetCompound : BSLinkset
222 if (lsi != null) 222 if (lsi != null)
223 { 223 {
224 // Since the child moved or rotationed, it needs a new relative position within the linkset 224 // Since the child moved or rotationed, it needs a new relative position within the linkset
225 BSLinksetCompoundInfo newLsi = new BSLinksetCompoundInfo(lsi.Index, LinksetRoot, updated, LinksetRoot.PositionDisplacement); 225 BSLinksetCompoundInfo newLsi = new BSLinksetCompoundInfo(lsi.Index, LinksetRoot, updated, OMV.Vector3.Zero);
226 updated.LinksetInfo = newLsi; 226 updated.LinksetInfo = newLsi;
227 227
228 // Find the physical instance of the child 228 // Find the physical instance of the child
@@ -291,7 +291,7 @@ public sealed class BSLinksetCompound : BSLinkset
291 // Since we don't keep in world relationships, do nothing unless it's a child changing. 291 // Since we don't keep in world relationships, do nothing unless it's a child changing.
292 // Returns 'true' of something was actually removed and would need restoring 292 // Returns 'true' of something was actually removed and would need restoring
293 // Called at taint-time!! 293 // Called at taint-time!!
294 public override bool RemoveBodyDependencies(BSPrim child) 294 public override bool RemoveBodyDependencies(BSPrimLinkable child)
295 { 295 {
296 bool ret = false; 296 bool ret = false;
297 297
@@ -316,7 +316,7 @@ public sealed class BSLinksetCompound : BSLinkset
316 // When the linkset is built, the child shape is added to the compound shape relative to the 316 // When the linkset is built, the child shape is added to the compound shape relative to the
317 // root shape. The linkset then moves around but this does not move the actual child 317 // root shape. The linkset then moves around but this does not move the actual child
318 // prim. The child prim's location must be recomputed based on the location of the root shape. 318 // prim. The child prim's location must be recomputed based on the location of the root shape.
319 private void RecomputeChildWorldPosition(BSPhysObject child, bool inTaintTime) 319 private void RecomputeChildWorldPosition(BSPrimLinkable child, bool inTaintTime)
320 { 320 {
321 // For the moment (20130201), disable this computation (converting the child physical addr back to 321 // For the moment (20130201), disable this computation (converting the child physical addr back to
322 // a region address) until we have a good handle on center-of-mass offsets and what the physics 322 // a region address) until we have a good handle on center-of-mass offsets and what the physics
@@ -361,7 +361,7 @@ public sealed class BSLinksetCompound : BSLinkset
361 361
362 // Add a new child to the linkset. 362 // Add a new child to the linkset.
363 // Called while LinkActivity is locked. 363 // Called while LinkActivity is locked.
364 protected override void AddChildToLinkset(BSPhysObject child) 364 protected override void AddChildToLinkset(BSPrimLinkable child)
365 { 365 {
366 if (!HasChild(child)) 366 if (!HasChild(child))
367 { 367 {
@@ -377,7 +377,7 @@ public sealed class BSLinksetCompound : BSLinkset
377 377
378 // Remove the specified child from the linkset. 378 // Remove the specified child from the linkset.
379 // Safe to call even if the child is not really in the linkset. 379 // Safe to call even if the child is not really in the linkset.
380 protected override void RemoveChildFromLinkset(BSPhysObject child) 380 protected override void RemoveChildFromLinkset(BSPrimLinkable child)
381 { 381 {
382 if (m_children.Remove(child)) 382 if (m_children.Remove(child))
383 { 383 {
@@ -429,7 +429,7 @@ public sealed class BSLinksetCompound : BSLinkset
429 if (disableCOM) // DEBUG DEBUG 429 if (disableCOM) // DEBUG DEBUG
430 { // DEBUG DEBUG 430 { // DEBUG DEBUG
431 centerOfMass = LinksetRoot.RawPosition; // DEBUG DEBUG 431 centerOfMass = LinksetRoot.RawPosition; // DEBUG DEBUG
432 LinksetRoot.PositionDisplacement = OMV.Vector3.Zero; 432 // LinksetRoot.PositionDisplacement = OMV.Vector3.Zero;
433 } // DEBUG DEBUG 433 } // DEBUG DEBUG
434 else 434 else
435 { 435 {
@@ -438,7 +438,7 @@ public sealed class BSLinksetCompound : BSLinkset
438 centerDisplacement = LinksetRoot.RawPosition - centerOfMass; 438 centerDisplacement = LinksetRoot.RawPosition - centerOfMass;
439 439
440 // Since we're displacing the center of the shape, we need to move the body in the world 440 // Since we're displacing the center of the shape, we need to move the body in the world
441 LinksetRoot.PositionDisplacement = centerDisplacement; 441 // LinksetRoot.PositionDisplacement = centerDisplacement;
442 442
443 // This causes the root prim position to be set properly based on the new PositionDisplacement 443 // This causes the root prim position to be set properly based on the new PositionDisplacement
444 LinksetRoot.ForcePosition = LinksetRoot.RawPosition; 444 LinksetRoot.ForcePosition = LinksetRoot.RawPosition;
@@ -453,7 +453,7 @@ public sealed class BSLinksetCompound : BSLinkset
453 453
454 // Add a shape for each of the other children in the linkset 454 // Add a shape for each of the other children in the linkset
455 int memberIndex = 1; 455 int memberIndex = 1;
456 ForEachMember(delegate(BSPhysObject cPrim) 456 ForEachMember(delegate(BSPrimLinkable cPrim)
457 { 457 {
458 if (!IsRoot(cPrim)) 458 if (!IsRoot(cPrim))
459 { 459 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
index 3011465..cc814d1 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
@@ -36,7 +36,7 @@ public sealed class BSLinksetConstraints : BSLinkset
36{ 36{
37 // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]"; 37 // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]";
38 38
39 public BSLinksetConstraints(BSScene scene, BSPhysObject parent) : base(scene, parent) 39 public BSLinksetConstraints(BSScene scene, BSPrimLinkable parent) : base(scene, parent)
40 { 40 {
41 } 41 }
42 42
@@ -44,7 +44,7 @@ public sealed class BSLinksetConstraints : BSLinkset
44 // its internal properties. 44 // its internal properties.
45 // This is queued in the 'post taint' queue so the 45 // This is queued in the 'post taint' queue so the
46 // refresh will happen once after all the other taints are applied. 46 // refresh will happen once after all the other taints are applied.
47 public override void Refresh(BSPhysObject requestor) 47 public override void Refresh(BSPrimLinkable requestor)
48 { 48 {
49 base.Refresh(requestor); 49 base.Refresh(requestor);
50 50
@@ -65,7 +65,7 @@ public sealed class BSLinksetConstraints : BSLinkset
65 // has not yet been fully constructed. 65 // has not yet been fully constructed.
66 // Return 'true' if any properties updated on the passed object. 66 // Return 'true' if any properties updated on the passed object.
67 // Called at taint-time! 67 // Called at taint-time!
68 public override bool MakeDynamic(BSPhysObject child) 68 public override bool MakeDynamic(BSPrimLinkable child)
69 { 69 {
70 // What is done for each object in BSPrim is what we want. 70 // What is done for each object in BSPrim is what we want.
71 return false; 71 return false;
@@ -76,14 +76,14 @@ public sealed class BSLinksetConstraints : BSLinkset
76 // This doesn't normally happen -- OpenSim removes the objects from the physical 76 // This doesn't normally happen -- OpenSim removes the objects from the physical
77 // world if it is a static linkset. 77 // world if it is a static linkset.
78 // Called at taint-time! 78 // Called at taint-time!
79 public override bool MakeStatic(BSPhysObject child) 79 public override bool MakeStatic(BSPrimLinkable child)
80 { 80 {
81 // What is done for each object in BSPrim is what we want. 81 // What is done for each object in BSPrim is what we want.
82 return false; 82 return false;
83 } 83 }
84 84
85 // Called at taint-time!! 85 // Called at taint-time!!
86 public override void UpdateProperties(UpdatedProperties whichUpdated, BSPhysObject pObj) 86 public override void UpdateProperties(UpdatedProperties whichUpdated, BSPrimLinkable pObj)
87 { 87 {
88 // Nothing to do for constraints on property updates 88 // Nothing to do for constraints on property updates
89 } 89 }
@@ -93,7 +93,7 @@ public sealed class BSLinksetConstraints : BSLinkset
93 // up to rebuild the constraints before the next simulation step. 93 // up to rebuild the constraints before the next simulation step.
94 // Returns 'true' of something was actually removed and would need restoring 94 // Returns 'true' of something was actually removed and would need restoring
95 // Called at taint-time!! 95 // Called at taint-time!!
96 public override bool RemoveBodyDependencies(BSPrim child) 96 public override bool RemoveBodyDependencies(BSPrimLinkable child)
97 { 97 {
98 bool ret = false; 98 bool ret = false;
99 99
@@ -114,7 +114,7 @@ public sealed class BSLinksetConstraints : BSLinkset
114 114
115 // Add a new child to the linkset. 115 // Add a new child to the linkset.
116 // Called while LinkActivity is locked. 116 // Called while LinkActivity is locked.
117 protected override void AddChildToLinkset(BSPhysObject child) 117 protected override void AddChildToLinkset(BSPrimLinkable child)
118 { 118 {
119 if (!HasChild(child)) 119 if (!HasChild(child))
120 { 120 {
@@ -130,12 +130,12 @@ public sealed class BSLinksetConstraints : BSLinkset
130 130
131 // Remove the specified child from the linkset. 131 // Remove the specified child from the linkset.
132 // Safe to call even if the child is not really in my linkset. 132 // Safe to call even if the child is not really in my linkset.
133 protected override void RemoveChildFromLinkset(BSPhysObject child) 133 protected override void RemoveChildFromLinkset(BSPrimLinkable child)
134 { 134 {
135 if (m_children.Remove(child)) 135 if (m_children.Remove(child))
136 { 136 {
137 BSPhysObject rootx = LinksetRoot; // capture the root and body as of now 137 BSPrimLinkable rootx = LinksetRoot; // capture the root and body as of now
138 BSPhysObject childx = child; 138 BSPrimLinkable childx = child;
139 139
140 DetailLog("{0},BSLinksetConstraints.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}", 140 DetailLog("{0},BSLinksetConstraints.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}",
141 childx.LocalID, 141 childx.LocalID,
@@ -159,13 +159,13 @@ public sealed class BSLinksetConstraints : BSLinkset
159 159
160 // Create a constraint between me (root of linkset) and the passed prim (the child). 160 // Create a constraint between me (root of linkset) and the passed prim (the child).
161 // Called at taint time! 161 // Called at taint time!
162 private void PhysicallyLinkAChildToRoot(BSPhysObject rootPrim, BSPhysObject childPrim) 162 private void PhysicallyLinkAChildToRoot(BSPrimLinkable rootPrim, BSPrimLinkable childPrim)
163 { 163 {
164 // Don't build the constraint when asked. Put it off until just before the simulation step. 164 // Don't build the constraint when asked. Put it off until just before the simulation step.
165 Refresh(rootPrim); 165 Refresh(rootPrim);
166 } 166 }
167 167
168 private BSConstraint BuildConstraint(BSPhysObject rootPrim, BSPhysObject childPrim) 168 private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSPrimLinkable childPrim)
169 { 169 {
170 // Zero motion for children so they don't interpolate 170 // Zero motion for children so they don't interpolate
171 childPrim.ZeroMotion(true); 171 childPrim.ZeroMotion(true);
@@ -239,7 +239,7 @@ public sealed class BSLinksetConstraints : BSLinkset
239 // The root and child bodies are passed in because we need to remove the constraint between 239 // The root and child bodies are passed in because we need to remove the constraint between
240 // the bodies that were present at unlink time. 240 // the bodies that were present at unlink time.
241 // Called at taint time! 241 // Called at taint time!
242 private bool PhysicallyUnlinkAChildFromRoot(BSPhysObject rootPrim, BSPhysObject childPrim) 242 private bool PhysicallyUnlinkAChildFromRoot(BSPrimLinkable rootPrim, BSPrimLinkable childPrim)
243 { 243 {
244 bool ret = false; 244 bool ret = false;
245 DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}", 245 DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}",
@@ -261,7 +261,7 @@ public sealed class BSLinksetConstraints : BSLinkset
261 // Remove linkage between myself and any possible children I might have. 261 // Remove linkage between myself and any possible children I might have.
262 // Returns 'true' of any constraints were destroyed. 262 // Returns 'true' of any constraints were destroyed.
263 // Called at taint time! 263 // Called at taint time!
264 private bool PhysicallyUnlinkAllChildrenFromRoot(BSPhysObject rootPrim) 264 private bool PhysicallyUnlinkAllChildrenFromRoot(BSPrimLinkable rootPrim)
265 { 265 {
266 DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); 266 DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID);
267 267
@@ -281,7 +281,7 @@ public sealed class BSLinksetConstraints : BSLinkset
281 DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}", 281 DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}",
282 LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString, linksetMass); 282 LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString, linksetMass);
283 283
284 foreach (BSPhysObject child in m_children) 284 foreach (BSPrimLinkable child in m_children)
285 { 285 {
286 // A child in the linkset physically shows the mass of the whole linkset. 286 // A child in the linkset physically shows the mass of the whole linkset.
287 // This allows Bullet to apply enough force on the child to move the whole linkset. 287 // This allows Bullet to apply enough force on the child to move the whole linkset.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
index 601c78c..3e0b4bc 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
@@ -87,6 +87,7 @@ public static class BSParam
87 public static float NumberOfSolverIterations; 87 public static float NumberOfSolverIterations;
88 public static bool UseSingleSidedMeshes { get { return UseSingleSidedMeshesF != ConfigurationParameters.numericFalse; } } 88 public static bool UseSingleSidedMeshes { get { return UseSingleSidedMeshesF != ConfigurationParameters.numericFalse; } }
89 public static float UseSingleSidedMeshesF; 89 public static float UseSingleSidedMeshesF;
90 public static float GlobalContactBreakingThreshold;
90 91
91 // Avatar parameters 92 // Avatar parameters
92 public static float AvatarFriction { get; private set; } 93 public static float AvatarFriction { get; private set; }
@@ -424,7 +425,7 @@ public static class BSParam
424 (s) => { return AvatarFriction; }, 425 (s) => { return AvatarFriction; },
425 (s,p,l,v) => { AvatarFriction = v; } ), 426 (s,p,l,v) => { AvatarFriction = v; } ),
426 new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.", 427 new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.",
427 10.0f, 428 0.95f,
428 (s,cf,p,v) => { AvatarStandingFriction = cf.GetFloat(p, v); }, 429 (s,cf,p,v) => { AvatarStandingFriction = cf.GetFloat(p, v); },
429 (s) => { return AvatarStandingFriction; }, 430 (s) => { return AvatarStandingFriction; },
430 (s,p,l,v) => { AvatarStandingFriction = v; } ), 431 (s,p,l,v) => { AvatarStandingFriction = v; } ),
@@ -570,6 +571,11 @@ public static class BSParam
570 (s,cf,p,v) => { UseSingleSidedMeshesF = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, 571 (s,cf,p,v) => { UseSingleSidedMeshesF = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
571 (s) => { return UseSingleSidedMeshesF; }, 572 (s) => { return UseSingleSidedMeshesF; },
572 (s,p,l,v) => { UseSingleSidedMeshesF = v; s.UnmanagedParams[0].useSingleSidedMeshes = v; } ), 573 (s,p,l,v) => { UseSingleSidedMeshesF = v; s.UnmanagedParams[0].useSingleSidedMeshes = v; } ),
574 new ParameterDefn("GlobalContactBreakingThreshold", "Amount of shape radius before breaking a collision contact (0 says Bullet default (0.2))",
575 0f,
576 (s,cf,p,v) => { GlobalContactBreakingThreshold = cf.GetFloat(p, v); },
577 (s) => { return GlobalContactBreakingThreshold; },
578 (s,p,l,v) => { GlobalContactBreakingThreshold = v; s.UnmanagedParams[0].globalContactBreakingThreshold = v; } ),
573 579
574 new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", 580 new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)",
575 (float)BSLinkset.LinksetImplementation.Compound, 581 (float)BSLinkset.LinksetImplementation.Compound,
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index 0d8bb03..de69fa0 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -86,10 +86,6 @@ public abstract class BSPhysObject : PhysicsActor
86 PhysBody = new BulletBody(localID); 86 PhysBody = new BulletBody(localID);
87 PhysShape = new BulletShape(); 87 PhysShape = new BulletShape();
88 88
89 // A linkset of just me
90 Linkset = BSLinkset.Factory(PhysicsScene, this);
91 PositionDisplacement = OMV.Vector3.Zero;
92
93 LastAssetBuildFailed = false; 89 LastAssetBuildFailed = false;
94 90
95 // Default material type. Also sets Friction, Restitution and Density. 91 // Default material type. Also sets Friction, Restitution and Density.
@@ -117,8 +113,6 @@ public abstract class BSPhysObject : PhysicsActor
117 public string PhysObjectName { get; protected set; } 113 public string PhysObjectName { get; protected set; }
118 public string TypeName { get; protected set; } 114 public string TypeName { get; protected set; }
119 115
120 public BSLinkset Linkset { get; set; }
121 public BSLinksetInfo LinksetInfo { get; set; }
122 116
123 // Return the object mass without calculating it or having side effects 117 // Return the object mass without calculating it or having side effects
124 public abstract float RawMass { get; } 118 public abstract float RawMass { get; }
@@ -188,15 +182,6 @@ public abstract class BSPhysObject : PhysicsActor
188 public abstract OMV.Vector3 RawPosition { get; set; } 182 public abstract OMV.Vector3 RawPosition { get; set; }
189 public abstract OMV.Vector3 ForcePosition { get; set; } 183 public abstract OMV.Vector3 ForcePosition { get; set; }
190 184
191 // 'Position' and 'Orientation' is what the simulator thinks the positions of the prim is.
192 // Because Bullet needs the zero coordinate to be the center of mass of the linkset,
193 // sometimes it is necessary to displace the position the physics engine thinks
194 // the position is. PositionDisplacement must be added and removed from the
195 // position as the simulator position is stored and fetched from the physics
196 // engine. Similar to OrientationDisplacement.
197 public virtual OMV.Vector3 PositionDisplacement { get; set; }
198 public virtual OMV.Quaternion OrientationDisplacement { get; set; }
199
200 public abstract OMV.Quaternion RawOrientation { get; set; } 185 public abstract OMV.Quaternion RawOrientation { get; set; }
201 public abstract OMV.Quaternion ForceOrientation { get; set; } 186 public abstract OMV.Quaternion ForceOrientation { get; set; }
202 187
@@ -302,22 +287,16 @@ public abstract class BSPhysObject : PhysicsActor
302 CollidingObjectStep = PhysicsScene.SimulationStep; 287 CollidingObjectStep = PhysicsScene.SimulationStep;
303 } 288 }
304 289
305 // prims in the same linkset cannot collide with each other
306 if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID))
307 {
308 return ret;
309 }
310
311 CollisionAccumulation++; 290 CollisionAccumulation++;
312 291
313 // For movement tests, remember if we are colliding with an object that is moving. 292 // For movement tests, remember if we are colliding with an object that is moving.
314 ColliderIsMoving = collidee != null ? collidee.RawVelocity != OMV.Vector3.Zero : false; 293 ColliderIsMoving = collidee != null ? (collidee.RawVelocity != OMV.Vector3.Zero) : false;
315 294
316 // If someone has subscribed for collision events log the collision so it will be reported up 295 // If someone has subscribed for collision events log the collision so it will be reported up
317 if (SubscribedEvents()) { 296 if (SubscribedEvents()) {
318 CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); 297 CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
319 DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5}", 298 DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5},colliderMoving={6}",
320 LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth); 299 LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth, ColliderIsMoving);
321 300
322 ret = true; 301 ret = true;
323 } 302 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 85c2627..cf7aa0f 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -39,7 +39,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
39{ 39{
40 40
41 [Serializable] 41 [Serializable]
42public sealed class BSPrim : BSPhysObject 42public class BSPrim : BSPhysObject
43{ 43{
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 private static readonly string LogHeader = "[BULLETS PRIM]"; 45 private static readonly string LogHeader = "[BULLETS PRIM]";
@@ -102,9 +102,6 @@ public sealed class BSPrim : BSPhysObject
102 102
103 _mass = CalculateMass(); 103 _mass = CalculateMass();
104 104
105 // Cause linkset variables to be initialized (like mass)
106 Linkset.Refresh(this);
107
108 DetailLog("{0},BSPrim.constructor,call", LocalID); 105 DetailLog("{0},BSPrim.constructor,call", LocalID);
109 // do the actual object creation at taint time 106 // do the actual object creation at taint time
110 PhysicsScene.TaintedObject("BSPrim.create", delegate() 107 PhysicsScene.TaintedObject("BSPrim.create", delegate()
@@ -121,15 +118,6 @@ public sealed class BSPrim : BSPhysObject
121 // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); 118 // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID);
122 base.Destroy(); 119 base.Destroy();
123 120
124 // Undo any links between me and any other object
125 BSPhysObject parentBefore = Linkset.LinksetRoot; // DEBUG DEBUG
126 int childrenBefore = Linkset.NumberOfChildren; // DEBUG DEBUG
127
128 Linkset = Linkset.RemoveMeFromLinkset(this);
129
130 DetailLog("{0},BSPrim.Destroy,call,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}",
131 LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
132
133 // Undo any vehicle properties 121 // Undo any vehicle properties
134 this.VehicleType = (int)Vehicle.TYPE_NONE; 122 this.VehicleType = (int)Vehicle.TYPE_NONE;
135 123
@@ -166,9 +154,9 @@ public sealed class BSPrim : BSPhysObject
166 ForceBodyShapeRebuild(false); 154 ForceBodyShapeRebuild(false);
167 } 155 }
168 } 156 }
169 // Whatever the linkset wants is what I want. 157 // 'unknown' says to choose the best type
170 public override BSPhysicsShapeType PreferredPhysicalShape 158 public override BSPhysicsShapeType PreferredPhysicalShape
171 { get { return Linkset.PreferredPhysicalShape(this); } } 159 { get { return BSPhysicsShapeType.SHAPE_UNKNOWN; } }
172 160
173 public override bool ForceBodyShapeRebuild(bool inTaintTime) 161 public override bool ForceBodyShapeRebuild(bool inTaintTime)
174 { 162 {
@@ -213,33 +201,10 @@ public sealed class BSPrim : BSPhysObject
213 201
214 // link me to the specified parent 202 // link me to the specified parent
215 public override void link(PhysicsActor obj) { 203 public override void link(PhysicsActor obj) {
216 BSPrim parent = obj as BSPrim;
217 if (parent != null)
218 {
219 BSPhysObject parentBefore = Linkset.LinksetRoot;
220 int childrenBefore = Linkset.NumberOfChildren;
221
222 Linkset = parent.Linkset.AddMeToLinkset(this);
223
224 DetailLog("{0},BSPrim.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}",
225 LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
226 }
227 return;
228 } 204 }
229 205
230 // delink me from my linkset 206 // delink me from my linkset
231 public override void delink() { 207 public override void delink() {
232 // TODO: decide if this parent checking needs to happen at taint time
233 // Race condition here: if link() and delink() in same simulation tick, the delink will not happen
234
235 BSPhysObject parentBefore = Linkset.LinksetRoot;
236 int childrenBefore = Linkset.NumberOfChildren;
237
238 Linkset = Linkset.RemoveMeFromLinkset(this);
239
240 DetailLog("{0},BSPrim.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ",
241 LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
242 return;
243 } 208 }
244 209
245 // Set motion values to zero. 210 // Set motion values to zero.
@@ -287,15 +252,8 @@ public sealed class BSPrim : BSPhysObject
287 } 252 }
288 public override OMV.Vector3 Position { 253 public override OMV.Vector3 Position {
289 get { 254 get {
290 /* NOTE: this refetch is not necessary. The simulator knows about linkset children
291 * and does not fetch this position info for children. Thus this is commented out.
292 // child prims move around based on their parent. Need to get the latest location
293 if (!Linkset.IsRoot(this))
294 _position = Linkset.PositionGet(this);
295 */
296
297 // don't do the GetObjectPosition for root elements because this function is called a zillion times. 255 // don't do the GetObjectPosition for root elements because this function is called a zillion times.
298 // _position = PhysicsScene.PE.GetObjectPosition2(PhysicsScene.World, BSBody) - PositionDisplacement; 256 // _position = ForcePosition;
299 return _position; 257 return _position;
300 } 258 }
301 set { 259 set {
@@ -313,24 +271,20 @@ public sealed class BSPrim : BSPhysObject
313 { 271 {
314 DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); 272 DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
315 ForcePosition = _position; 273 ForcePosition = _position;
316
317 // A linkset might need to know if a component information changed.
318 Linkset.UpdateProperties(UpdatedProperties.Position, this);
319
320 }); 274 });
321 } 275 }
322 } 276 }
323 277
324 public override OMV.Vector3 ForcePosition { 278 public override OMV.Vector3 ForcePosition {
325 get { 279 get {
326 _position = PhysicsScene.PE.GetPosition(PhysBody) - PositionDisplacement; 280 _position = PhysicsScene.PE.GetPosition(PhysBody);
327 return _position; 281 return _position;
328 } 282 }
329 set { 283 set {
330 _position = value; 284 _position = value;
331 if (PhysBody.HasPhysicalBody) 285 if (PhysBody.HasPhysicalBody)
332 { 286 {
333 PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation); 287 PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
334 ActivateIfPhysical(false); 288 ActivateIfPhysical(false);
335 } 289 }
336 } 290 }
@@ -398,12 +352,13 @@ public sealed class BSPrim : BSPhysObject
398 // If the simulator cares about the mass of the linkset, it will sum it itself. 352 // If the simulator cares about the mass of the linkset, it will sum it itself.
399 public override float Mass 353 public override float Mass
400 { 354 {
401 get 355 get { return _mass; }
402 { 356 }
403 return _mass; 357 // TotalMass returns the mass of the large object the prim may be in (overridden by linkset code)
404 } 358 public virtual float TotalMass
359 {
360 get { return _mass; }
405 } 361 }
406
407 // used when we only want this prim's mass and not the linkset thing 362 // used when we only want this prim's mass and not the linkset thing
408 public override float RawMass { 363 public override float RawMass {
409 get { return _mass; } 364 get { return _mass; }
@@ -467,13 +422,13 @@ public sealed class BSPrim : BSPhysObject
467 // Is this used? 422 // Is this used?
468 public override OMV.Vector3 CenterOfMass 423 public override OMV.Vector3 CenterOfMass
469 { 424 {
470 get { return Linkset.CenterOfMass; } 425 get { return RawPosition; }
471 } 426 }
472 427
473 // Is this used? 428 // Is this used?
474 public override OMV.Vector3 GeometricCenter 429 public override OMV.Vector3 GeometricCenter
475 { 430 {
476 get { return Linkset.GeometricCenter; } 431 get { return RawPosition; }
477 } 432 }
478 433
479 public override OMV.Vector3 Force { 434 public override OMV.Vector3 Force {
@@ -721,14 +676,6 @@ public sealed class BSPrim : BSPhysObject
721 } 676 }
722 public override OMV.Quaternion Orientation { 677 public override OMV.Quaternion Orientation {
723 get { 678 get {
724 /* NOTE: this refetch is not necessary. The simulator knows about linkset children
725 * and does not fetch this position info for children. Thus this is commented out.
726 // Children move around because tied to parent. Get a fresh value.
727 if (!Linkset.IsRoot(this))
728 {
729 _orientation = Linkset.OrientationGet(this);
730 }
731 */
732 return _orientation; 679 return _orientation;
733 } 680 }
734 set { 681 set {
@@ -739,10 +686,6 @@ public sealed class BSPrim : BSPhysObject
739 PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate() 686 PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate()
740 { 687 {
741 ForceOrientation = _orientation; 688 ForceOrientation = _orientation;
742
743 // A linkset might need to know if a component information changed.
744 Linkset.UpdateProperties(UpdatedProperties.Orientation, this);
745
746 }); 689 });
747 } 690 }
748 } 691 }
@@ -758,7 +701,7 @@ public sealed class BSPrim : BSPhysObject
758 { 701 {
759 _orientation = value; 702 _orientation = value;
760 if (PhysBody.HasPhysicalBody) 703 if (PhysBody.HasPhysicalBody)
761 PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation); 704 PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
762 } 705 }
763 } 706 }
764 public override int PhysicsActorType { 707 public override int PhysicsActorType {
@@ -814,7 +757,7 @@ public sealed class BSPrim : BSPhysObject
814 // isSolid: other objects bounce off of this object 757 // isSolid: other objects bounce off of this object
815 // isVolumeDetect: other objects pass through but can generate collisions 758 // isVolumeDetect: other objects pass through but can generate collisions
816 // collisionEvents: whether this object returns collision events 759 // collisionEvents: whether this object returns collision events
817 public void UpdatePhysicalParameters() 760 public virtual void UpdatePhysicalParameters()
818 { 761 {
819 if (!PhysBody.HasPhysicalBody) 762 if (!PhysBody.HasPhysicalBody)
820 { 763 {
@@ -844,12 +787,6 @@ public sealed class BSPrim : BSPhysObject
844 // Rebuild its shape 787 // Rebuild its shape
845 PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, PhysBody); 788 PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, PhysBody);
846 789
847 // Recompute any linkset parameters.
848 // When going from non-physical to physical, this re-enables the constraints that
849 // had been automatically disabled when the mass was set to zero.
850 // For compound based linksets, this enables and disables interactions of the children.
851 Linkset.Refresh(this);
852
853 DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},cType={6},body={7},shape={8}", 790 DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},cType={6},body={7},shape={8}",
854 LocalID, IsStatic, IsSolid, Mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody.collisionType, PhysBody, PhysShape); 791 LocalID, IsStatic, IsSolid, Mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody.collisionType, PhysBody, PhysShape);
855 } 792 }
@@ -859,7 +796,7 @@ public sealed class BSPrim : BSPhysObject
859 // When dynamic, the object can fall and be pushed by others. 796 // When dynamic, the object can fall and be pushed by others.
860 // This is independent of its 'solidness' which controls what passes through 797 // This is independent of its 'solidness' which controls what passes through
861 // this object and what interacts with it. 798 // this object and what interacts with it.
862 private void MakeDynamic(bool makeStatic) 799 protected virtual void MakeDynamic(bool makeStatic)
863 { 800 {
864 if (makeStatic) 801 if (makeStatic)
865 { 802 {
@@ -889,9 +826,6 @@ public sealed class BSPrim : BSPhysObject
889 826
890 // This collides like a static object 827 // This collides like a static object
891 PhysBody.collisionType = CollisionType.Static; 828 PhysBody.collisionType = CollisionType.Static;
892
893 // There can be special things needed for implementing linksets
894 Linkset.MakeStatic(this);
895 } 829 }
896 else 830 else
897 { 831 {
@@ -908,10 +842,7 @@ public sealed class BSPrim : BSPhysObject
908 // PhysicsScene.PE.ClearAllForces(BSBody); 842 // PhysicsScene.PE.ClearAllForces(BSBody);
909 843
910 // For good measure, make sure the transform is set through to the motion state 844 // For good measure, make sure the transform is set through to the motion state
911 PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation); 845 ForcePosition = _position;
912
913 // Center of mass is at the center of the object
914 // DEBUG DEBUG PhysicsScene.PE.SetCenterOfMassByPosRot(Linkset.LinksetRoot.PhysBody, _position, _orientation);
915 846
916 // A dynamic object has mass 847 // A dynamic object has mass
917 UpdatePhysicalMassProperties(RawMass, false); 848 UpdatePhysicalMassProperties(RawMass, false);
@@ -935,9 +866,6 @@ public sealed class BSPrim : BSPhysObject
935 // Force activation of the object so Bullet will act on it. 866 // Force activation of the object so Bullet will act on it.
936 // Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects. 867 // Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects.
937 PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.ACTIVE_TAG); 868 PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.ACTIVE_TAG);
938
939 // There might be special things needed for implementing linksets.
940 Linkset.MakeDynamic(this);
941 } 869 }
942 } 870 }
943 871
@@ -1643,16 +1571,6 @@ public sealed class BSPrim : BSPhysObject
1643 1571
1644 returnMass = Density * volume; 1572 returnMass = Density * volume;
1645 1573
1646 /* Comment out code that computes the mass of the linkset. That is done in the Linkset class.
1647 if (IsRootOfLinkset)
1648 {
1649 foreach (BSPrim prim in _childrenPrims)
1650 {
1651 returnMass += prim.CalculateMass();
1652 }
1653 }
1654 */
1655
1656 returnMass = Util.Clamp(returnMass, BSParam.MinimumObjectMass, BSParam.MaximumObjectMass); 1574 returnMass = Util.Clamp(returnMass, BSParam.MinimumObjectMass, BSParam.MaximumObjectMass);
1657 1575
1658 return returnMass; 1576 return returnMass;
@@ -1672,8 +1590,7 @@ public sealed class BSPrim : BSPhysObject
1672 // Called if the current prim body is about to be destroyed. 1590 // Called if the current prim body is about to be destroyed.
1673 // Remove all the physical dependencies on the old body. 1591 // Remove all the physical dependencies on the old body.
1674 // (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...) 1592 // (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...)
1675 Linkset.RemoveBodyDependencies(this); 1593 RemoveBodyDependencies();
1676 VehicleController.RemoveBodyDependencies(this);
1677 }); 1594 });
1678 1595
1679 // Make sure the properties are set on the new object 1596 // Make sure the properties are set on the new object
@@ -1681,57 +1598,50 @@ public sealed class BSPrim : BSPhysObject
1681 return; 1598 return;
1682 } 1599 }
1683 1600
1601 protected virtual void RemoveBodyDependencies()
1602 {
1603 VehicleController.RemoveBodyDependencies(this);
1604 }
1605
1684 // The physics engine says that properties have updated. Update same and inform 1606 // The physics engine says that properties have updated. Update same and inform
1685 // the world that things have changed. 1607 // the world that things have changed.
1686 public override void UpdateProperties(EntityProperties entprop) 1608 public override void UpdateProperties(EntityProperties entprop)
1687 { 1609 {
1688 // Updates only for individual prims and for the root object of a linkset. 1610 // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet
1689 if (Linkset.IsRoot(this)) 1611 // TODO: handle physics introduced by Bullet with computed vehicle physics.
1612 if (VehicleController.IsActive)
1690 { 1613 {
1691 // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet 1614 entprop.RotationalVelocity = OMV.Vector3.Zero;
1692 // TODO: handle physics introduced by Bullet with computed vehicle physics. 1615 }
1693 if (VehicleController.IsActive)
1694 {
1695 entprop.RotationalVelocity = OMV.Vector3.Zero;
1696 }
1697
1698 // DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG
1699 1616
1700 // Undo any center-of-mass displacement that might have been done. 1617 // DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG
1701 if (PositionDisplacement != OMV.Vector3.Zero)
1702 {
1703 // Correct for any rotation around the center-of-mass
1704 // TODO!!!
1705 entprop.Position -= PositionDisplacement;
1706 }
1707 1618
1708 // Assign directly to the local variables so the normal set actions do not happen 1619 // Assign directly to the local variables so the normal set actions do not happen
1709 _position = entprop.Position; 1620 _position = entprop.Position;
1710 _orientation = entprop.Rotation; 1621 _orientation = entprop.Rotation;
1711 _velocity = entprop.Velocity; 1622 _velocity = entprop.Velocity;
1712 _acceleration = entprop.Acceleration; 1623 _acceleration = entprop.Acceleration;
1713 _rotationalVelocity = entprop.RotationalVelocity; 1624 _rotationalVelocity = entprop.RotationalVelocity;
1714 1625
1715 // DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG 1626 // DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG
1716 1627
1717 // The sanity check can change the velocity and/or position. 1628 // The sanity check can change the velocity and/or position.
1718 if (PositionSanityCheck(true /* inTaintTime */ )) 1629 if (PositionSanityCheck(true /* inTaintTime */ ))
1719 { 1630 {
1720 entprop.Position = _position; 1631 entprop.Position = _position;
1721 entprop.Velocity = _velocity; 1632 entprop.Velocity = _velocity;
1722 entprop.RotationalVelocity = _rotationalVelocity; 1633 entprop.RotationalVelocity = _rotationalVelocity;
1723 entprop.Acceleration = _acceleration; 1634 entprop.Acceleration = _acceleration;
1724 } 1635 }
1725 1636
1726 OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG 1637 OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG
1727 DetailLog("{0},BSPrim.UpdateProperties,call,entProp={1},dir={2}", LocalID, entprop, direction); 1638 DetailLog("{0},BSPrim.UpdateProperties,call,entProp={1},dir={2}", LocalID, entprop, direction);
1728 1639
1729 // remember the current and last set values 1640 // remember the current and last set values
1730 LastEntityProperties = CurrentEntityProperties; 1641 LastEntityProperties = CurrentEntityProperties;
1731 CurrentEntityProperties = entprop; 1642 CurrentEntityProperties = entprop;
1732 1643
1733 base.RequestPhysicsterseUpdate(); 1644 base.RequestPhysicsterseUpdate();
1734 }
1735 /* 1645 /*
1736 else 1646 else
1737 { 1647 {
@@ -1741,9 +1651,6 @@ public sealed class BSPrim : BSPhysObject
1741 entprop.Acceleration, entprop.RotationalVelocity); 1651 entprop.Acceleration, entprop.RotationalVelocity);
1742 } 1652 }
1743 */ 1653 */
1744
1745 // The linkset implimentation might want to know about this.
1746 Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);
1747 } 1654 }
1748} 1655}
1749} 1656}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs
new file mode 100755
index 0000000..6401308
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs
@@ -0,0 +1,118 @@
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 * The quotations from http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial
28 * are Copyright (c) 2009 Linden Research, Inc and are used under their license
29 * of Creative Commons Attribution-Share Alike 3.0
30 * (http://creativecommons.org/licenses/by-sa/3.0/).
31 */
32
33using System;
34using System.Collections.Generic;
35using System.Reflection;
36using System.Runtime.InteropServices;
37using OpenMetaverse;
38using OpenSim.Framework;
39using OpenSim.Region.Physics.Manager;
40
41using OMV = OpenMetaverse;
42
43namespace OpenSim.Region.Physics.BulletSPlugin
44{
45public class BSPrimDisplaced : BSPrim
46{
47 // 'Position' and 'Orientation' is what the simulator thinks the positions of the prim is.
48 // Because Bullet needs the zero coordinate to be the center of mass of the linkset,
49 // sometimes it is necessary to displace the position the physics engine thinks
50 // the position is. PositionDisplacement must be added and removed from the
51 // position as the simulator position is stored and fetched from the physics
52 // engine. Similar to OrientationDisplacement.
53 public virtual OMV.Vector3 PositionDisplacement { get; set; }
54 public virtual OMV.Quaternion OrientationDisplacement { get; set; }
55 public virtual OMV.Vector3 CenterOfMassLocation { get; set; }
56 public virtual OMV.Vector3 GeometricCenterLocation { get; set; }
57
58 public BSPrimDisplaced(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
59 OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
60 : base(localID, primName, parent_scene, pos, size, rotation, pbs, pisPhysical)
61 {
62 CenterOfMassLocation = RawPosition;
63 GeometricCenterLocation = RawPosition;
64 }
65
66 public override Vector3 ForcePosition
67 {
68 get
69 {
70 return base.ForcePosition;
71 }
72 set
73 {
74 base.ForcePosition = value;
75 CenterOfMassLocation = RawPosition;
76 GeometricCenterLocation = RawPosition;
77 }
78 }
79
80 public override Quaternion ForceOrientation
81 {
82 get
83 {
84 return base.ForceOrientation;
85 }
86 set
87 {
88 base.ForceOrientation = value;
89 }
90 }
91
92 // Is this used?
93 public override OMV.Vector3 CenterOfMass
94 {
95 get { return CenterOfMassLocation; }
96 }
97
98 // Is this used?
99 public override OMV.Vector3 GeometricCenter
100 {
101 get { return GeometricCenterLocation; }
102 }
103
104
105 public override void UpdateProperties(EntityProperties entprop)
106 {
107 // Undo any center-of-mass displacement that might have been done.
108 if (PositionDisplacement != OMV.Vector3.Zero)
109 {
110 // Correct for any rotation around the center-of-mass
111 // TODO!!!
112 entprop.Position -= PositionDisplacement;
113 }
114
115 base.UpdateProperties(entprop);
116 }
117}
118}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs
new file mode 100755
index 0000000..9898562
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs
@@ -0,0 +1,179 @@
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 copyrightD
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 */
27using System;
28using System.Collections.Generic;
29using System.Linq;
30using System.Text;
31
32using OpenSim.Framework;
33
34using OMV = OpenMetaverse;
35
36namespace OpenSim.Region.Physics.BulletSPlugin
37{
38public class BSPrimLinkable : BSPrimDisplaced
39{
40 public BSLinkset Linkset { get; set; }
41 public BSLinksetInfo LinksetInfo { get; set; }
42
43 public BSPrimLinkable(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
44 OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
45 : base(localID, primName, parent_scene, pos, size, rotation, pbs, pisPhysical)
46 {
47 Linkset = BSLinkset.Factory(PhysicsScene, this);
48
49 PhysicsScene.TaintedObject("BSPrimLinksetCompound.Refresh", delegate()
50 {
51 Linkset.Refresh(this);
52 });
53 }
54
55 public override void Destroy()
56 {
57 Linkset = Linkset.RemoveMeFromLinkset(this);
58 base.Destroy();
59 }
60
61 public override BSPhysicsShapeType PreferredPhysicalShape
62 { get { return Linkset.PreferredPhysicalShape(this); } }
63
64 public override void link(Manager.PhysicsActor obj)
65 {
66 BSPrimLinkable parent = obj as BSPrimLinkable;
67 if (parent != null)
68 {
69 BSPhysObject parentBefore = Linkset.LinksetRoot;
70 int childrenBefore = Linkset.NumberOfChildren;
71
72 Linkset = parent.Linkset.AddMeToLinkset(this);
73
74 DetailLog("{0},BSPrimLinkset.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}",
75 LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
76 }
77 return;
78 }
79
80 public override void delink()
81 {
82 // TODO: decide if this parent checking needs to happen at taint time
83 // Race condition here: if link() and delink() in same simulation tick, the delink will not happen
84
85 BSPhysObject parentBefore = Linkset.LinksetRoot;
86 int childrenBefore = Linkset.NumberOfChildren;
87
88 Linkset = Linkset.RemoveMeFromLinkset(this);
89
90 DetailLog("{0},BSPrimLinkset.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ",
91 LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
92 return;
93 base.delink();
94 }
95
96 // When simulator changes position, this might be moving a child of the linkset.
97 public override OMV.Vector3 Position
98 {
99 get { return base.Position; }
100 set
101 {
102 base.Position = value;
103 PhysicsScene.TaintedObject("BSPrimLinkset.setPosition", delegate()
104 {
105 Linkset.UpdateProperties(UpdatedProperties.Position, this);
106 });
107 }
108 }
109
110 // When simulator changes orientation, this might be moving a child of the linkset.
111 public override OMV.Quaternion Orientation
112 {
113 get { return base.Orientation; }
114 set
115 {
116 base.Orientation = value;
117 PhysicsScene.TaintedObject("BSPrimLinkset.setOrientation", delegate()
118 {
119 Linkset.UpdateProperties(UpdatedProperties.Orientation, this);
120 });
121 }
122 }
123
124 public override float TotalMass
125 {
126 get { return Linkset.LinksetMass; }
127 }
128
129 public override void UpdatePhysicalParameters()
130 {
131 base.UpdatePhysicalParameters();
132 // Recompute any linkset parameters.
133 // When going from non-physical to physical, this re-enables the constraints that
134 // had been automatically disabled when the mass was set to zero.
135 // For compound based linksets, this enables and disables interactions of the children.
136 Linkset.Refresh(this);
137 }
138
139 protected override void MakeDynamic(bool makeStatic)
140 {
141 base.MakeDynamic(makeStatic);
142 if (makeStatic)
143 Linkset.MakeStatic(this);
144 else
145 Linkset.MakeDynamic(this);
146 }
147
148 // Body is being taken apart. Remove physical dependencies and schedule a rebuild.
149 protected override void RemoveBodyDependencies()
150 {
151 Linkset.RemoveBodyDependencies(this);
152 base.RemoveBodyDependencies();
153 }
154
155 public override void UpdateProperties(EntityProperties entprop)
156 {
157 if (Linkset.IsRoot(this))
158 {
159 // Properties are only updated for the roots of a linkset.
160 // TODO: this will have to change when linksets are articulated.
161 base.UpdateProperties(entprop);
162 }
163 // The linkset might like to know about changing locations
164 Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);
165 }
166
167 public override bool Collide(uint collidingWith, BSPhysObject collidee,
168 OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
169 {
170 // prims in the same linkset cannot collide with each other
171 BSPrimLinkable convCollidee = collidee as BSPrimLinkable;
172 if (convCollidee != null && (this.Linkset.LinksetID == convCollidee.Linkset.LinksetID))
173 {
174 return false;
175 }
176 return base.Collide(collidingWith, collidee, contactPoint, contactNormal, pentrationDepth);
177 }
178}
179}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index f8a0c1e..05722b8 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -434,7 +434,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
434 { 434 {
435 if (!m_initialized) return; 435 if (!m_initialized) return;
436 436
437 BSPrim bsprim = prim as BSPrim; 437 BSPhysObject bsprim = prim as BSPhysObject;
438 if (bsprim != null) 438 if (bsprim != null)
439 { 439 {
440 DetailLog("{0},RemovePrim,call", bsprim.LocalID); 440 DetailLog("{0},RemovePrim,call", bsprim.LocalID);
@@ -463,9 +463,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
463 463
464 if (!m_initialized) return null; 464 if (!m_initialized) return null;
465 465
466 DetailLog("{0},AddPrimShape,call", localID); 466 DetailLog("{0},BSScene.AddPrimShape,call", localID);
467 467
468 BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical); 468 BSPhysObject prim = new BSPrimLinkable(localID, primName, this, position, size, rotation, pbs, isPhysical);
469 lock (PhysObjects) PhysObjects.Add(localID, prim); 469 lock (PhysObjects) PhysObjects.Add(localID, prim);
470 return prim; 470 return prim;
471 } 471 }