aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin
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
parentUpdated Robust.HG.ini.example. Thanks Austin Tate. (diff)
downloadopensim-SC_OLD-87825b0abee76c28dcffdaa2c532779b813b6d14.zip
opensim-SC_OLD-87825b0abee76c28dcffdaa2c532779b813b6d14.tar.gz
opensim-SC_OLD-87825b0abee76c28dcffdaa2c532779b813b6d14.tar.bz2
opensim-SC_OLD-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')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs13
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs2
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs137
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs3
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs9
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs11
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs45
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs14
8 files changed, 132 insertions, 102 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
index 63a4127..a20be3a 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
@@ -49,9 +49,16 @@ public abstract class BSConstraint : IDisposable
49 if (m_enabled) 49 if (m_enabled)
50 { 50 {
51 m_enabled = false; 51 m_enabled = false;
52 bool success = BulletSimAPI.DestroyConstraint2(m_world.ptr, m_constraint.ptr); 52 if (m_constraint.ptr != IntPtr.Zero)
53 m_world.physicsScene.DetailLog("{0},BSConstraint.Dispose,taint,body1={1},body2={2},success={3}", BSScene.DetailLogZero, m_body1.ID, m_body2.ID, success); 53 {
54 m_constraint.ptr = System.IntPtr.Zero; 54 bool success = BulletSimAPI.DestroyConstraint2(m_world.ptr, m_constraint.ptr);
55 m_world.physicsScene.DetailLog("{0},BSConstraint.Dispose,taint,id1={1},body1={2},id2={3},body2={4},success={5}",
56 BSScene.DetailLogZero,
57 m_body1.ID, m_body1.ptr.ToString("X"),
58 m_body2.ID, m_body2.ptr.ToString("X"),
59 success);
60 m_constraint.ptr = System.IntPtr.Zero;
61 }
55 } 62 }
56 } 63 }
57 64
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 4ba2f62..3fb2253 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -862,7 +862,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
862 private void VDetailLog(string msg, params Object[] args) 862 private void VDetailLog(string msg, params Object[] args)
863 { 863 {
864 if (Prim.PhysicsScene.VehicleLoggingEnabled) 864 if (Prim.PhysicsScene.VehicleLoggingEnabled)
865 Prim.PhysicsScene.PhysicsLogging.Write(msg, args); 865 Prim.PhysicsScene.DetailLog(msg, args);
866 } 866 }
867 } 867 }
868} 868}
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}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index 1ac8c59..0665292 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -207,7 +207,8 @@ public abstract class BSPhysObject : PhysicsActor
207 // High performance detailed logging routine used by the physical objects. 207 // High performance detailed logging routine used by the physical objects.
208 protected void DetailLog(string msg, params Object[] args) 208 protected void DetailLog(string msg, params Object[] args)
209 { 209 {
210 PhysicsScene.PhysicsLogging.Write(msg, args); 210 if (PhysicsScene.PhysicsLogging.Enabled)
211 PhysicsScene.DetailLog(msg, args);
211 } 212 }
212} 213}
213} 214}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index f7b68ba..98a18a1 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -196,7 +196,7 @@ public sealed class BSPrim : BSPhysObject
196 _isSelected = value; 196 _isSelected = value;
197 PhysicsScene.TaintedObject("BSPrim.setSelected", delegate() 197 PhysicsScene.TaintedObject("BSPrim.setSelected", delegate()
198 { 198 {
199 // DetailLog("{0},BSPrim.selected,taint,selected={1}", LocalID, _isSelected); 199 DetailLog("{0},BSPrim.selected,taint,selected={1}", LocalID, _isSelected);
200 SetObjectDynamic(false); 200 SetObjectDynamic(false);
201 }); 201 });
202 } 202 }
@@ -620,8 +620,10 @@ public sealed class BSPrim : BSPhysObject
620 BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr); 620 BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr);
621 // There can be special things needed for implementing linksets 621 // There can be special things needed for implementing linksets
622 Linkset.MakeStatic(this); 622 Linkset.MakeStatic(this);
623 // The activation state is 'disabled' so Bullet will not try to act on it 623 // The activation state is 'disabled' so Bullet will not try to act on it.
624 BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.DISABLE_SIMULATION); 624 // BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.DISABLE_SIMULATION);
625 // Start it out sleeping and physical actions could wake it up.
626 BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.ISLAND_SLEEPING);
625 627
626 BSBody.collisionFilter = CollisionFilterGroups.StaticObjectFilter; 628 BSBody.collisionFilter = CollisionFilterGroups.StaticObjectFilter;
627 BSBody.collisionMask = CollisionFilterGroups.StaticObjectMask; 629 BSBody.collisionMask = CollisionFilterGroups.StaticObjectMask;
@@ -1204,6 +1206,7 @@ public sealed class BSPrim : BSPhysObject
1204 { 1206 {
1205 // Called if the current prim body is about to be destroyed. 1207 // Called if the current prim body is about to be destroyed.
1206 // Remove all the physical dependencies on the old body. 1208 // Remove all the physical dependencies on the old body.
1209 // (Maybe someday make the changing of BSShape an event handled by BSLinkset.)
1207 needToRestoreLinkset = Linkset.RemoveBodyDependencies(this); 1210 needToRestoreLinkset = Linkset.RemoveBodyDependencies(this);
1208 }); 1211 });
1209 1212
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index aaed7de..eed915d 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -254,7 +254,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
254 254
255 // The bounding box for the simulated world. The origin is 0,0,0 unless we're 255 // The bounding box for the simulated world. The origin is 0,0,0 unless we're
256 // a child in a mega-region. 256 // a child in a mega-region.
257 // Turns out that Bullet really doesn't care about the extents of the simulated 257 // Bullet actually doesn't care about the extents of the simulated
258 // area. It tracks active objects no matter where they are. 258 // area. It tracks active objects no matter where they are.
259 Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight); 259 Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight);
260 260
@@ -331,7 +331,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
331 // Called directly from unmanaged code so don't do much 331 // Called directly from unmanaged code so don't do much
332 private void BulletLoggerPhysLog(string msg) 332 private void BulletLoggerPhysLog(string msg)
333 { 333 {
334 PhysicsLogging.Write("[BULLETS UNMANAGED]:" + msg); 334 DetailLog("[BULLETS UNMANAGED]:" + msg);
335 } 335 }
336 336
337 public override void Dispose() 337 public override void Dispose()
@@ -494,8 +494,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
494 m_simulationStep++; 494 m_simulationStep++;
495 int numSubSteps = 0; 495 int numSubSteps = 0;
496 496
497 // Sometimes needed for debugging to find out what happened before the step 497 // DEBUG
498 // PhysicsLogging.Flush(); 498 DetailLog("{0},BSScene.Simulate,beforeStep,ntaimts={1},step={2}", DetailLogZero, numTaints, m_simulationStep);
499 499
500 try 500 try
501 { 501 {
@@ -715,6 +715,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
715 { 715 {
716 try 716 try
717 { 717 {
718 DetailLog("{0},BSScene.ProcessTaints,doTaint,id={1}", DetailLogZero, tcbe.ident); // DEBUG DEBUG DEBUG
718 tcbe.callback(); 719 tcbe.callback();
719 } 720 }
720 catch (Exception e) 721 catch (Exception e)
@@ -1270,6 +1271,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1270 public void DetailLog(string msg, params Object[] args) 1271 public void DetailLog(string msg, params Object[] args)
1271 { 1272 {
1272 PhysicsLogging.Write(msg, args); 1273 PhysicsLogging.Write(msg, args);
1274 // Add the Flush() if debugging crashes to get all the messages written out.
1275 PhysicsLogging.Flush(); // DEBUG DEBUG DEBUG
1273 } 1276 }
1274 // used to fill in the LocalID when there isn't one 1277 // used to fill in the LocalID when there isn't one
1275 public const string DetailLogZero = "0000000000"; 1278 public const string DetailLogZero = "0000000000";
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
index 399a133..283b601 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
@@ -136,7 +136,21 @@ public class BSShapeCollection : IDisposable
136 // New entry 136 // New entry
137 bodyDesc.ptr = body.ptr; 137 bodyDesc.ptr = body.ptr;
138 bodyDesc.referenceCount = 1; 138 bodyDesc.referenceCount = 1;
139 DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,ref={1}", body.ID, body, bodyDesc.referenceCount); 139 DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,ref={2}",
140 body.ID, body, bodyDesc.referenceCount);
141 BSScene.TaintCallback createOperation = delegate()
142 {
143 if (!BulletSimAPI.IsInWorld2(body.ptr))
144 {
145 BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, body.ptr);
146 DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}",
147 body.ID, body);
148 }
149 };
150 if (atTaintTime)
151 createOperation();
152 else
153 PhysicsScene.TaintedObject("BSShapeCollection.ReferenceBody", createOperation);
140 } 154 }
141 bodyDesc.lastReferenced = System.DateTime.Now; 155 bodyDesc.lastReferenced = System.DateTime.Now;
142 Bodies[body.ID] = bodyDesc; 156 Bodies[body.ID] = bodyDesc;
@@ -160,21 +174,22 @@ public class BSShapeCollection : IDisposable
160 Bodies[body.ID] = bodyDesc; 174 Bodies[body.ID] = bodyDesc;
161 DetailLog("{0},BSShapeCollection.DereferenceBody,ref={1}", body.ID, bodyDesc.referenceCount); 175 DetailLog("{0},BSShapeCollection.DereferenceBody,ref={1}", body.ID, bodyDesc.referenceCount);
162 176
163 // If body is no longer being used, free it -- bodies are never shared. 177 // If body is no longer being used, free it -- bodies can never be shared.
164 if (bodyDesc.referenceCount == 0) 178 if (bodyDesc.referenceCount == 0)
165 { 179 {
166 Bodies.Remove(body.ID); 180 Bodies.Remove(body.ID);
167 BSScene.TaintCallback removeOperation = delegate() 181 BSScene.TaintCallback removeOperation = delegate()
168 { 182 {
169 DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody. ptr={1}", 183 DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody. ptr={1}, inTaintTime={2}",
170 body.ID, body.ptr.ToString("X")); 184 body.ID, body.ptr.ToString("X"), inTaintTime);
171 // If the caller needs to know the old body is going away, pass the event up. 185 // If the caller needs to know the old body is going away, pass the event up.
172 if (bodyCallback != null) bodyCallback(body); 186 if (bodyCallback != null) bodyCallback(body);
173 187
174 // Zero any reference to the shape so it is not freed when the body is deleted.
175 BulletSimAPI.SetCollisionShape2(PhysicsScene.World.ptr, body.ptr, IntPtr.Zero);
176 // It may have already been removed from the world in which case the next is a NOOP. 188 // It may have already been removed from the world in which case the next is a NOOP.
177 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, body.ptr); 189 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, body.ptr);
190
191 // Zero any reference to the shape so it is not freed when the body is deleted.
192 BulletSimAPI.SetCollisionShape2(PhysicsScene.World.ptr, body.ptr, IntPtr.Zero);
178 BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, body.ptr); 193 BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, body.ptr);
179 }; 194 };
180 // If already in taint-time, do the operations now. Otherwise queue for later. 195 // If already in taint-time, do the operations now. Otherwise queue for later.
@@ -208,7 +223,7 @@ public class BSShapeCollection : IDisposable
208 { 223 {
209 // There is an existing instance of this mesh. 224 // There is an existing instance of this mesh.
210 meshDesc.referenceCount++; 225 meshDesc.referenceCount++;
211 DetailLog("{0},BSShapeColliction.ReferenceShape,existingMesh,key={1},cnt={2}", 226 DetailLog("{0},BSShapeCollection.ReferenceShape,existingMesh,key={1},cnt={2}",
212 BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount); 227 BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount);
213 } 228 }
214 else 229 else
@@ -217,7 +232,7 @@ public class BSShapeCollection : IDisposable
217 meshDesc.ptr = shape.ptr; 232 meshDesc.ptr = shape.ptr;
218 // We keep a reference to the underlying IMesh data so a hull can be built 233 // We keep a reference to the underlying IMesh data so a hull can be built
219 meshDesc.referenceCount = 1; 234 meshDesc.referenceCount = 1;
220 DetailLog("{0},BSShapeColliction.ReferenceShape,newMesh,key={1},cnt={2}", 235 DetailLog("{0},BSShapeCollection.ReferenceShape,newMesh,key={1},cnt={2}",
221 BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount); 236 BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount);
222 ret = true; 237 ret = true;
223 } 238 }
@@ -230,7 +245,7 @@ public class BSShapeCollection : IDisposable
230 { 245 {
231 // There is an existing instance of this hull. 246 // There is an existing instance of this hull.
232 hullDesc.referenceCount++; 247 hullDesc.referenceCount++;
233 DetailLog("{0},BSShapeColliction.ReferenceShape,existingHull,key={1},cnt={2}", 248 DetailLog("{0},BSShapeCollection.ReferenceShape,existingHull,key={1},cnt={2}",
234 BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount); 249 BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount);
235 } 250 }
236 else 251 else
@@ -238,7 +253,7 @@ public class BSShapeCollection : IDisposable
238 // This is a new reference to a hull 253 // This is a new reference to a hull
239 hullDesc.ptr = shape.ptr; 254 hullDesc.ptr = shape.ptr;
240 hullDesc.referenceCount = 1; 255 hullDesc.referenceCount = 1;
241 DetailLog("{0},BSShapeColliction.ReferenceShape,newHull,key={1},cnt={2}", 256 DetailLog("{0},BSShapeCollection.ReferenceShape,newHull,key={1},cnt={2}",
242 BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount); 257 BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount);
243 ret = true; 258 ret = true;
244 259
@@ -525,7 +540,7 @@ public class BSShapeCollection : IDisposable
525 DetailLog("{0},BSShapeCollection.CreateGeomHull,create,oldKey={1},newKey={2}", 540 DetailLog("{0},BSShapeCollection.CreateGeomHull,create,oldKey={1},newKey={2}",
526 prim.LocalID, prim.BSShape.shapeKey.ToString("X"), newHullKey.ToString("X")); 541 prim.LocalID, prim.BSShape.shapeKey.ToString("X"), newHullKey.ToString("X"));
527 542
528 // Remove usage of the previous shape. Also removes reference to underlying mesh if it is a hull. 543 // Remove usage of the previous shape.
529 DereferenceShape(prim.BSShape, true, shapeCallback); 544 DereferenceShape(prim.BSShape, true, shapeCallback);
530 545
531 newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, pbs, shapeData.Size, lod); 546 newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, pbs, shapeData.Size, lod);
@@ -659,6 +674,7 @@ public class BSShapeCollection : IDisposable
659 if (pbs.SculptEntry) 674 if (pbs.SculptEntry)
660 lod = PhysicsScene.SculptLOD; 675 lod = PhysicsScene.SculptLOD;
661 676
677 // Mega prims usually get more detail because one can interact with shape approximations at this size.
662 float maxAxis = Math.Max(shapeData.Size.X, Math.Max(shapeData.Size.Y, shapeData.Size.Z)); 678 float maxAxis = Math.Max(shapeData.Size.X, Math.Max(shapeData.Size.Y, shapeData.Size.Z));
663 if (maxAxis > PhysicsScene.MeshMegaPrimThreshold) 679 if (maxAxis > PhysicsScene.MeshMegaPrimThreshold)
664 lod = PhysicsScene.MeshMegaPrimLOD; 680 lod = PhysicsScene.MeshMegaPrimLOD;
@@ -709,13 +725,13 @@ public class BSShapeCollection : IDisposable
709 { 725 {
710 bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr, 726 bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr,
711 shapeData.ID, shapeData.Position, shapeData.Rotation); 727 shapeData.ID, shapeData.Position, shapeData.Rotation);
712 // DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); 728 DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString("X"));
713 } 729 }
714 else 730 else
715 { 731 {
716 bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr, 732 bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr,
717 shapeData.ID, shapeData.Position, shapeData.Rotation); 733 shapeData.ID, shapeData.Position, shapeData.Rotation);
718 // DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); 734 DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString("X"));
719 } 735 }
720 aBody = new BulletBody(shapeData.ID, bodyPtr); 736 aBody = new BulletBody(shapeData.ID, bodyPtr);
721 737
@@ -731,7 +747,8 @@ public class BSShapeCollection : IDisposable
731 747
732 private void DetailLog(string msg, params Object[] args) 748 private void DetailLog(string msg, params Object[] args)
733 { 749 {
734 PhysicsScene.PhysicsLogging.Write(msg, args); 750 if (PhysicsScene.PhysicsLogging.Enabled)
751 PhysicsScene.DetailLog(msg, args);
735 } 752 }
736} 753}
737} 754}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
index a43880d..bb4d399 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
@@ -192,8 +192,9 @@ public struct ShapeData
192 SHAPE_SPHERE = 5, 192 SHAPE_SPHERE = 5,
193 SHAPE_MESH = 6, 193 SHAPE_MESH = 6,
194 SHAPE_HULL = 7, 194 SHAPE_HULL = 7,
195 SHAPE_GROUNDPLANE = 8, 195 // following defined by BulletSim
196 SHAPE_TERRAIN = 9, 196 SHAPE_GROUNDPLANE = 20,
197 SHAPE_TERRAIN = 21,
197 }; 198 };
198 public uint ID; 199 public uint ID;
199 public PhysicsShapeType Type; 200 public PhysicsShapeType Type;
@@ -1108,6 +1109,15 @@ public static extern float GetMargin2(IntPtr shape);
1108public static extern void DumpRigidBody2(IntPtr sim, IntPtr collisionObject); 1109public static extern void DumpRigidBody2(IntPtr sim, IntPtr collisionObject);
1109 1110
1110[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1111[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1112public static extern void DumpCollisionShape2(IntPtr sim, IntPtr collisionShape);
1113
1114[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1115public static extern void DumpConstraint2(IntPtr sim, IntPtr constrain);
1116
1117[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1118public static extern void DumpAllInfo2(IntPtr sim);
1119
1120[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1111public static extern void DumpMapInfo2(IntPtr sim, IntPtr manInfo); 1121public static extern void DumpMapInfo2(IntPtr sim, IntPtr manInfo);
1112 1122
1113[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1123[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]