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