aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs57
1 files changed, 27 insertions, 30 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index bf262c5..f68e06e 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -40,9 +40,12 @@ public class BSLinkset
40 public BSPrim Root { get { return m_linksetRoot; } } 40 public BSPrim Root { get { return m_linksetRoot; } }
41 41
42 private BSScene m_scene; 42 private BSScene m_scene;
43 public BSScene Scene { get { return m_scene; } }
43 44
44 private List<BSPrim> m_children; 45 private List<BSPrim> m_children;
45 46
47 public int NumberOfChildren { get { return m_children.Count; } }
48
46 // We lock the diddling of linkset classes to prevent any badness. 49 // We lock the diddling of linkset classes to prevent any badness.
47 // This locks the modification of the instances of this class. Changes 50 // This locks the modification of the instances of this class. Changes
48 // to the physical representation is done via the tainting mechenism. 51 // to the physical representation is done via the tainting mechenism.
@@ -113,9 +116,10 @@ public class BSLinkset
113 } 116 }
114 117
115 // The child is down to a linkset of just itself 118 // The child is down to a linkset of just itself
116 return new BSLinkset(m_scene, child); 119 return new BSLinkset(Scene, child);
117 } 120 }
118 121
122 /* DEPRECATED: this is really bad in that it trys to unlink other prims.
119 // An existing linkset had one of its members rebuilt or something. 123 // An existing linkset had one of its members rebuilt or something.
120 // Go through the linkset and rebuild the pointers to the bodies of the linkset members. 124 // Go through the linkset and rebuild the pointers to the bodies of the linkset members.
121 public BSLinkset RefreshLinkset(BSPrim requestor) 125 public BSLinkset RefreshLinkset(BSPrim requestor)
@@ -163,6 +167,7 @@ public class BSLinkset
163 167
164 return ret; 168 return ret;
165 } 169 }
170 */
166 171
167 172
168 // Return 'true' if the passed object is the root object of this linkset 173 // Return 'true' if the passed object is the root object of this linkset
@@ -229,18 +234,19 @@ public class BSLinkset
229 } 234 }
230 235
231 // I am the root of a linkset and a new child is being added 236 // I am the root of a linkset and a new child is being added
232 public void AddChildToLinkset(BSPrim pchild) 237 // Called while LinkActivity is locked.
238 public void AddChildToLinkset(BSPrim child)
233 { 239 {
234 BSPrim child = pchild;
235 if (!HasChild(child)) 240 if (!HasChild(child))
236 { 241 {
237 m_children.Add(child); 242 m_children.Add(child);
238 243
244 BSPrim root = Root; // capture the root as of now
239 m_scene.TaintedObject("AddChildToLinkset", delegate() 245 m_scene.TaintedObject("AddChildToLinkset", delegate()
240 { 246 {
241 DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, m_linksetRoot.LocalID); 247 DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, m_linksetRoot.LocalID);
242 DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, pchild.LocalID); 248 DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
243 PhysicallyLinkAChildToRoot(pchild); // build the physical binding between me and the child 249 PhysicallyLinkAChildToRoot(root, child); // build the physical binding between me and the child
244 }); 250 });
245 } 251 }
246 return; 252 return;
@@ -259,26 +265,17 @@ public class BSLinkset
259 265
260 // I am the root of a linkset and one of my children is being removed. 266 // I am the root of a linkset and one of my children is being removed.
261 // Safe to call even if the child is not really in my linkset. 267 // Safe to call even if the child is not really in my linkset.
262 public void RemoveChildFromLinkset(BSPrim pchild) 268 public void RemoveChildFromLinkset(BSPrim child)
263 { 269 {
264 BSPrim child = pchild;
265
266 if (m_children.Remove(child)) 270 if (m_children.Remove(child))
267 { 271 {
272 BSPrim root = Root; // capture the root as of now
268 m_scene.TaintedObject("RemoveChildFromLinkset", delegate() 273 m_scene.TaintedObject("RemoveChildFromLinkset", delegate()
269 { 274 {
270 DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID); 275 DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID);
271 DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, pchild.LocalID); 276 DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
272 277
273 if (m_children.Count == 0) 278 PhysicallyUnlinkAChildFromRoot(root, child);
274 {
275 // if the linkset is empty, make sure all linkages have been removed
276 PhysicallyUnlinkAllChildrenFromRoot();
277 }
278 else
279 {
280 PhysicallyUnlinkAChildFromRoot(pchild);
281 }
282 }); 279 });
283 } 280 }
284 else 281 else
@@ -291,14 +288,14 @@ public class BSLinkset
291 288
292 // Create a constraint between me (root of linkset) and the passed prim (the child). 289 // Create a constraint between me (root of linkset) and the passed prim (the child).
293 // Called at taint time! 290 // Called at taint time!
294 private void PhysicallyLinkAChildToRoot(BSPrim childPrim) 291 private void PhysicallyLinkAChildToRoot(BSPrim rootPrim, BSPrim childPrim)
295 { 292 {
296 // Zero motion for children so they don't interpolate 293 // Zero motion for children so they don't interpolate
297 childPrim.ZeroMotion(); 294 childPrim.ZeroMotion();
298 295
299 // relative position normalized to the root prim 296 // relative position normalized to the root prim
300 OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(m_linksetRoot.Orientation); 297 OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation);
301 OMV.Vector3 childRelativePosition = (childPrim.Position - m_linksetRoot.Position) * invThisOrientation; 298 OMV.Vector3 childRelativePosition = (childPrim.Position - rootPrim.Position) * invThisOrientation;
302 299
303 // relative rotation of the child to the parent 300 // relative rotation of the child to the parent
304 OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation; 301 OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation;
@@ -306,9 +303,9 @@ public class BSLinkset
306 // create a constraint that allows no freedom of movement between the two objects 303 // create a constraint that allows no freedom of movement between the two objects
307 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 304 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
308 // DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID); 305 // DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID);
309 DetailLog("{0},LinkAChildToMe,taint,root={1},child={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, childPrim.LocalID); 306 DetailLog("{0},LinkAChildToMe,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
310 BS6DofConstraint constrain = new BS6DofConstraint( 307 BS6DofConstraint constrain = new BS6DofConstraint(
311 m_scene.World, m_linksetRoot.Body, childPrim.Body, 308 m_scene.World, rootPrim.Body, childPrim.Body,
312 childRelativePosition, 309 childRelativePosition,
313 childRelativeRotation, 310 childRelativeRotation,
314 OMV.Vector3.Zero, 311 OMV.Vector3.Zero,
@@ -331,25 +328,25 @@ public class BSLinkset
331 328
332 // Remove linkage between myself and a particular child 329 // Remove linkage between myself and a particular child
333 // Called at taint time! 330 // Called at taint time!
334 private void PhysicallyUnlinkAChildFromRoot(BSPrim childPrim) 331 private void PhysicallyUnlinkAChildFromRoot(BSPrim rootPrim, BSPrim childPrim)
335 { 332 {
336 // DebugLog("{0}: PhysicallyUnlinkAChildFromRoot: RemoveConstraint between root prim {1} and child prim {2}", 333 // DebugLog("{0}: PhysicallyUnlinkAChildFromRoot: RemoveConstraint between root prim {1} and child prim {2}",
337 // LogHeader, m_linksetRoot.LocalID, childPrim.LocalID); 334 // LogHeader, rootPrim.LocalID, childPrim.LocalID);
338 DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, childPrim.LocalID); 335 DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
339 336
340 m_scene.Constraints.RemoveAndDestroyConstraint(m_linksetRoot.Body, childPrim.Body); 337 m_scene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body, childPrim.Body);
341 // Make the child refresh its location 338 // Make the child refresh its location
342 BulletSimAPI.PushUpdate2(childPrim.Body.Ptr); 339 BulletSimAPI.PushUpdate2(childPrim.Body.Ptr);
343 } 340 }
344 341
345 // Remove linkage between myself and any possible children I might have 342 // Remove linkage between myself and any possible children I might have
346 // Called at taint time! 343 // Called at taint time!
347 private void PhysicallyUnlinkAllChildrenFromRoot() 344 private void PhysicallyUnlinkAllChildrenFromRoot(BSPrim rootPrim)
348 { 345 {
349 // DebugLog("{0}: PhysicallyUnlinkAllChildren:", LogHeader); 346 // DebugLog("{0}: PhysicallyUnlinkAllChildren:", LogHeader);
350 DetailLog("{0},PhysicallyUnlinkAllChildren,taint", m_linksetRoot.LocalID); 347 DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID);
351 348
352 m_scene.Constraints.RemoveAndDestroyConstraint(m_linksetRoot.Body); 349 m_scene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body);
353 } 350 }
354 351
355 // Invoke the detailed logger and output something if it's enabled. 352 // Invoke the detailed logger and output something if it's enabled.