aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorRobert Adams2013-02-07 21:57:31 -0800
committerRobert Adams2013-02-08 16:29:29 -0800
commit1b203601f43662541526369f540dd04f5b485be6 (patch)
tree418bae04970c59ed4ab7653686843bc2e916b730
parentBulletSim: reclass BSPrim into layers so linkset and physical world displacem... (diff)
downloadopensim-SC-1b203601f43662541526369f540dd04f5b485be6.zip
opensim-SC-1b203601f43662541526369f540dd04f5b485be6.tar.gz
opensim-SC-1b203601f43662541526369f540dd04f5b485be6.tar.bz2
opensim-SC-1b203601f43662541526369f540dd04f5b485be6.tar.xz
BulletSim: include the linkage to the layered prim implementation. Separate layers for physical (vs simulator) location displacement and linksets.
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs2
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs2
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs48
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs32
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs30
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs21
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs195
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs4
8 files changed, 109 insertions, 225 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index d694a6a..0afc437 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -901,7 +901,7 @@ public sealed class BSCharacter : BSPhysObject
901 CurrentEntityProperties = entprop; 901 CurrentEntityProperties = entprop;
902 902
903 // Tell the linkset about value changes 903 // Tell the linkset about value changes
904 Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this); 904 // Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);
905 905
906 // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. 906 // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
907 // base.RequestPhysicsterseUpdate(); 907 // 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..8e69db3 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
@@ -74,7 +74,7 @@ public abstract class BSLinkset
74 return ret; 74 return ret;
75 } 75 }
76 76
77 public BSPhysObject LinksetRoot { get; protected set; } 77 public BSPrimLinkable LinksetRoot { get; protected set; }
78 78
79 public BSScene PhysicsScene { get; private set; } 79 public BSScene PhysicsScene { get; private set; }
80 80
@@ -82,7 +82,7 @@ public abstract class BSLinkset
82 public int LinksetID { get; private set; } 82 public int LinksetID { get; private set; }
83 83
84 // The children under the root in this linkset. 84 // The children under the root in this linkset.
85 protected HashSet<BSPhysObject> m_children; 85 protected HashSet<BSPrimLinkable> m_children;
86 86
87 // We lock the diddling of linkset classes to prevent any badness. 87 // We lock the diddling of linkset classes to prevent any badness.
88 // This locks the modification of the instances of this class. Changes 88 // This locks the modification of the instances of this class. Changes
@@ -91,7 +91,7 @@ public abstract class BSLinkset
91 91
92 // Some linksets have a preferred physical shape. 92 // Some linksets have a preferred physical shape.
93 // Returns SHAPE_UNKNOWN if there is no preference. Causes the correct shape to be selected. 93 // Returns SHAPE_UNKNOWN if there is no preference. Causes the correct shape to be selected.
94 public virtual BSPhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor) 94 public virtual BSPhysicsShapeType PreferredPhysicalShape(BSPrimLinkable requestor)
95 { 95 {
96 return BSPhysicsShapeType.SHAPE_UNKNOWN; 96 return BSPhysicsShapeType.SHAPE_UNKNOWN;
97 } 97 }
@@ -111,7 +111,7 @@ public abstract class BSLinkset
111 get { return ComputeLinksetGeometricCenter(); } 111 get { return ComputeLinksetGeometricCenter(); }
112 } 112 }
113 113
114 protected BSLinkset(BSScene scene, BSPhysObject parent) 114 protected BSLinkset(BSScene scene, BSPrimLinkable parent)
115 { 115 {
116 // A simple linkset of one (no children) 116 // A simple linkset of one (no children)
117 LinksetID = m_nextLinksetID++; 117 LinksetID = m_nextLinksetID++;
@@ -120,7 +120,7 @@ public abstract class BSLinkset
120 m_nextLinksetID = 1; 120 m_nextLinksetID = 1;
121 PhysicsScene = scene; 121 PhysicsScene = scene;
122 LinksetRoot = parent; 122 LinksetRoot = parent;
123 m_children = new HashSet<BSPhysObject>(); 123 m_children = new HashSet<BSPrimLinkable>();
124 LinksetMass = parent.RawMass; 124 LinksetMass = parent.RawMass;
125 Rebuilding = false; 125 Rebuilding = false;
126 } 126 }
@@ -129,7 +129,7 @@ public abstract class BSLinkset
129 // Parent changing should not happen so do some sanity checking. 129 // Parent changing should not happen so do some sanity checking.
130 // We return the parent's linkset so the child can track its membership. 130 // We return the parent's linkset so the child can track its membership.
131 // Called at runtime. 131 // Called at runtime.
132 public BSLinkset AddMeToLinkset(BSPhysObject child) 132 public BSLinkset AddMeToLinkset(BSPrimLinkable child)
133 { 133 {
134 lock (m_linksetActivityLock) 134 lock (m_linksetActivityLock)
135 { 135 {
@@ -145,14 +145,13 @@ public abstract class BSLinkset
145 // Returns a new linkset for the child which is a linkset of one (just the 145 // Returns a new linkset for the child which is a linkset of one (just the
146 // orphened child). 146 // orphened child).
147 // Called at runtime. 147 // Called at runtime.
148 public BSLinkset RemoveMeFromLinkset(BSPhysObject child) 148 public BSLinkset RemoveMeFromLinkset(BSPrimLinkable child)
149 { 149 {
150 lock (m_linksetActivityLock) 150 lock (m_linksetActivityLock)
151 { 151 {
152 if (IsRoot(child)) 152 if (IsRoot(child))
153 { 153 {
154 // Cannot remove the root from a linkset. 154 // Cannot remove the root from a linkset.
155 child.PositionDisplacement = OMV.Vector3.Zero;
156 return this; 155 return this;
157 } 156 }
158 RemoveChildFromLinkset(child); 157 RemoveChildFromLinkset(child);
@@ -160,12 +159,11 @@ public abstract class BSLinkset
160 } 159 }
161 160
162 // The child is down to a linkset of just itself 161 // The child is down to a linkset of just itself
163 child.PositionDisplacement = OMV.Vector3.Zero;
164 return BSLinkset.Factory(PhysicsScene, child); 162 return BSLinkset.Factory(PhysicsScene, child);
165 } 163 }
166 164
167 // Return 'true' if the passed object is the root object of this linkset 165 // Return 'true' if the passed object is the root object of this linkset
168 public bool IsRoot(BSPhysObject requestor) 166 public bool IsRoot(BSPrimLinkable requestor)
169 { 167 {
170 return (requestor.LocalID == LinksetRoot.LocalID); 168 return (requestor.LocalID == LinksetRoot.LocalID);
171 } 169 }
@@ -176,14 +174,14 @@ public abstract class BSLinkset
176 public bool HasAnyChildren { get { return (m_children.Count > 0); } } 174 public bool HasAnyChildren { get { return (m_children.Count > 0); } }
177 175
178 // Return 'true' if this child is in this linkset 176 // Return 'true' if this child is in this linkset
179 public bool HasChild(BSPhysObject child) 177 public bool HasChild(BSPrimLinkable child)
180 { 178 {
181 bool ret = false; 179 bool ret = false;
182 lock (m_linksetActivityLock) 180 lock (m_linksetActivityLock)
183 { 181 {
184 ret = m_children.Contains(child); 182 ret = m_children.Contains(child);
185 /* Safer version but the above should work 183 /* Safer version but the above should work
186 foreach (BSPhysObject bp in m_children) 184 foreach (BSPrimLinkable bp in m_children)
187 { 185 {
188 if (child.LocalID == bp.LocalID) 186 if (child.LocalID == bp.LocalID)
189 { 187 {
@@ -198,14 +196,14 @@ public abstract class BSLinkset
198 196
199 // Perform an action on each member of the linkset including root prim. 197 // 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. 198 // Depends on the action on whether this should be done at taint time.
201 public delegate bool ForEachMemberAction(BSPhysObject obj); 199 public delegate bool ForEachMemberAction(BSPrimLinkable obj);
202 public virtual bool ForEachMember(ForEachMemberAction action) 200 public virtual bool ForEachMember(ForEachMemberAction action)
203 { 201 {
204 bool ret = false; 202 bool ret = false;
205 lock (m_linksetActivityLock) 203 lock (m_linksetActivityLock)
206 { 204 {
207 action(LinksetRoot); 205 action(LinksetRoot);
208 foreach (BSPhysObject po in m_children) 206 foreach (BSPrimLinkable po in m_children)
209 { 207 {
210 if (action(po)) 208 if (action(po))
211 break; 209 break;
@@ -216,16 +214,16 @@ public abstract class BSLinkset
216 214
217 // I am the root of a linkset and a new child is being added 215 // I am the root of a linkset and a new child is being added
218 // Called while LinkActivity is locked. 216 // Called while LinkActivity is locked.
219 protected abstract void AddChildToLinkset(BSPhysObject child); 217 protected abstract void AddChildToLinkset(BSPrimLinkable child);
220 218
221 // I am the root of a linkset and one of my children is being removed. 219 // 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. 220 // Safe to call even if the child is not really in my linkset.
223 protected abstract void RemoveChildFromLinkset(BSPhysObject child); 221 protected abstract void RemoveChildFromLinkset(BSPrimLinkable child);
224 222
225 // When physical properties are changed the linkset needs to recalculate 223 // When physical properties are changed the linkset needs to recalculate
226 // its internal properties. 224 // its internal properties.
227 // May be called at runtime or taint-time. 225 // May be called at runtime or taint-time.
228 public virtual void Refresh(BSPhysObject requestor) 226 public virtual void Refresh(BSPrimLinkable requestor)
229 { 227 {
230 LinksetMass = ComputeLinksetMass(); 228 LinksetMass = ComputeLinksetMass();
231 } 229 }
@@ -240,26 +238,26 @@ public abstract class BSLinkset
240 // has not yet been fully constructed. 238 // has not yet been fully constructed.
241 // Return 'true' if any properties updated on the passed object. 239 // Return 'true' if any properties updated on the passed object.
242 // Called at taint-time! 240 // Called at taint-time!
243 public abstract bool MakeDynamic(BSPhysObject child); 241 public abstract bool MakeDynamic(BSPrimLinkable child);
244 242
245 // The object is going static (non-physical). Do any setup necessary 243 // The object is going static (non-physical). Do any setup necessary
246 // for a static linkset. 244 // for a static linkset.
247 // Return 'true' if any properties updated on the passed object. 245 // Return 'true' if any properties updated on the passed object.
248 // Called at taint-time! 246 // Called at taint-time!
249 public abstract bool MakeStatic(BSPhysObject child); 247 public abstract bool MakeStatic(BSPrimLinkable child);
250 248
251 // Called when a parameter update comes from the physics engine for any object 249 // Called when a parameter update comes from the physics engine for any object
252 // of the linkset is received. 250 // of the linkset is received.
253 // Passed flag is update came from physics engine (true) or the user (false). 251 // Passed flag is update came from physics engine (true) or the user (false).
254 // Called at taint-time!! 252 // Called at taint-time!!
255 public abstract void UpdateProperties(UpdatedProperties whichUpdated, BSPhysObject physObject); 253 public abstract void UpdateProperties(UpdatedProperties whichUpdated, BSPrimLinkable physObject);
256 254
257 // Routine used when rebuilding the body of the root of the linkset 255 // Routine used when rebuilding the body of the root of the linkset
258 // Destroy all the constraints have have been made to root. 256 // Destroy all the constraints have have been made to root.
259 // This is called when the root body is changing. 257 // This is called when the root body is changing.
260 // Returns 'true' of something was actually removed and would need restoring 258 // Returns 'true' of something was actually removed and would need restoring
261 // Called at taint-time!! 259 // Called at taint-time!!
262 public abstract bool RemoveBodyDependencies(BSPrim child); 260 public abstract bool RemoveBodyDependencies(BSPrimLinkable child);
263 261
264 // ================================================================ 262 // ================================================================
265 protected virtual float ComputeLinksetMass() 263 protected virtual float ComputeLinksetMass()
@@ -269,7 +267,7 @@ public abstract class BSLinkset
269 { 267 {
270 lock (m_linksetActivityLock) 268 lock (m_linksetActivityLock)
271 { 269 {
272 foreach (BSPhysObject bp in m_children) 270 foreach (BSPrimLinkable bp in m_children)
273 { 271 {
274 mass += bp.RawMass; 272 mass += bp.RawMass;
275 } 273 }
@@ -286,7 +284,7 @@ public abstract class BSLinkset
286 com = LinksetRoot.Position * LinksetRoot.RawMass; 284 com = LinksetRoot.Position * LinksetRoot.RawMass;
287 float totalMass = LinksetRoot.RawMass; 285 float totalMass = LinksetRoot.RawMass;
288 286
289 foreach (BSPhysObject bp in m_children) 287 foreach (BSPrimLinkable bp in m_children)
290 { 288 {
291 com += bp.Position * bp.RawMass; 289 com += bp.Position * bp.RawMass;
292 totalMass += bp.RawMass; 290 totalMass += bp.RawMass;
@@ -305,7 +303,7 @@ public abstract class BSLinkset
305 { 303 {
306 com = LinksetRoot.Position; 304 com = LinksetRoot.Position;
307 305
308 foreach (BSPhysObject bp in m_children) 306 foreach (BSPrimLinkable bp in m_children)
309 { 307 {
310 com += bp.Position; 308 com += bp.Position;
311 } 309 }
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/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index 0d8bb03..e1d269a 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,12 +287,6 @@ 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.
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/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index f8a0c1e..e506d22 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);
@@ -465,7 +465,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
465 465
466 DetailLog("{0},AddPrimShape,call", localID); 466 DetailLog("{0},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 }