diff options
author | Teravus Ovares | 2008-03-02 09:31:39 +0000 |
---|---|---|
committer | Teravus Ovares | 2008-03-02 09:31:39 +0000 |
commit | 0a5c48b1c820d0899ffb130c9bf0a59b04bc9099 (patch) | |
tree | 9f10684320a6808503ef211d3eeda7fbac5cf086 /OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | |
parent | Rename handler020 through handler029 with more (diff) | |
download | opensim-SC-0a5c48b1c820d0899ffb130c9bf0a59b04bc9099.zip opensim-SC-0a5c48b1c820d0899ffb130c9bf0a59b04bc9099.tar.gz opensim-SC-0a5c48b1c820d0899ffb130c9bf0a59b04bc9099.tar.bz2 opensim-SC-0a5c48b1c820d0899ffb130c9bf0a59b04bc9099.tar.xz |
* This is a very icky implementation of physical linkset prim using fixed joints. This will change quite drastically, however it's fun to play with.
* To play with this you must link your prim before setting it physical, otherwise they won't link in the physics engine properly. This will also be fixed.
* Currently the linked prim are extremely unstable because I have yet to implement combining of forces with the same normal. This will also be fixed. In fact, the whole PhysicsActor, ODEPrim relationship will be reworked to consider groups from the get-go.
* This implementation is better then it crashing your sim, so I'm commiting it for now.
Diffstat (limited to 'OpenSim/Region/Physics/OdePlugin/ODEPrim.cs')
-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 | ||