diff options
author | Robert Adams | 2012-10-05 15:33:17 -0700 |
---|---|---|
committer | Robert Adams | 2012-10-11 14:01:03 -0700 |
commit | 87825b0abee76c28dcffdaa2c532779b813b6d14 (patch) | |
tree | 1028e20a0c2cd8ddea9a60b0b013fa1db69daa74 /OpenSim/Region/Physics/BulletSPlugin | |
parent | Updated Robust.HG.ini.example. Thanks Austin Tate. (diff) | |
download | opensim-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')
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); | |||
1108 | public static extern void DumpRigidBody2(IntPtr sim, IntPtr collisionObject); | 1109 | public static extern void DumpRigidBody2(IntPtr sim, IntPtr collisionObject); |
1109 | 1110 | ||
1110 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 1111 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
1112 | public static extern void DumpCollisionShape2(IntPtr sim, IntPtr collisionShape); | ||
1113 | |||
1114 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||
1115 | public static extern void DumpConstraint2(IntPtr sim, IntPtr constrain); | ||
1116 | |||
1117 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||
1118 | public static extern void DumpAllInfo2(IntPtr sim); | ||
1119 | |||
1120 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||
1111 | public static extern void DumpMapInfo2(IntPtr sim, IntPtr manInfo); | 1121 | public static extern void DumpMapInfo2(IntPtr sim, IntPtr manInfo); |
1112 | 1122 | ||
1113 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 1123 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |