aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs75
1 files changed, 60 insertions, 15 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index 84a7fac..6967108 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -92,7 +92,9 @@ public class BSLinkset
92 { 92 {
93 lock (m_linksetActivityLock) 93 lock (m_linksetActivityLock)
94 { 94 {
95 AddChildToLinkset(child); 95 // Don't add the root to its own linkset
96 if (!IsRoot(child))
97 AddChildToLinkset(child);
96 } 98 }
97 return this; 99 return this;
98 } 100 }
@@ -106,6 +108,17 @@ public class BSLinkset
106 { 108 {
107 if (IsRoot(child)) 109 if (IsRoot(child))
108 { 110 {
111 // Cannot remove the root from a linkset.
112 return this;
113 }
114
115 RemoveChildFromLinkset(child);
116
117 /* Alternate implementation that destroys the linkset of the root is removed.
118 * This fails because items are added and removed from linksets to build shapes.
119 * Code left for reference.
120 if (IsRoot(child))
121 {
109 // if root of linkset, take the linkset apart 122 // if root of linkset, take the linkset apart
110 while (m_children.Count > 0) 123 while (m_children.Count > 0)
111 { 124 {
@@ -120,6 +133,7 @@ public class BSLinkset
120 // Just removing a child from an existing linkset 133 // Just removing a child from an existing linkset
121 RemoveChildFromLinkset(child); 134 RemoveChildFromLinkset(child);
122 } 135 }
136 */
123 } 137 }
124 138
125 // The child is down to a linkset of just itself 139 // The child is down to a linkset of just itself
@@ -308,12 +322,16 @@ public class BSLinkset
308 { 322 {
309 m_children.Add(child); 323 m_children.Add(child);
310 324
311 BSPhysObject rootx = LinksetRoot; // capture the root as of now 325 BSPhysObject rootx = LinksetRoot; // capture the root and body as of now
326 BulletBody rootBodyx = LinksetRoot.BSBody;
312 BSPhysObject childx = child; 327 BSPhysObject childx = child;
328 BulletBody childBodyx = child.BSBody;
329
313 PhysicsScene.TaintedObject("AddChildToLinkset", delegate() 330 PhysicsScene.TaintedObject("AddChildToLinkset", delegate()
314 { 331 {
315 DetailLog("{0},AddChildToLinkset,taint,child={1}", LinksetRoot.LocalID, child.LocalID); 332 DetailLog("{0},AddChildToLinkset,taint,child={1}", LinksetRoot.LocalID, child.LocalID);
316 PhysicallyLinkAChildToRoot(rootx, childx); // build the physical binding between me and the child 333 // build the physical binding between me and the child
334 PhysicallyLinkAChildToRoot(rootx, rootBodyx, childx, childBodyx);
317 }); 335 });
318 } 336 }
319 return; 337 return;
@@ -323,7 +341,7 @@ public class BSLinkset
323 // This is not being called by the child so we have to make sure the child doesn't think 341 // This is not being called by the child so we have to make sure the child doesn't think
324 // it's still connected to the linkset. 342 // it's still connected to the linkset.
325 // Normal OpenSimulator operation will never do this because other SceneObjectPart information 343 // Normal OpenSimulator operation will never do this because other SceneObjectPart information
326 // has to be updated also (like pointer to prim's parent). 344 // also has to be updated (like pointer to prim's parent).
327 private void RemoveChildFromOtherLinkset(BSPhysObject pchild) 345 private void RemoveChildFromOtherLinkset(BSPhysObject pchild)
328 { 346 {
329 pchild.Linkset = new BSLinkset(PhysicsScene, pchild); 347 pchild.Linkset = new BSLinkset(PhysicsScene, pchild);
@@ -336,13 +354,15 @@ public class BSLinkset
336 { 354 {
337 if (m_children.Remove(child)) 355 if (m_children.Remove(child))
338 { 356 {
339 BSPhysObject rootx = LinksetRoot; // capture the root as of now 357 BSPhysObject rootx = LinksetRoot; // capture the root and body as of now
358 BulletBody rootBodyx = LinksetRoot.BSBody;
340 BSPhysObject childx = child; 359 BSPhysObject childx = child;
360 BulletBody childBodyx = child.BSBody;
341 PhysicsScene.TaintedObject("RemoveChildFromLinkset", delegate() 361 PhysicsScene.TaintedObject("RemoveChildFromLinkset", delegate()
342 { 362 {
343 DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", LinksetRoot.LocalID, child.LocalID); 363 DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", LinksetRoot.LocalID, child.LocalID);
344 364
345 PhysicallyUnlinkAChildFromRoot(rootx, childx); 365 PhysicallyUnlinkAChildFromRoot(rootx, rootBodyx, childx, childBodyx);
346 RecomputeLinksetConstraintVariables(); 366 RecomputeLinksetConstraintVariables();
347 }); 367 });
348 368
@@ -357,7 +377,8 @@ public class BSLinkset
357 377
358 // Create a constraint between me (root of linkset) and the passed prim (the child). 378 // Create a constraint between me (root of linkset) and the passed prim (the child).
359 // Called at taint time! 379 // Called at taint time!
360 private void PhysicallyLinkAChildToRoot(BSPhysObject rootPrim, BSPhysObject childPrim) 380 private void PhysicallyLinkAChildToRoot(BSPhysObject rootPrim, BulletBody rootBody,
381 BSPhysObject childPrim, BulletBody childBody)
361 { 382 {
362 // Zero motion for children so they don't interpolate 383 // Zero motion for children so they don't interpolate
363 childPrim.ZeroMotion(); 384 childPrim.ZeroMotion();
@@ -371,16 +392,32 @@ public class BSLinkset
371 392
372 // create a constraint that allows no freedom of movement between the two objects 393 // create a constraint that allows no freedom of movement between the two objects
373 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 394 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
374 DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2},rLoc={3},cLoc={4},midLoc={5}", 395 DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}",
375 rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID, rootPrim.Position, childPrim.Position, midPoint); 396 rootPrim.LocalID,
397 rootPrim.LocalID, rootBody.ptr.ToString("X"),
398 childPrim.LocalID, childBody.ptr.ToString("X"),
399 rootPrim.Position, childPrim.Position, midPoint);
400
401 // There is great subtlty in these paramters. Notice the check for a ptr of zero.
402 // We pass the BulletBody structure into the taint in order to capture the pointer
403 // of the body at the time of constraint creation. This doesn't work for the very first
404 // construction because there is no body yet. The body
405 // is constructed later at taint time. Thus we use the body address at time of the
406 // taint creation but, if it is zero, use what's in the prim at the moment.
407 // There is a possible race condition since shape can change without a taint call
408 // (like changing to a mesh that is already constructed). The fix for that would be
409 // to only change BSShape at taint time thus syncronizing these operations at
410 // the cost of efficiency and lag.
376 BS6DofConstraint constrain = new BS6DofConstraint( 411 BS6DofConstraint constrain = new BS6DofConstraint(
377 PhysicsScene.World, rootPrim.BSBody, childPrim.BSBody, 412 PhysicsScene.World,
413 rootBody.ptr == IntPtr.Zero ? rootPrim.BSBody : rootBody,
414 childBody.ptr == IntPtr.Zero ? childPrim.BSBody : childBody,
378 midPoint, 415 midPoint,
379 true, 416 true,
380 true 417 true
381 ); 418 );
382 /* NOTE: below is an attempt to build constraint with full frame computation, etc. 419 /* NOTE: below is an attempt to build constraint with full frame computation, etc.
383 * Using the midpoint is easier since it lets the Bullet code use the transforms 420 * Using the midpoint is easier since it lets the Bullet code manipulate the transforms
384 * of the objects. 421 * of the objects.
385 * Code left as a warning to future programmers. 422 * Code left as a warning to future programmers.
386 // ================================================================================== 423 // ==================================================================================
@@ -433,19 +470,26 @@ public class BSLinkset
433 } 470 }
434 471
435 // Remove linkage between myself and a particular child 472 // Remove linkage between myself and a particular child
473 // The root and child bodies are passed in because we need to remove the constraint between
474 // the bodies that were at unlink time.
436 // Called at taint time! 475 // Called at taint time!
437 private void PhysicallyUnlinkAChildFromRoot(BSPhysObject rootPrim, BSPhysObject childPrim) 476 private void PhysicallyUnlinkAChildFromRoot(BSPhysObject rootPrim, BulletBody rootBody,
477 BSPhysObject childPrim, BulletBody childBody)
438 { 478 {
439 DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); 479 DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}",
480 rootPrim.LocalID,
481 rootPrim.LocalID, rootBody.ptr.ToString("X"),
482 childPrim.LocalID, childBody.ptr.ToString("X"));
440 483
441 // Find the constraint for this link and get rid of it from the overall collection and from my list 484 // Find the constraint for this link and get rid of it from the overall collection and from my list
442 PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody, childPrim.BSBody); 485 PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootBody, childBody);
443 486
444 // Make the child refresh its location 487 // Make the child refresh its location
445 BulletSimAPI.PushUpdate2(childPrim.BSBody.ptr); 488 BulletSimAPI.PushUpdate2(childPrim.BSBody.ptr);
446 } 489 }
447 490
448 // Remove linkage between myself and any possible children I might have 491 /*
492 // Remove linkage between myself and any possible children I might have.
449 // Called at taint time! 493 // Called at taint time!
450 private void PhysicallyUnlinkAllChildrenFromRoot(BSPhysObject rootPrim) 494 private void PhysicallyUnlinkAllChildrenFromRoot(BSPhysObject rootPrim)
451 { 495 {
@@ -453,6 +497,7 @@ public class BSLinkset
453 497
454 PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody); 498 PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody);
455 } 499 }
500 */
456 501
457 // Invoke the detailed logger and output something if it's enabled. 502 // Invoke the detailed logger and output something if it's enabled.
458 private void DetailLog(string msg, params Object[] args) 503 private void DetailLog(string msg, params Object[] args)