aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
diff options
context:
space:
mode:
authorRobert Adams2012-10-05 15:33:17 -0700
committerRobert Adams2012-10-11 14:01:03 -0700
commit87825b0abee76c28dcffdaa2c532779b813b6d14 (patch)
tree1028e20a0c2cd8ddea9a60b0b013fa1db69daa74 /OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
parentUpdated Robust.HG.ini.example. Thanks Austin Tate. (diff)
downloadopensim-SC-87825b0abee76c28dcffdaa2c532779b813b6d14.zip
opensim-SC-87825b0abee76c28dcffdaa2c532779b813b6d14.tar.gz
opensim-SC-87825b0abee76c28dcffdaa2c532779b813b6d14.tar.bz2
opensim-SC-87825b0abee76c28dcffdaa2c532779b813b6d14.tar.xz
BulletSim: Fix crash when linking large physical linksets.
Properly remove and restore linkage constraints when upgrading a prim's mesh to a hull. Lots more debug logging. Definitions and use of Bullet structure dumping. Centralize detail logging so a Flush() can be added for debugging.
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs137
1 files changed, 63 insertions, 74 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index 3e82642..20db4de 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -52,8 +52,8 @@ public class BSLinkset
52 // the physical 'taint' children separately. 52 // the physical 'taint' children separately.
53 // After taint processing and before the simulation step, these 53 // After taint processing and before the simulation step, these
54 // two lists must be the same. 54 // two lists must be the same.
55 private List<BSPhysObject> m_children; 55 private HashSet<BSPhysObject> m_children;
56 private List<BSPhysObject> m_taintChildren; 56 private HashSet<BSPhysObject> m_taintChildren;
57 57
58 // We lock the diddling of linkset classes to prevent any badness. 58 // We lock the diddling of linkset classes to prevent any badness.
59 // This locks the modification of the instances of this class. Changes 59 // This locks the modification of the instances of this class. Changes
@@ -90,8 +90,8 @@ public class BSLinkset
90 m_nextLinksetID = 1; 90 m_nextLinksetID = 1;
91 PhysicsScene = scene; 91 PhysicsScene = scene;
92 LinksetRoot = parent; 92 LinksetRoot = parent;
93 m_children = new List<BSPhysObject>(); 93 m_children = new HashSet<BSPhysObject>();
94 m_taintChildren = new List<BSPhysObject>(); 94 m_taintChildren = new HashSet<BSPhysObject>();
95 m_mass = parent.MassRaw; 95 m_mass = parent.MassRaw;
96 } 96 }
97 97
@@ -197,6 +197,8 @@ public class BSLinkset
197 PhysicsScene.TaintedObject("BSLinkSet.Refresh", delegate() 197 PhysicsScene.TaintedObject("BSLinkSet.Refresh", delegate()
198 { 198 {
199 RecomputeLinksetConstraintVariables(); 199 RecomputeLinksetConstraintVariables();
200 DetailLog("{0},BSLinkset.Refresh,complete,rBody={1}",
201 LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"));
200 }); 202 });
201 } 203 }
202 } 204 }
@@ -215,13 +217,10 @@ public class BSLinkset
215 if (IsRoot(child)) 217 if (IsRoot(child))
216 { 218 {
217 // If the one with the dependency is root, must undo all children 219 // If the one with the dependency is root, must undo all children
218 DetailLog("{0},BSLinkset.RemoveBodyDependencies,removeChildrenForRoot,rID={1},numChild={2}", 220 DetailLog("{0},BSLinkset.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}",
219 child.LocalID, LinksetRoot.LocalID, m_taintChildren.Count); 221 child.LocalID, LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"));
220 foreach (BSPhysObject bpo in m_taintChildren) 222
221 { 223 ret = PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot);
222 PhysicallyUnlinkAChildFromRoot(LinksetRoot, LinksetRoot.BSBody, bpo, bpo.BSBody);
223 ret = true;
224 }
225 } 224 }
226 else 225 else
227 { 226 {
@@ -229,12 +228,9 @@ public class BSLinkset
229 child.LocalID, 228 child.LocalID,
230 LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"), 229 LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"),
231 child.LocalID, child.BSBody.ptr.ToString("X")); 230 child.LocalID, child.BSBody.ptr.ToString("X"));
232 // Remove the dependency on the body of this one 231 // ret = PhysicallyUnlinkAChildFromRoot(LinksetRoot, child);
233 if (m_taintChildren.Contains(child)) 232 // Despite the function name, this removes any link to the specified object.
234 { 233 ret = PhysicallyUnlinkAllChildrenFromRoot(child);
235 PhysicallyUnlinkAChildFromRoot(LinksetRoot, LinksetRoot.BSBody, child, child.BSBody);
236 ret = true;
237 }
238 } 234 }
239 } 235 }
240 return ret; 236 return ret;
@@ -254,7 +250,7 @@ public class BSLinkset
254 child.LocalID, LinksetRoot.LocalID, m_taintChildren.Count); 250 child.LocalID, LinksetRoot.LocalID, m_taintChildren.Count);
255 foreach (BSPhysObject bpo in m_taintChildren) 251 foreach (BSPhysObject bpo in m_taintChildren)
256 { 252 {
257 PhysicallyLinkAChildToRoot(LinksetRoot, LinksetRoot.BSBody, bpo, bpo.BSBody); 253 PhysicallyLinkAChildToRoot(LinksetRoot, bpo);
258 } 254 }
259 } 255 }
260 else 256 else
@@ -263,7 +259,7 @@ public class BSLinkset
263 LinksetRoot.LocalID, 259 LinksetRoot.LocalID,
264 LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"), 260 LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"),
265 child.LocalID, child.BSBody.ptr.ToString("X")); 261 child.LocalID, child.BSBody.ptr.ToString("X"));
266 PhysicallyLinkAChildToRoot(LinksetRoot, LinksetRoot.BSBody, child, child.BSBody); 262 PhysicallyLinkAChildToRoot(LinksetRoot, child);
267 } 263 }
268 } 264 }
269 } 265 }
@@ -330,22 +326,22 @@ public class BSLinkset
330 { 326 {
331 m_children.Add(child); 327 m_children.Add(child);
332 328
333 BSPhysObject rootx = LinksetRoot; // capture the root and body as of now 329 BSPhysObject rootx = LinksetRoot; // capture the root as of now
334 BSPhysObject childx = child; 330 BSPhysObject childx = child;
335 331
336 DetailLog("{0},AddChildToLinkset,call,rID={1},rBody={2},cID={3},cBody={4}", 332 DetailLog("{0},AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID);
337 rootx.LocalID,
338 rootx.LocalID, rootx.BSBody.ptr.ToString("X"),
339 childx.LocalID, childx.BSBody.ptr.ToString("X"));
340 333
341 PhysicsScene.TaintedObject("AddChildToLinkset", delegate() 334 PhysicsScene.TaintedObject("AddChildToLinkset", delegate()
342 { 335 {
343 DetailLog("{0},AddChildToLinkset,taint,child={1}", LinksetRoot.LocalID, child.LocalID); 336 DetailLog("{0},AddChildToLinkset,taint,rID={1},rBody={2},cID={3},cBody={4}",
344 // build the physical binding between me and the child 337 rootx.LocalID,
345 m_taintChildren.Add(childx); 338 rootx.LocalID, rootx.BSBody.ptr.ToString("X"),
346 339 childx.LocalID, childx.BSBody.ptr.ToString("X"));
347 // Since this is taint-time, the body and shape could have changed for the child 340 // Since this is taint-time, the body and shape could have changed for the child
348 PhysicallyLinkAChildToRoot(rootx, rootx.BSBody, childx, childx.BSBody); 341 rootx.ForcePosition = rootx.Position; // DEBUG
342 childx.ForcePosition = childx.Position; // DEBUG
343 PhysicallyLinkAChildToRoot(rootx, childx);
344 m_taintChildren.Add(child);
349 }); 345 });
350 } 346 }
351 return; 347 return;
@@ -378,10 +374,8 @@ public class BSLinkset
378 374
379 PhysicsScene.TaintedObject("RemoveChildFromLinkset", delegate() 375 PhysicsScene.TaintedObject("RemoveChildFromLinkset", delegate()
380 { 376 {
381 if (m_taintChildren.Contains(childx)) 377 m_taintChildren.Remove(child);
382 m_taintChildren.Remove(childx); 378 PhysicallyUnlinkAChildFromRoot(rootx, childx);
383
384 PhysicallyUnlinkAChildFromRoot(rootx, rootx.BSBody, childx, childx.BSBody);
385 RecomputeLinksetConstraintVariables(); 379 RecomputeLinksetConstraintVariables();
386 }); 380 });
387 381
@@ -396,8 +390,7 @@ public class BSLinkset
396 390
397 // Create a constraint between me (root of linkset) and the passed prim (the child). 391 // Create a constraint between me (root of linkset) and the passed prim (the child).
398 // Called at taint time! 392 // Called at taint time!
399 private void PhysicallyLinkAChildToRoot(BSPhysObject rootPrim, BulletBody rootBody, 393 private void PhysicallyLinkAChildToRoot(BSPhysObject rootPrim, BSPhysObject childPrim)
400 BSPhysObject childPrim, BulletBody childBody)
401 { 394 {
402 // Zero motion for children so they don't interpolate 395 // Zero motion for children so they don't interpolate
403 childPrim.ZeroMotion(); 396 childPrim.ZeroMotion();
@@ -409,33 +402,17 @@ public class BSLinkset
409 // real world coordinate of midpoint between the two objects 402 // real world coordinate of midpoint between the two objects
410 OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2); 403 OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2);
411 404
412 DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", 405 DetailLog("{0},BSLinkset.PhysicallyLinkAChildToRoot,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}",
413 rootPrim.LocalID, 406 rootPrim.LocalID,
414 rootPrim.LocalID, rootBody.ptr.ToString("X"), 407 rootPrim.LocalID, rootPrim.BSBody.ptr.ToString("X"),
415 childPrim.LocalID, childBody.ptr.ToString("X"), 408 childPrim.LocalID, childPrim.BSBody.ptr.ToString("X"),
416 rootPrim.Position, childPrim.Position, midPoint); 409 rootPrim.Position, childPrim.Position, midPoint);
417 410
418 // create a constraint that allows no freedom of movement between the two objects 411 // create a constraint that allows no freedom of movement between the two objects
419 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 412 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
420 413
421 // There is great subtlty in these paramters. Notice the check for a ptr of zero.
422 // We pass the BulletBody structure into the taint in order to capture the pointer
423 // of the body at the time of constraint creation. This doesn't work for the very first
424 // construction because there is no body yet. The body
425 // is constructed later at taint time. Thus we use the body address at time of the
426 // taint creation but, if it is zero, use what's in the prim at the moment.
427 // There is a possible race condition since shape can change without a taint call
428 // (like changing to a mesh that is already constructed). The fix for that would be
429 // to only change BSShape at taint time thus syncronizing these operations at
430 // the cost of efficiency and lag.
431 BS6DofConstraint constrain = new BS6DofConstraint( 414 BS6DofConstraint constrain = new BS6DofConstraint(
432 PhysicsScene.World, 415 PhysicsScene.World, rootPrim.BSBody, childPrim.BSBody, midPoint, true, true );
433 rootBody.ptr == IntPtr.Zero ? rootPrim.BSBody : rootBody,
434 childBody.ptr == IntPtr.Zero ? childPrim.BSBody : childBody,
435 midPoint,
436 true,
437 true
438 );
439 416
440 /* NOTE: below is an attempt to build constraint with full frame computation, etc. 417 /* NOTE: below is an attempt to build constraint with full frame computation, etc.
441 * Using the midpoint is easier since it lets the Bullet code manipulate the transforms 418 * Using the midpoint is easier since it lets the Bullet code manipulate the transforms
@@ -452,7 +429,7 @@ public class BSLinkset
452 429
453 // create a constraint that allows no freedom of movement between the two objects 430 // create a constraint that allows no freedom of movement between the two objects
454 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 431 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
455 DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); 432 DetailLog("{0},BSLinkset.PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
456 BS6DofConstraint constrain = new BS6DofConstraint( 433 BS6DofConstraint constrain = new BS6DofConstraint(
457 PhysicsScene.World, rootPrim.Body, childPrim.Body, 434 PhysicsScene.World, rootPrim.Body, childPrim.Body,
458 OMV.Vector3.Zero, 435 OMV.Vector3.Zero,
@@ -486,39 +463,44 @@ public class BSLinkset
486 { 463 {
487 constrain.SetSolverIterations(PhysicsScene.Params.linkConstraintSolverIterations); 464 constrain.SetSolverIterations(PhysicsScene.Params.linkConstraintSolverIterations);
488 } 465 }
489
490 RecomputeLinksetConstraintVariables();
491 } 466 }
492 467
493 // Remove linkage between myself and a particular child 468 // Remove linkage between myself and a particular child
494 // The root and child bodies are passed in because we need to remove the constraint between 469 // The root and child bodies are passed in because we need to remove the constraint between
495 // the bodies that were at unlink time. 470 // the bodies that were at unlink time.
496 // Called at taint time! 471 // Called at taint time!
497 private void PhysicallyUnlinkAChildFromRoot(BSPhysObject rootPrim, BulletBody rootBody, 472 private bool PhysicallyUnlinkAChildFromRoot(BSPhysObject rootPrim, BSPhysObject childPrim)
498 BSPhysObject childPrim, BulletBody childBody)
499 { 473 {
500 DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}", 474 bool ret = false;
475 DetailLog("{0},BSLinkset.PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}",
501 rootPrim.LocalID, 476 rootPrim.LocalID,
502 rootPrim.LocalID, rootBody.ptr.ToString("X"), 477 rootPrim.LocalID, rootPrim.BSBody.ptr.ToString("X"),
503 childPrim.LocalID, childBody.ptr.ToString("X")); 478 childPrim.LocalID, childPrim.BSBody.ptr.ToString("X"));
504 479
505 // Find the constraint for this link and get rid of it from the overall collection and from my list 480 // Find the constraint for this link and get rid of it from the overall collection and from my list
506 PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootBody, childBody); 481 if (PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody, childPrim.BSBody))
482 {
483 // Make the child refresh its location
484 BulletSimAPI.PushUpdate2(childPrim.BSBody.ptr);
485 ret = true;
486 }
507 487
508 // Make the child refresh its location 488 return ret;
509 BulletSimAPI.PushUpdate2(childPrim.BSBody.ptr);
510 } 489 }
511 490
512 /*
513 // Remove linkage between myself and any possible children I might have. 491 // Remove linkage between myself and any possible children I might have.
514 // Called at taint time! 492 // Called at taint time!
515 private void PhysicallyUnlinkAllChildrenFromRoot(BSPhysObject rootPrim) 493 private bool PhysicallyUnlinkAllChildrenFromRoot(BSPhysObject rootPrim)
516 { 494 {
517 DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); 495 DetailLog("{0},BSLinkset.PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID);
496 bool ret = false;
518 497
519 PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody); 498 if (PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody))
499 {
500 ret = true;
501 }
502 return ret;
520 } 503 }
521 */
522 504
523 // Call each of the constraints that make up this linkset and recompute the 505 // Call each of the constraints that make up this linkset and recompute the
524 // various transforms and variables. Used when objects are added or removed 506 // various transforms and variables. Used when objects are added or removed
@@ -550,11 +532,17 @@ public class BSLinkset
550 { 532 {
551 // If this is a multiple object linkset, set everybody's center of mass to the set's center of mass 533 // If this is a multiple object linkset, set everybody's center of mass to the set's center of mass
552 OMV.Vector3 centerOfMass = ComputeLinksetCenterOfMass(); 534 OMV.Vector3 centerOfMass = ComputeLinksetCenterOfMass();
553 BulletSimAPI.SetCenterOfMassByPosRot2(LinksetRoot.BSBody.ptr, centerOfMass, OMV.Quaternion.Identity); 535 BulletSimAPI.SetCenterOfMassByPosRot2(LinksetRoot.BSBody.ptr,
536 centerOfMass, OMV.Quaternion.Identity);
537 DetailLog("{0},BSLinkset.RecomputeLinksetConstraintVariables,setCenterOfMass,COM={1},rBody={2}",
538 LinksetRoot.LocalID, centerOfMass, LinksetRoot.BSBody.ptr.ToString("X"));
554 foreach (BSPhysObject child in m_taintChildren) 539 foreach (BSPhysObject child in m_taintChildren)
555 { 540 {
556 BulletSimAPI.SetCenterOfMassByPosRot2(child.BSBody.ptr, centerOfMass, OMV.Quaternion.Identity); 541 BulletSimAPI.SetCenterOfMassByPosRot2(child.BSBody.ptr,
542 centerOfMass, OMV.Quaternion.Identity);
557 } 543 }
544
545 // BulletSimAPI.DumpAllInfo2(PhysicsScene.World.ptr); // DEBUG DEBUG DEBUG
558 } 546 }
559 return; 547 return;
560 } 548 }
@@ -563,7 +551,8 @@ public class BSLinkset
563 // Invoke the detailed logger and output something if it's enabled. 551 // Invoke the detailed logger and output something if it's enabled.
564 private void DetailLog(string msg, params Object[] args) 552 private void DetailLog(string msg, params Object[] args)
565 { 553 {
566 PhysicsScene.PhysicsLogging.Write(msg, args); 554 if (PhysicsScene.PhysicsLogging.Enabled)
555 PhysicsScene.DetailLog(msg, args);
567 } 556 }
568 557
569} 558}