aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
diff options
context:
space:
mode:
authorTeravus Ovares2008-03-02 09:31:39 +0000
committerTeravus Ovares2008-03-02 09:31:39 +0000
commit0a5c48b1c820d0899ffb130c9bf0a59b04bc9099 (patch)
tree9f10684320a6808503ef211d3eeda7fbac5cf086 /OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
parentRename handler020 through handler029 with more (diff)
downloadopensim-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.cs321
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