diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 321 |
1 files changed, 201 insertions, 120 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 34c5cfd..eb90cf4 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | |||
@@ -90,6 +90,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
90 | public IntPtr prev_geom; | 90 | public IntPtr prev_geom; |
91 | public IntPtr _triMeshData; | 91 | public IntPtr _triMeshData; |
92 | 92 | ||
93 | private IntPtr _linkJointGroup = (IntPtr)0; | ||
94 | private PhysicsActor _parent = null; | ||
95 | private PhysicsActor m_taintparent = null; | ||
96 | |||
97 | |||
93 | private bool iscolliding = false; | 98 | private bool iscolliding = false; |
94 | private bool m_isphysical = false; | 99 | private bool m_isphysical = false; |
95 | private bool m_isSelected = false; | 100 | private bool m_isSelected = false; |
@@ -113,6 +118,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
113 | private PhysicsVector _target_velocity; | 118 | private PhysicsVector _target_velocity; |
114 | public d.Mass pMass; | 119 | public d.Mass pMass; |
115 | 120 | ||
121 | private IntPtr m_linkJoint = (IntPtr)0; | ||
122 | |||
116 | private int debugcounter = 0; | 123 | private int debugcounter = 0; |
117 | 124 | ||
118 | public OdePrim(String primName, OdeScene parent_scene, PhysicsVector pos, PhysicsVector size, | 125 | public OdePrim(String primName, OdeScene parent_scene, PhysicsVector pos, PhysicsVector size, |
@@ -719,6 +726,45 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
719 | 726 | ||
720 | if (m_taintVelocity != PhysicsVector.Zero) | 727 | if (m_taintVelocity != PhysicsVector.Zero) |
721 | changevelocity(timestep); | 728 | changevelocity(timestep); |
729 | |||
730 | if (m_taintparent != _parent) | ||
731 | changelink(timestep); | ||
732 | } | ||
733 | |||
734 | private void changelink(float timestep) | ||
735 | { | ||
736 | while (ode.lockquery()) | ||
737 | { | ||
738 | } | ||
739 | ode.dlock(_parent_scene.world); | ||
740 | |||
741 | if (_parent == null && m_taintparent != null) | ||
742 | { | ||
743 | if (m_taintparent.PhysicsActorType == (int)ActorTypes.Prim) | ||
744 | { | ||
745 | OdePrim obj = (OdePrim)m_taintparent; | ||
746 | if (obj.Body != (IntPtr)0 && Body != (IntPtr)0) | ||
747 | { | ||
748 | _linkJointGroup = d.JointGroupCreate(0); | ||
749 | m_linkJoint = d.JointCreateFixed(_parent_scene.world, _linkJointGroup); | ||
750 | d.JointAttach(m_linkJoint, obj.Body, Body); | ||
751 | d.JointSetFixed(m_linkJoint); | ||
752 | } | ||
753 | } | ||
754 | |||
755 | } | ||
756 | else if (_parent != null && m_taintparent == null) | ||
757 | { | ||
758 | if (Body != (IntPtr)0 && _linkJointGroup != (IntPtr)0) | ||
759 | d.JointGroupDestroy(_linkJointGroup); | ||
760 | |||
761 | _linkJointGroup = (IntPtr)0; | ||
762 | m_linkJoint = (IntPtr)0; | ||
763 | |||
764 | } | ||
765 | ode.dunlock(_parent_scene.world); | ||
766 | |||
767 | _parent = m_taintparent; | ||
722 | } | 768 | } |
723 | 769 | ||
724 | private void changeSelectedStatus(float timestep) | 770 | private void changeSelectedStatus(float timestep) |
@@ -970,8 +1016,25 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
970 | enableBody(); | 1016 | enableBody(); |
971 | //Prim auto disable after 20 frames, | 1017 | //Prim auto disable after 20 frames, |
972 | //if you move it, re-enable the prim manually. | 1018 | //if you move it, re-enable the prim manually. |
973 | 1019 | if (_parent != null) | |
1020 | { | ||
1021 | if (m_linkJoint != (IntPtr)0) | ||
1022 | { | ||
1023 | d.JointDestroy(m_linkJoint); | ||
1024 | m_linkJoint = (IntPtr)0; | ||
1025 | } | ||
1026 | } | ||
974 | d.BodySetPosition(Body, _position.X, _position.Y, _position.Z); | 1027 | d.BodySetPosition(Body, _position.X, _position.Y, _position.Z); |
1028 | if (_parent != null) | ||
1029 | { | ||
1030 | OdePrim odParent = (OdePrim)_parent; | ||
1031 | if (Body != (IntPtr)0 && odParent.Body != (IntPtr)0) | ||
1032 | { | ||
1033 | m_linkJoint = d.JointCreateFixed(_parent_scene.world, _linkJointGroup); | ||
1034 | d.JointAttach(m_linkJoint, Body, odParent.Body); | ||
1035 | d.JointSetFixed(m_linkJoint); | ||
1036 | } | ||
1037 | } | ||
975 | d.BodyEnable(Body); | 1038 | d.BodyEnable(Body); |
976 | 1039 | ||
977 | } | 1040 | } |
@@ -1652,154 +1715,172 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1652 | m_log.Warn("[PHYSICS]: Too many crossing failures for: " + m_primName); | 1715 | m_log.Warn("[PHYSICS]: Too many crossing failures for: " + m_primName); |
1653 | } | 1716 | } |
1654 | } | 1717 | } |
1718 | |||
1719 | public override void link(PhysicsActor obj) | ||
1720 | { | ||
1721 | m_taintparent = obj; | ||
1722 | } | ||
1723 | |||
1724 | public override void delink() | ||
1725 | { | ||
1726 | m_taintparent = null; | ||
1727 | } | ||
1728 | |||
1655 | public void UpdatePositionAndVelocity() | 1729 | public void UpdatePositionAndVelocity() |
1656 | { | 1730 | { |
1657 | // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! | 1731 | // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! |
1658 | PhysicsVector pv = new PhysicsVector(0, 0, 0); | 1732 | if (_parent != null) |
1659 | bool lastZeroFlag = _zeroFlag; | ||
1660 | if (Body != (IntPtr) 0) | ||
1661 | { | 1733 | { |
1662 | d.Vector3 vec = d.BodyGetPosition(Body); | ||
1663 | d.Quaternion ori = d.BodyGetQuaternion(Body); | ||
1664 | d.Vector3 vel = d.BodyGetLinearVel(Body); | ||
1665 | d.Vector3 rotvel = d.BodyGetAngularVel(Body); | ||
1666 | 1734 | ||
1667 | PhysicsVector l_position = new PhysicsVector(); | 1735 | } |
1736 | else | ||
1737 | { | ||
1738 | PhysicsVector pv = new PhysicsVector(0, 0, 0); | ||
1739 | bool lastZeroFlag = _zeroFlag; | ||
1740 | if (Body != (IntPtr)0) | ||
1741 | { | ||
1742 | d.Vector3 vec = d.BodyGetPosition(Body); | ||
1743 | d.Quaternion ori = d.BodyGetQuaternion(Body); | ||
1744 | d.Vector3 vel = d.BodyGetLinearVel(Body); | ||
1745 | d.Vector3 rotvel = d.BodyGetAngularVel(Body); | ||
1668 | 1746 | ||
1669 | 1747 | PhysicsVector l_position = new PhysicsVector(); | |
1670 | // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!) | ||
1671 | //if (vec.X < 0.0f) { vec.X = 0.0f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } | ||
1672 | //if (vec.Y < 0.0f) { vec.Y = 0.0f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } | ||
1673 | //if (vec.X > 255.95f) { vec.X = 255.95f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } | ||
1674 | //if (vec.Y > 255.95f) { vec.Y = 255.95f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } | ||
1675 | 1748 | ||
1676 | m_lastposition = _position; | ||
1677 | 1749 | ||
1678 | l_position.X = vec.X; | 1750 | // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!) |
1679 | l_position.Y = vec.Y; | 1751 | //if (vec.X < 0.0f) { vec.X = 0.0f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } |
1680 | l_position.Z = vec.Z; | 1752 | //if (vec.Y < 0.0f) { vec.Y = 0.0f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } |
1753 | //if (vec.X > 255.95f) { vec.X = 255.95f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } | ||
1754 | //if (vec.Y > 255.95f) { vec.Y = 255.95f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } | ||
1681 | 1755 | ||
1682 | if (l_position.X > 255.95f || l_position.X < 0f || l_position.Y > 255.95f || l_position.Y < 0f) | 1756 | m_lastposition = _position; |
1683 | { | 1757 | |
1684 | base.RaiseOutOfBounds(_position); | 1758 | l_position.X = vec.X; |
1685 | } | 1759 | l_position.Y = vec.Y; |
1760 | l_position.Z = vec.Z; | ||
1761 | |||
1762 | if (l_position.X > 255.95f || l_position.X < 0f || l_position.Y > 255.95f || l_position.Y < 0f) | ||
1763 | { | ||
1764 | base.RaiseOutOfBounds(_position); | ||
1765 | } | ||
1686 | //if (m_crossingfailures < 5) | 1766 | //if (m_crossingfailures < 5) |
1687 | //{ | 1767 | //{ |
1688 | //base.RequestPhysicsterseUpdate(); | 1768 | //base.RequestPhysicsterseUpdate(); |
1769 | //} | ||
1689 | //} | 1770 | //} |
1690 | //} | ||
1691 | |||
1692 | if (l_position.Z < 0) | ||
1693 | { | ||
1694 | // This is so prim that get lost underground don't fall forever and suck up | ||
1695 | // | ||
1696 | // Sim resources and memory. | ||
1697 | // Disables the prim's movement physics.... | ||
1698 | // It's a hack and will generate a console message if it fails. | ||
1699 | |||
1700 | |||
1701 | //IsPhysical = false; | ||
1702 | base.RaiseOutOfBounds(_position); | ||
1703 | _velocity.X = 0; | ||
1704 | _velocity.Y = 0; | ||
1705 | _velocity.Z = 0; | ||
1706 | m_rotationalVelocity.X = 0; | ||
1707 | m_rotationalVelocity.Y = 0; | ||
1708 | m_rotationalVelocity.Z = 0; | ||
1709 | base.RequestPhysicsterseUpdate(); | ||
1710 | m_throttleUpdates = false; | ||
1711 | throttleCounter = 0; | ||
1712 | _zeroFlag = true; | ||
1713 | //outofBounds = true; | ||
1714 | } | ||
1715 | |||
1716 | if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02) | ||
1717 | && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02) | ||
1718 | && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02)) | ||
1719 | { | ||
1720 | _zeroFlag = true; | ||
1721 | m_throttleUpdates = false; | ||
1722 | } | ||
1723 | else | ||
1724 | { | ||
1725 | //System.Console.WriteLine(Math.Abs(m_lastposition.X - l_position.X).ToString()); | ||
1726 | _zeroFlag = false; | ||
1727 | } | ||
1728 | |||
1729 | 1771 | ||
1730 | if (_zeroFlag) | 1772 | if (l_position.Z < 0) |
1731 | { | ||
1732 | // Supposedly this is supposed to tell SceneObjectGroup that | ||
1733 | // no more updates need to be sent.. | ||
1734 | // but it seems broken. | ||
1735 | _velocity.X = 0.0f; | ||
1736 | _velocity.Y = 0.0f; | ||
1737 | _velocity.Z = 0.0f; | ||
1738 | //_orientation.w = 0f; | ||
1739 | //_orientation.x = 0f; | ||
1740 | //_orientation.y = 0f; | ||
1741 | //_orientation.z = 0f; | ||
1742 | m_rotationalVelocity.X = 0; | ||
1743 | m_rotationalVelocity.Y = 0; | ||
1744 | m_rotationalVelocity.Z = 0; | ||
1745 | if (!m_lastUpdateSent) | ||
1746 | { | 1773 | { |
1774 | // This is so prim that get lost underground don't fall forever and suck up | ||
1775 | // | ||
1776 | // Sim resources and memory. | ||
1777 | // Disables the prim's movement physics.... | ||
1778 | // It's a hack and will generate a console message if it fails. | ||
1779 | |||
1780 | |||
1781 | //IsPhysical = false; | ||
1782 | base.RaiseOutOfBounds(_position); | ||
1783 | _velocity.X = 0; | ||
1784 | _velocity.Y = 0; | ||
1785 | _velocity.Z = 0; | ||
1786 | m_rotationalVelocity.X = 0; | ||
1787 | m_rotationalVelocity.Y = 0; | ||
1788 | m_rotationalVelocity.Z = 0; | ||
1789 | base.RequestPhysicsterseUpdate(); | ||
1747 | m_throttleUpdates = false; | 1790 | m_throttleUpdates = false; |
1748 | throttleCounter = 0; | 1791 | throttleCounter = 0; |
1749 | m_rotationalVelocity = pv; | 1792 | _zeroFlag = true; |
1750 | base.RequestPhysicsterseUpdate(); | 1793 | //outofBounds = true; |
1751 | m_lastUpdateSent = true; | ||
1752 | } | 1794 | } |
1753 | } | ||
1754 | else | ||
1755 | { | ||
1756 | if (lastZeroFlag != _zeroFlag) | ||
1757 | base.RequestPhysicsterseUpdate(); | ||
1758 | |||
1759 | m_lastVelocity = _velocity; | ||
1760 | 1795 | ||
1761 | _position = l_position; | 1796 | if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02) |
1762 | 1797 | && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02) | |
1763 | _velocity.X = vel.X; | 1798 | && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02)) |
1764 | _velocity.Y = vel.Y; | ||
1765 | _velocity.Z = vel.Z; | ||
1766 | if (_velocity.IsIdentical(pv, 0.5f)) | ||
1767 | { | 1799 | { |
1768 | m_rotationalVelocity = pv; | 1800 | _zeroFlag = true; |
1801 | m_throttleUpdates = false; | ||
1769 | } | 1802 | } |
1770 | else | 1803 | else |
1771 | { | 1804 | { |
1772 | m_rotationalVelocity.setValues(rotvel.X, rotvel.Y, rotvel.Z); | 1805 | //System.Console.WriteLine(Math.Abs(m_lastposition.X - l_position.X).ToString()); |
1806 | _zeroFlag = false; | ||
1773 | } | 1807 | } |
1774 | 1808 | ||
1775 | //System.Console.WriteLine("ODE: " + m_rotationalVelocity.ToString()); | 1809 | |
1776 | _orientation.w = ori.W; | 1810 | if (_zeroFlag) |
1777 | _orientation.x = ori.X; | ||
1778 | _orientation.y = ori.Y; | ||
1779 | _orientation.z = ori.Z; | ||
1780 | m_lastUpdateSent = false; | ||
1781 | if (!m_throttleUpdates || throttleCounter > 15) | ||
1782 | { | 1811 | { |
1783 | 1812 | // Supposedly this is supposed to tell SceneObjectGroup that | |
1784 | base.RequestPhysicsterseUpdate(); | 1813 | // no more updates need to be sent.. |
1814 | // but it seems broken. | ||
1815 | _velocity.X = 0.0f; | ||
1816 | _velocity.Y = 0.0f; | ||
1817 | _velocity.Z = 0.0f; | ||
1818 | //_orientation.w = 0f; | ||
1819 | //_orientation.x = 0f; | ||
1820 | //_orientation.y = 0f; | ||
1821 | //_orientation.z = 0f; | ||
1822 | m_rotationalVelocity.X = 0; | ||
1823 | m_rotationalVelocity.Y = 0; | ||
1824 | m_rotationalVelocity.Z = 0; | ||
1825 | if (!m_lastUpdateSent) | ||
1826 | { | ||
1827 | m_throttleUpdates = false; | ||
1828 | throttleCounter = 0; | ||
1829 | m_rotationalVelocity = pv; | ||
1830 | base.RequestPhysicsterseUpdate(); | ||
1831 | m_lastUpdateSent = true; | ||
1832 | } | ||
1785 | } | 1833 | } |
1786 | else | 1834 | else |
1787 | { | 1835 | { |
1788 | throttleCounter++; | 1836 | if (lastZeroFlag != _zeroFlag) |
1837 | base.RequestPhysicsterseUpdate(); | ||
1838 | |||
1839 | m_lastVelocity = _velocity; | ||
1840 | |||
1841 | _position = l_position; | ||
1842 | |||
1843 | _velocity.X = vel.X; | ||
1844 | _velocity.Y = vel.Y; | ||
1845 | _velocity.Z = vel.Z; | ||
1846 | if (_velocity.IsIdentical(pv, 0.5f)) | ||
1847 | { | ||
1848 | m_rotationalVelocity = pv; | ||
1849 | } | ||
1850 | else | ||
1851 | { | ||
1852 | m_rotationalVelocity.setValues(rotvel.X, rotvel.Y, rotvel.Z); | ||
1853 | } | ||
1854 | |||
1855 | //System.Console.WriteLine("ODE: " + m_rotationalVelocity.ToString()); | ||
1856 | _orientation.w = ori.W; | ||
1857 | _orientation.x = ori.X; | ||
1858 | _orientation.y = ori.Y; | ||
1859 | _orientation.z = ori.Z; | ||
1860 | m_lastUpdateSent = false; | ||
1861 | if (!m_throttleUpdates || throttleCounter > 15) | ||
1862 | { | ||
1863 | |||
1864 | base.RequestPhysicsterseUpdate(); | ||
1865 | } | ||
1866 | else | ||
1867 | { | ||
1868 | throttleCounter++; | ||
1869 | } | ||
1789 | } | 1870 | } |
1871 | m_lastposition = l_position; | ||
1872 | } | ||
1873 | else | ||
1874 | { | ||
1875 | // Not a body.. so Make sure the client isn't interpolating | ||
1876 | _velocity.X = 0; | ||
1877 | _velocity.Y = 0; | ||
1878 | _velocity.Z = 0; | ||
1879 | m_rotationalVelocity.X = 0; | ||
1880 | m_rotationalVelocity.Y = 0; | ||
1881 | m_rotationalVelocity.Z = 0; | ||
1882 | _zeroFlag = true; | ||
1790 | } | 1883 | } |
1791 | m_lastposition = l_position; | ||
1792 | } | ||
1793 | else | ||
1794 | { | ||
1795 | // Not a body.. so Make sure the client isn't interpolating | ||
1796 | _velocity.X = 0; | ||
1797 | _velocity.Y = 0; | ||
1798 | _velocity.Z = 0; | ||
1799 | m_rotationalVelocity.X = 0; | ||
1800 | m_rotationalVelocity.Y = 0; | ||
1801 | m_rotationalVelocity.Z = 0; | ||
1802 | _zeroFlag = true; | ||
1803 | } | 1884 | } |
1804 | } | 1885 | } |
1805 | 1886 | ||