diff options
author | Alan M Webb | 2009-09-16 17:31:14 -0400 |
---|---|---|
committer | dr scofield (aka dirk husemann) | 2009-09-17 17:49:13 +0200 |
commit | 88294d9ebfcbaf1a382bb71a1fcacbe90913fbd8 (patch) | |
tree | 9f55578cb0af8bbb95f7aa0c517328417914fc33 /OpenSim/Region/Framework | |
parent | Thank you, mcortez, for a patch to address showing users in group list (diff) | |
download | opensim-SC-88294d9ebfcbaf1a382bb71a1fcacbe90913fbd8.zip opensim-SC-88294d9ebfcbaf1a382bb71a1fcacbe90913fbd8.tar.gz opensim-SC-88294d9ebfcbaf1a382bb71a1fcacbe90913fbd8.tar.bz2 opensim-SC-88294d9ebfcbaf1a382bb71a1fcacbe90913fbd8.tar.xz |
While running a test case I had written to pursue problems with
llDie() not always completely working, I discovered I was
getting a lot (60+ over 6000 iterations of the test case)
null pointer exceptions in various physics related checks in
SceneObjectPart. It was apparent that the (frequent) checks for
PhysActor being non-null is an insufficient protection in a
highly asynchronous environment. The null reference exceptions
are one example of failure, but it could also happen that a
sequence started with one instance of a PhysicsActor might
finish with another?
Anyway, I have implemented a safer mechanism that should
stop the errors. I re-ran my test case with the fix in place,
and completed nearly 1000 iterations without a single occurrence.
SceneObjectPart is seriously in need of rejigging, if not for
this reason, then for its ridiculous size.
Signed-off-by: dr scofield (aka dirk husemann) <drscofield@xyzzyxyzzy.net>
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 265 |
1 files changed, 152 insertions, 113 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index b0d279c..51bb114 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -415,9 +415,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
415 | set | 415 | set |
416 | { | 416 | { |
417 | m_name = value; | 417 | m_name = value; |
418 | if (PhysActor != null) | 418 | PhysicsActor pa = PhysActor; |
419 | if (pa != null) | ||
419 | { | 420 | { |
420 | PhysActor.SOPName = value; | 421 | pa.SOPName = value; |
421 | } | 422 | } |
422 | } | 423 | } |
423 | } | 424 | } |
@@ -427,10 +428,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
427 | get { return (byte) m_material; } | 428 | get { return (byte) m_material; } |
428 | set | 429 | set |
429 | { | 430 | { |
431 | PhysicsActor pa = PhysActor; | ||
430 | m_material = (Material)value; | 432 | m_material = (Material)value; |
431 | if (PhysActor != null) | 433 | if (pa != null) |
432 | { | 434 | { |
433 | PhysActor.SetMaterial((int)value); | 435 | pa.SetMaterial((int)value); |
434 | } | 436 | } |
435 | } | 437 | } |
436 | } | 438 | } |
@@ -501,11 +503,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
501 | get | 503 | get |
502 | { | 504 | { |
503 | // If this is a linkset, we don't want the physics engine mucking up our group position here. | 505 | // If this is a linkset, we don't want the physics engine mucking up our group position here. |
504 | if (PhysActor != null && _parentID == 0) | 506 | PhysicsActor pa = PhysActor; |
507 | if (pa != null && _parentID == 0) | ||
505 | { | 508 | { |
506 | m_groupPosition.X = PhysActor.Position.X; | 509 | m_groupPosition.X = pa.Position.X; |
507 | m_groupPosition.Y = PhysActor.Position.Y; | 510 | m_groupPosition.Y = pa.Position.Y; |
508 | m_groupPosition.Z = PhysActor.Position.Z; | 511 | m_groupPosition.Z = pa.Position.Z; |
509 | } | 512 | } |
510 | 513 | ||
511 | if (IsAttachment) | 514 | if (IsAttachment) |
@@ -525,26 +528,27 @@ namespace OpenSim.Region.Framework.Scenes | |||
525 | 528 | ||
526 | m_groupPosition = value; | 529 | m_groupPosition = value; |
527 | 530 | ||
528 | if (PhysActor != null) | 531 | PhysicsActor pa = PhysActor; |
532 | if (pa != null) | ||
529 | { | 533 | { |
530 | try | 534 | try |
531 | { | 535 | { |
532 | // Root prim actually goes at Position | 536 | // Root prim actually goes at Position |
533 | if (_parentID == 0) | 537 | if (_parentID == 0) |
534 | { | 538 | { |
535 | PhysActor.Position = new PhysicsVector(value.X, value.Y, value.Z); | 539 | pa.Position = new PhysicsVector(value.X, value.Y, value.Z); |
536 | } | 540 | } |
537 | else | 541 | else |
538 | { | 542 | { |
539 | // To move the child prim in respect to the group position and rotation we have to calculate | 543 | // To move the child prim in respect to the group position and rotation we have to calculate |
540 | Vector3 resultingposition = GetWorldPosition(); | 544 | Vector3 resultingposition = GetWorldPosition(); |
541 | PhysActor.Position = new PhysicsVector(resultingposition.X, resultingposition.Y, resultingposition.Z); | 545 | pa.Position = new PhysicsVector(resultingposition.X, resultingposition.Y, resultingposition.Z); |
542 | Quaternion resultingrot = GetWorldRotation(); | 546 | Quaternion resultingrot = GetWorldRotation(); |
543 | PhysActor.Orientation = resultingrot; | 547 | pa.Orientation = resultingrot; |
544 | } | 548 | } |
545 | 549 | ||
546 | // Tell the physics engines that this prim changed. | 550 | // Tell the physics engines that this prim changed. |
547 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); | 551 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); |
548 | } | 552 | } |
549 | catch (Exception e) | 553 | catch (Exception e) |
550 | { | 554 | { |
@@ -577,15 +581,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
577 | 581 | ||
578 | if (ParentGroup != null && !ParentGroup.IsDeleted) | 582 | if (ParentGroup != null && !ParentGroup.IsDeleted) |
579 | { | 583 | { |
580 | if (_parentID != 0 && PhysActor != null) | 584 | PhysicsActor pa = PhysActor; |
585 | if (_parentID != 0 && pa != null) | ||
581 | { | 586 | { |
582 | Vector3 resultingposition = GetWorldPosition(); | 587 | Vector3 resultingposition = GetWorldPosition(); |
583 | PhysActor.Position = new PhysicsVector(resultingposition.X, resultingposition.Y, resultingposition.Z); | 588 | pa.Position = new PhysicsVector(resultingposition.X, resultingposition.Y, resultingposition.Z); |
584 | Quaternion resultingrot = GetWorldRotation(); | 589 | Quaternion resultingrot = GetWorldRotation(); |
585 | PhysActor.Orientation = resultingrot; | 590 | pa.Orientation = resultingrot; |
586 | 591 | ||
587 | // Tell the physics engines that this prim changed. | 592 | // Tell the physics engines that this prim changed. |
588 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); | 593 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); |
589 | } | 594 | } |
590 | } | 595 | } |
591 | } | 596 | } |
@@ -595,13 +600,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
595 | { | 600 | { |
596 | get | 601 | get |
597 | { | 602 | { |
603 | PhysicsActor pa = PhysActor; | ||
598 | // We don't want the physics engine mucking up the rotations in a linkset | 604 | // We don't want the physics engine mucking up the rotations in a linkset |
599 | if ((_parentID == 0) && (Shape.PCode != 9 || Shape.State == 0) && (PhysActor != null)) | 605 | if ((_parentID == 0) && (Shape.PCode != 9 || Shape.State == 0) && (pa != null)) |
600 | { | 606 | { |
601 | if (PhysActor.Orientation.X != 0 || PhysActor.Orientation.Y != 0 | 607 | if (pa.Orientation.X != 0 || pa.Orientation.Y != 0 |
602 | || PhysActor.Orientation.Z != 0 || PhysActor.Orientation.W != 0) | 608 | || pa.Orientation.Z != 0 || pa.Orientation.W != 0) |
603 | { | 609 | { |
604 | m_rotationOffset = PhysActor.Orientation; | 610 | m_rotationOffset = pa.Orientation; |
605 | } | 611 | } |
606 | } | 612 | } |
607 | 613 | ||
@@ -610,27 +616,28 @@ namespace OpenSim.Region.Framework.Scenes | |||
610 | 616 | ||
611 | set | 617 | set |
612 | { | 618 | { |
619 | PhysicsActor pa = PhysActor; | ||
613 | StoreUndoState(); | 620 | StoreUndoState(); |
614 | m_rotationOffset = value; | 621 | m_rotationOffset = value; |
615 | 622 | ||
616 | if (PhysActor != null) | 623 | if (pa != null) |
617 | { | 624 | { |
618 | try | 625 | try |
619 | { | 626 | { |
620 | // Root prim gets value directly | 627 | // Root prim gets value directly |
621 | if (_parentID == 0) | 628 | if (_parentID == 0) |
622 | { | 629 | { |
623 | PhysActor.Orientation = value; | 630 | pa.Orientation = value; |
624 | //m_log.Info("[PART]: RO1:" + PhysActor.Orientation.ToString()); | 631 | //m_log.Info("[PART]: RO1:" + PhysActor.Orientation.ToString()); |
625 | } | 632 | } |
626 | else | 633 | else |
627 | { | 634 | { |
628 | // Child prim we have to calculate it's world rotationwel | 635 | // Child prim we have to calculate it's world rotationwel |
629 | Quaternion resultingrotation = GetWorldRotation(); | 636 | Quaternion resultingrotation = GetWorldRotation(); |
630 | PhysActor.Orientation = resultingrotation; | 637 | pa.Orientation = resultingrotation; |
631 | //m_log.Info("[PART]: RO2:" + PhysActor.Orientation.ToString()); | 638 | //m_log.Info("[PART]: RO2:" + PhysActor.Orientation.ToString()); |
632 | } | 639 | } |
633 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); | 640 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); |
634 | //} | 641 | //} |
635 | } | 642 | } |
636 | catch (Exception ex) | 643 | catch (Exception ex) |
@@ -650,13 +657,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
650 | //if (PhysActor.Velocity.X != 0 || PhysActor.Velocity.Y != 0 | 657 | //if (PhysActor.Velocity.X != 0 || PhysActor.Velocity.Y != 0 |
651 | //|| PhysActor.Velocity.Z != 0) | 658 | //|| PhysActor.Velocity.Z != 0) |
652 | //{ | 659 | //{ |
653 | if (PhysActor != null) | 660 | PhysicsActor pa = PhysActor; |
661 | if (pa != null) | ||
654 | { | 662 | { |
655 | if (PhysActor.IsPhysical) | 663 | if (pa.IsPhysical) |
656 | { | 664 | { |
657 | m_velocity.X = PhysActor.Velocity.X; | 665 | m_velocity.X = pa.Velocity.X; |
658 | m_velocity.Y = PhysActor.Velocity.Y; | 666 | m_velocity.Y = pa.Velocity.Y; |
659 | m_velocity.Z = PhysActor.Velocity.Z; | 667 | m_velocity.Z = pa.Velocity.Z; |
660 | } | 668 | } |
661 | } | 669 | } |
662 | 670 | ||
@@ -666,12 +674,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
666 | set | 674 | set |
667 | { | 675 | { |
668 | m_velocity = value; | 676 | m_velocity = value; |
669 | if (PhysActor != null) | 677 | PhysicsActor pa = PhysActor; |
678 | if (pa != null) | ||
670 | { | 679 | { |
671 | if (PhysActor.IsPhysical) | 680 | if (pa.IsPhysical) |
672 | { | 681 | { |
673 | PhysActor.Velocity = new PhysicsVector(value.X, value.Y, value.Z); | 682 | pa.Velocity = new PhysicsVector(value.X, value.Y, value.Z); |
674 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); | 683 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); |
675 | } | 684 | } |
676 | } | 685 | } |
677 | } | 686 | } |
@@ -688,9 +697,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
688 | { | 697 | { |
689 | get | 698 | get |
690 | { | 699 | { |
691 | if ((PhysActor != null) && PhysActor.IsPhysical) | 700 | PhysicsActor pa = PhysActor; |
701 | if ((pa != null) && pa.IsPhysical) | ||
692 | { | 702 | { |
693 | m_angularVelocity.FromBytes(PhysActor.RotationalVelocity.GetBytes(), 0); | 703 | m_angularVelocity.FromBytes(pa.RotationalVelocity.GetBytes(), 0); |
694 | } | 704 | } |
695 | return m_angularVelocity; | 705 | return m_angularVelocity; |
696 | } | 706 | } |
@@ -709,10 +719,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
709 | get { return m_description; } | 719 | get { return m_description; } |
710 | set | 720 | set |
711 | { | 721 | { |
722 | PhysicsActor pa = PhysActor; | ||
712 | m_description = value; | 723 | m_description = value; |
713 | if (PhysActor != null) | 724 | if (pa != null) |
714 | { | 725 | { |
715 | PhysActor.SOPDescription = value; | 726 | pa.SOPDescription = value; |
716 | } | 727 | } |
717 | } | 728 | } |
718 | } | 729 | } |
@@ -806,14 +817,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
806 | if (m_shape != null) { | 817 | if (m_shape != null) { |
807 | m_shape.Scale = value; | 818 | m_shape.Scale = value; |
808 | 819 | ||
809 | if (PhysActor != null && m_parentGroup != null) | 820 | PhysicsActor pa = PhysActor; |
821 | if (pa != null && m_parentGroup != null) | ||
810 | { | 822 | { |
811 | if (m_parentGroup.Scene != null) | 823 | if (m_parentGroup.Scene != null) |
812 | { | 824 | { |
813 | if (m_parentGroup.Scene.PhysicsScene != null) | 825 | if (m_parentGroup.Scene.PhysicsScene != null) |
814 | { | 826 | { |
815 | PhysActor.Size = new PhysicsVector(m_shape.Scale.X, m_shape.Scale.Y, m_shape.Scale.Z); | 827 | pa.Size = new PhysicsVector(m_shape.Scale.X, m_shape.Scale.Y, m_shape.Scale.Z); |
816 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); | 828 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); |
817 | } | 829 | } |
818 | } | 830 | } |
819 | } | 831 | } |
@@ -1343,13 +1355,14 @@ if (m_shape != null) { | |||
1343 | RigidBody); | 1355 | RigidBody); |
1344 | 1356 | ||
1345 | // Basic Physics returns null.. joy joy joy. | 1357 | // Basic Physics returns null.. joy joy joy. |
1346 | if (PhysActor != null) | 1358 | PhysicsActor pa = PhysActor; |
1359 | if (pa != null) | ||
1347 | { | 1360 | { |
1348 | PhysActor.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info | 1361 | pa.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info |
1349 | PhysActor.SOPDescription = this.Description; | 1362 | pa.SOPDescription = this.Description; |
1350 | PhysActor.LocalID = LocalId; | 1363 | pa.LocalID = LocalId; |
1351 | DoPhysicsPropertyUpdate(RigidBody, true); | 1364 | DoPhysicsPropertyUpdate(RigidBody, true); |
1352 | PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0); | 1365 | pa.SetVolumeDetect(VolumeDetectActive ? 1 : 0); |
1353 | } | 1366 | } |
1354 | } | 1367 | } |
1355 | } | 1368 | } |
@@ -1563,23 +1576,24 @@ if (m_shape != null) { | |||
1563 | } | 1576 | } |
1564 | else | 1577 | else |
1565 | { | 1578 | { |
1566 | if (PhysActor != null) | 1579 | PhysicsActor pa = PhysActor; |
1580 | if (pa != null) | ||
1567 | { | 1581 | { |
1568 | if (UsePhysics != PhysActor.IsPhysical || isNew) | 1582 | if (UsePhysics != pa.IsPhysical || isNew) |
1569 | { | 1583 | { |
1570 | if (PhysActor.IsPhysical) // implies UsePhysics==false for this block | 1584 | if (pa.IsPhysical) // implies UsePhysics==false for this block |
1571 | { | 1585 | { |
1572 | if (!isNew) | 1586 | if (!isNew) |
1573 | ParentGroup.Scene.RemovePhysicalPrim(1); | 1587 | ParentGroup.Scene.RemovePhysicalPrim(1); |
1574 | 1588 | ||
1575 | PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; | 1589 | pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; |
1576 | PhysActor.OnOutOfBounds -= PhysicsOutOfBounds; | 1590 | pa.OnOutOfBounds -= PhysicsOutOfBounds; |
1577 | PhysActor.delink(); | 1591 | pa.delink(); |
1578 | 1592 | ||
1579 | if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew)) | 1593 | if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew)) |
1580 | { | 1594 | { |
1581 | // destroy all joints connected to this now deactivated body | 1595 | // destroy all joints connected to this now deactivated body |
1582 | m_parentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(PhysActor); | 1596 | m_parentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa); |
1583 | } | 1597 | } |
1584 | 1598 | ||
1585 | // stop client-side interpolation of all joint proxy objects that have just been deleted | 1599 | // stop client-side interpolation of all joint proxy objects that have just been deleted |
@@ -1598,7 +1612,7 @@ if (m_shape != null) { | |||
1598 | //RotationalVelocity = new Vector3(0, 0, 0); | 1612 | //RotationalVelocity = new Vector3(0, 0, 0); |
1599 | } | 1613 | } |
1600 | 1614 | ||
1601 | PhysActor.IsPhysical = UsePhysics; | 1615 | pa.IsPhysical = UsePhysics; |
1602 | 1616 | ||
1603 | 1617 | ||
1604 | // If we're not what we're supposed to be in the physics scene, recreate ourselves. | 1618 | // If we're not what we're supposed to be in the physics scene, recreate ourselves. |
@@ -1612,19 +1626,19 @@ if (m_shape != null) { | |||
1612 | { | 1626 | { |
1613 | ParentGroup.Scene.AddPhysicalPrim(1); | 1627 | ParentGroup.Scene.AddPhysicalPrim(1); |
1614 | 1628 | ||
1615 | PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; | 1629 | pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; |
1616 | PhysActor.OnOutOfBounds += PhysicsOutOfBounds; | 1630 | pa.OnOutOfBounds += PhysicsOutOfBounds; |
1617 | if (_parentID != 0 && _parentID != LocalId) | 1631 | if (_parentID != 0 && _parentID != LocalId) |
1618 | { | 1632 | { |
1619 | if (ParentGroup.RootPart.PhysActor != null) | 1633 | if (ParentGroup.RootPart.PhysActor != null) |
1620 | { | 1634 | { |
1621 | PhysActor.link(ParentGroup.RootPart.PhysActor); | 1635 | pa.link(ParentGroup.RootPart.PhysActor); |
1622 | } | 1636 | } |
1623 | } | 1637 | } |
1624 | } | 1638 | } |
1625 | } | 1639 | } |
1626 | } | 1640 | } |
1627 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); | 1641 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); |
1628 | } | 1642 | } |
1629 | } | 1643 | } |
1630 | } | 1644 | } |
@@ -1690,9 +1704,10 @@ if (m_shape != null) { | |||
1690 | 1704 | ||
1691 | public Vector3 GetGeometricCenter() | 1705 | public Vector3 GetGeometricCenter() |
1692 | { | 1706 | { |
1693 | if (PhysActor != null) | 1707 | PhysicsActor pa = PhysActor; |
1708 | if (pa != null) | ||
1694 | { | 1709 | { |
1695 | return new Vector3(PhysActor.CenterOfMass.X, PhysActor.CenterOfMass.Y, PhysActor.CenterOfMass.Z); | 1710 | return new Vector3(pa.CenterOfMass.X, pa.CenterOfMass.Y, pa.CenterOfMass.Z); |
1696 | } | 1711 | } |
1697 | else | 1712 | else |
1698 | { | 1713 | { |
@@ -1702,9 +1717,10 @@ if (m_shape != null) { | |||
1702 | 1717 | ||
1703 | public float GetMass() | 1718 | public float GetMass() |
1704 | { | 1719 | { |
1705 | if (PhysActor != null) | 1720 | PhysicsActor pa = PhysActor; |
1721 | if (pa != null) | ||
1706 | { | 1722 | { |
1707 | return PhysActor.Mass; | 1723 | return pa.Mass; |
1708 | } | 1724 | } |
1709 | else | 1725 | else |
1710 | { | 1726 | { |
@@ -1714,8 +1730,9 @@ if (m_shape != null) { | |||
1714 | 1730 | ||
1715 | public PhysicsVector GetForce() | 1731 | public PhysicsVector GetForce() |
1716 | { | 1732 | { |
1717 | if (PhysActor != null) | 1733 | PhysicsActor pa = PhysActor; |
1718 | return PhysActor.Force; | 1734 | if (pa != null) |
1735 | return pa.Force; | ||
1719 | else | 1736 | else |
1720 | return new PhysicsVector(); | 1737 | return new PhysicsVector(); |
1721 | } | 1738 | } |
@@ -2094,11 +2111,15 @@ if (m_shape != null) { | |||
2094 | 2111 | ||
2095 | public void PhysicsRequestingTerseUpdate() | 2112 | public void PhysicsRequestingTerseUpdate() |
2096 | { | 2113 | { |
2097 | if (PhysActor != null) | 2114 | PhysicsActor pa = PhysActor; |
2115 | if (pa != null) | ||
2098 | { | 2116 | { |
2099 | Vector3 newpos = new Vector3(PhysActor.Position.GetBytes(), 0); | 2117 | Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); |
2100 | 2118 | ||
2101 | if (m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.N) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.S) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.E) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) | 2119 | if (m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.N) | |
2120 | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.S) | | ||
2121 | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.E) | | ||
2122 | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) | ||
2102 | { | 2123 | { |
2103 | m_parentGroup.AbsolutePosition = newpos; | 2124 | m_parentGroup.AbsolutePosition = newpos; |
2104 | return; | 2125 | return; |
@@ -2294,14 +2315,15 @@ if (m_shape != null) { | |||
2294 | if (texture != null) | 2315 | if (texture != null) |
2295 | m_shape.SculptData = texture.Data; | 2316 | m_shape.SculptData = texture.Data; |
2296 | 2317 | ||
2297 | if (PhysActor != null) | 2318 | PhysicsActor pa = PhysActor; |
2319 | if (pa != null) | ||
2298 | { | 2320 | { |
2299 | // Tricks physics engine into thinking we've changed the part shape. | 2321 | // Tricks physics engine into thinking we've changed the part shape. |
2300 | PrimitiveBaseShape m_newshape = m_shape.Copy(); | 2322 | PrimitiveBaseShape m_newshape = m_shape.Copy(); |
2301 | PhysActor.Shape = m_newshape; | 2323 | pa.Shape = m_newshape; |
2302 | m_shape = m_newshape; | 2324 | m_shape = m_newshape; |
2303 | 2325 | ||
2304 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); | 2326 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); |
2305 | } | 2327 | } |
2306 | } | 2328 | } |
2307 | } | 2329 | } |
@@ -2520,9 +2542,10 @@ if (m_shape != null) { | |||
2520 | 2542 | ||
2521 | public void SetBuoyancy(float fvalue) | 2543 | public void SetBuoyancy(float fvalue) |
2522 | { | 2544 | { |
2523 | if (PhysActor != null) | 2545 | PhysicsActor pa = PhysActor; |
2546 | if (pa != null) | ||
2524 | { | 2547 | { |
2525 | PhysActor.Buoyancy = fvalue; | 2548 | pa.Buoyancy = fvalue; |
2526 | } | 2549 | } |
2527 | } | 2550 | } |
2528 | 2551 | ||
@@ -2538,56 +2561,62 @@ if (m_shape != null) { | |||
2538 | 2561 | ||
2539 | public void SetFloatOnWater(int floatYN) | 2562 | public void SetFloatOnWater(int floatYN) |
2540 | { | 2563 | { |
2541 | if (PhysActor != null) | 2564 | PhysicsActor pa = PhysActor; |
2565 | if (pa != null) | ||
2542 | { | 2566 | { |
2543 | if (floatYN == 1) | 2567 | if (floatYN == 1) |
2544 | { | 2568 | { |
2545 | PhysActor.FloatOnWater = true; | 2569 | pa.FloatOnWater = true; |
2546 | } | 2570 | } |
2547 | else | 2571 | else |
2548 | { | 2572 | { |
2549 | PhysActor.FloatOnWater = false; | 2573 | pa.FloatOnWater = false; |
2550 | } | 2574 | } |
2551 | } | 2575 | } |
2552 | } | 2576 | } |
2553 | 2577 | ||
2554 | public void SetForce(PhysicsVector force) | 2578 | public void SetForce(PhysicsVector force) |
2555 | { | 2579 | { |
2556 | if (PhysActor != null) | 2580 | PhysicsActor pa = PhysActor; |
2581 | if (pa != null) | ||
2557 | { | 2582 | { |
2558 | PhysActor.Force = force; | 2583 | pa.Force = force; |
2559 | } | 2584 | } |
2560 | } | 2585 | } |
2561 | 2586 | ||
2562 | public void SetVehicleType(int type) | 2587 | public void SetVehicleType(int type) |
2563 | { | 2588 | { |
2564 | if (PhysActor != null) | 2589 | PhysicsActor pa = PhysActor; |
2590 | if (pa != null) | ||
2565 | { | 2591 | { |
2566 | PhysActor.VehicleType = type; | 2592 | pa.VehicleType = type; |
2567 | } | 2593 | } |
2568 | } | 2594 | } |
2569 | 2595 | ||
2570 | public void SetVehicleFloatParam(int param, float value) | 2596 | public void SetVehicleFloatParam(int param, float value) |
2571 | { | 2597 | { |
2572 | if (PhysActor != null) | 2598 | PhysicsActor pa = PhysActor; |
2599 | if (pa != null) | ||
2573 | { | 2600 | { |
2574 | PhysActor.VehicleFloatParam(param, value); | 2601 | pa.VehicleFloatParam(param, value); |
2575 | } | 2602 | } |
2576 | } | 2603 | } |
2577 | 2604 | ||
2578 | public void SetVehicleVectorParam(int param, PhysicsVector value) | 2605 | public void SetVehicleVectorParam(int param, PhysicsVector value) |
2579 | { | 2606 | { |
2580 | if (PhysActor != null) | 2607 | PhysicsActor pa = PhysActor; |
2608 | if (pa != null) | ||
2581 | { | 2609 | { |
2582 | PhysActor.VehicleVectorParam(param, value); | 2610 | pa.VehicleVectorParam(param, value); |
2583 | } | 2611 | } |
2584 | } | 2612 | } |
2585 | 2613 | ||
2586 | public void SetVehicleRotationParam(int param, Quaternion rotation) | 2614 | public void SetVehicleRotationParam(int param, Quaternion rotation) |
2587 | { | 2615 | { |
2588 | if (PhysActor != null) | 2616 | PhysicsActor pa = PhysActor; |
2617 | if (pa != null) | ||
2589 | { | 2618 | { |
2590 | PhysActor.VehicleRotationParam(param, rotation); | 2619 | pa.VehicleRotationParam(param, rotation); |
2591 | } | 2620 | } |
2592 | } | 2621 | } |
2593 | 2622 | ||
@@ -2615,10 +2644,11 @@ if (m_shape != null) { | |||
2615 | 2644 | ||
2616 | public void SetPhysicsAxisRotation() | 2645 | public void SetPhysicsAxisRotation() |
2617 | { | 2646 | { |
2618 | if (PhysActor != null) | 2647 | PhysicsActor pa = PhysActor; |
2648 | if (pa != null) | ||
2619 | { | 2649 | { |
2620 | PhysActor.LockAngularMotion(RotationAxis); | 2650 | pa.LockAngularMotion(RotationAxis); |
2621 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); | 2651 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); |
2622 | } | 2652 | } |
2623 | } | 2653 | } |
2624 | 2654 | ||
@@ -3350,8 +3380,9 @@ if (m_shape != null) { | |||
3350 | { | 3380 | { |
3351 | IsVD = false; // Switch it of for the course of this routine | 3381 | IsVD = false; // Switch it of for the course of this routine |
3352 | VolumeDetectActive = false; // and also permanently | 3382 | VolumeDetectActive = false; // and also permanently |
3353 | if (PhysActor != null) | 3383 | PhysicsActor pa = PhysActor; |
3354 | PhysActor.SetVolumeDetect(0); // Let physics know about it too | 3384 | if (pa != null) |
3385 | pa.SetVolumeDetect(0); // Let physics know about it too | ||
3355 | } | 3386 | } |
3356 | else | 3387 | else |
3357 | { | 3388 | { |
@@ -3399,18 +3430,21 @@ if (m_shape != null) { | |||
3399 | if (IsPhantom || IsAttachment) // note: this may have been changed above in the case of joints | 3430 | if (IsPhantom || IsAttachment) // note: this may have been changed above in the case of joints |
3400 | { | 3431 | { |
3401 | AddFlag(PrimFlags.Phantom); | 3432 | AddFlag(PrimFlags.Phantom); |
3402 | if (PhysActor != null) | 3433 | PhysicsActor pa = PhysActor; |
3434 | if (pa != null) | ||
3403 | { | 3435 | { |
3404 | m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); | 3436 | m_parentGroup.Scene.PhysicsScene.RemovePrim(pa); |
3405 | /// that's not wholesome. Had to make Scene public | 3437 | /// that's not wholesome. Had to make Scene public |
3406 | PhysActor = null; | 3438 | pa = null; |
3407 | } | 3439 | } |
3408 | } | 3440 | } |
3409 | else // Not phantom | 3441 | else // Not phantom |
3410 | { | 3442 | { |
3411 | RemFlag(PrimFlags.Phantom); | 3443 | RemFlag(PrimFlags.Phantom); |
3412 | 3444 | ||
3413 | if (PhysActor == null) | 3445 | // This is NOT safe!! |
3446 | PhysicsActor pa = PhysActor; | ||
3447 | if (pa == null) | ||
3414 | { | 3448 | { |
3415 | // It's not phantom anymore. So make sure the physics engine get's knowledge of it | 3449 | // It's not phantom anymore. So make sure the physics engine get's knowledge of it |
3416 | PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( | 3450 | PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( |
@@ -3421,9 +3455,9 @@ if (m_shape != null) { | |||
3421 | RotationOffset, | 3455 | RotationOffset, |
3422 | UsePhysics); | 3456 | UsePhysics); |
3423 | 3457 | ||
3424 | if (PhysActor != null) | 3458 | if (pa != null) |
3425 | { | 3459 | { |
3426 | PhysActor.LocalID = LocalId; | 3460 | pa.LocalID = LocalId; |
3427 | DoPhysicsPropertyUpdate(UsePhysics, true); | 3461 | DoPhysicsPropertyUpdate(UsePhysics, true); |
3428 | if (m_parentGroup != null) | 3462 | if (m_parentGroup != null) |
3429 | { | 3463 | { |
@@ -3442,14 +3476,14 @@ if (m_shape != null) { | |||
3442 | (CollisionSound != UUID.Zero) | 3476 | (CollisionSound != UUID.Zero) |
3443 | ) | 3477 | ) |
3444 | { | 3478 | { |
3445 | PhysActor.OnCollisionUpdate += PhysicsCollision; | 3479 | pa.OnCollisionUpdate += PhysicsCollision; |
3446 | PhysActor.SubscribeEvents(1000); | 3480 | pa.SubscribeEvents(1000); |
3447 | } | 3481 | } |
3448 | } | 3482 | } |
3449 | } | 3483 | } |
3450 | else // it already has a physical representation | 3484 | else // it already has a physical representation |
3451 | { | 3485 | { |
3452 | PhysActor.IsPhysical = UsePhysics; | 3486 | pa.IsPhysical = UsePhysics; |
3453 | 3487 | ||
3454 | DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim | 3488 | DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim |
3455 | if (m_parentGroup != null) | 3489 | if (m_parentGroup != null) |
@@ -3472,9 +3506,10 @@ if (m_shape != null) { | |||
3472 | // Defensive programming calls for a check here. | 3506 | // Defensive programming calls for a check here. |
3473 | // Better would be throwing an exception that could be catched by a unit test as the internal | 3507 | // Better would be throwing an exception that could be catched by a unit test as the internal |
3474 | // logic should make sure, this Physactor is always here. | 3508 | // logic should make sure, this Physactor is always here. |
3475 | if (this.PhysActor != null) | 3509 | PhysicsActor pa = this.PhysActor; |
3510 | if (pa != null) | ||
3476 | { | 3511 | { |
3477 | PhysActor.SetVolumeDetect(1); | 3512 | pa.SetVolumeDetect(1); |
3478 | AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active | 3513 | AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active |
3479 | this.VolumeDetectActive = true; | 3514 | this.VolumeDetectActive = true; |
3480 | } | 3515 | } |
@@ -3482,10 +3517,11 @@ if (m_shape != null) { | |||
3482 | } | 3517 | } |
3483 | else | 3518 | else |
3484 | { // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like | 3519 | { // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like |
3485 | // (mumbles, well, at least if you have infinte CPU powers :-)) | 3520 | // (mumbles, well, at least if you have infinte CPU powers :-) ) |
3486 | if (this.PhysActor != null) | 3521 | PhysicsActor pa = this.PhysActor; |
3522 | if (pa != null) | ||
3487 | { | 3523 | { |
3488 | PhysActor.SetVolumeDetect(0); | 3524 | pa.SetVolumeDetect(0); |
3489 | } | 3525 | } |
3490 | this.VolumeDetectActive = false; | 3526 | this.VolumeDetectActive = false; |
3491 | } | 3527 | } |
@@ -3543,10 +3579,11 @@ if (m_shape != null) { | |||
3543 | m_shape.PathTaperY = shapeBlock.PathTaperY; | 3579 | m_shape.PathTaperY = shapeBlock.PathTaperY; |
3544 | m_shape.PathTwist = shapeBlock.PathTwist; | 3580 | m_shape.PathTwist = shapeBlock.PathTwist; |
3545 | m_shape.PathTwistBegin = shapeBlock.PathTwistBegin; | 3581 | m_shape.PathTwistBegin = shapeBlock.PathTwistBegin; |
3546 | if (PhysActor != null) | 3582 | PhysicsActor pa = PhysActor; |
3583 | if (pa != null) | ||
3547 | { | 3584 | { |
3548 | PhysActor.Shape = m_shape; | 3585 | pa.Shape = m_shape; |
3549 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); | 3586 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); |
3550 | } | 3587 | } |
3551 | 3588 | ||
3552 | // This is what makes vehicle trailers work | 3589 | // This is what makes vehicle trailers work |
@@ -3647,19 +3684,21 @@ if (m_shape != null) { | |||
3647 | ) | 3684 | ) |
3648 | { | 3685 | { |
3649 | // subscribe to physics updates. | 3686 | // subscribe to physics updates. |
3650 | if (PhysActor != null) | 3687 | PhysicsActor pa = PhysActor; |
3688 | if (pa != null) | ||
3651 | { | 3689 | { |
3652 | PhysActor.OnCollisionUpdate += PhysicsCollision; | 3690 | pa.OnCollisionUpdate += PhysicsCollision; |
3653 | PhysActor.SubscribeEvents(1000); | 3691 | pa.SubscribeEvents(1000); |
3654 | 3692 | ||
3655 | } | 3693 | } |
3656 | } | 3694 | } |
3657 | else | 3695 | else |
3658 | { | 3696 | { |
3659 | if (PhysActor != null) | 3697 | PhysicsActor pa = PhysActor; |
3698 | if (pa != null) | ||
3660 | { | 3699 | { |
3661 | PhysActor.UnSubscribeEvents(); | 3700 | pa.UnSubscribeEvents(); |
3662 | PhysActor.OnCollisionUpdate -= PhysicsCollision; | 3701 | pa.OnCollisionUpdate -= PhysicsCollision; |
3663 | } | 3702 | } |
3664 | } | 3703 | } |
3665 | 3704 | ||