diff options
Diffstat (limited to 'OpenSim/Region/Physics/OdePlugin/ODEPrim.cs')
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 141 |
1 files changed, 138 insertions, 3 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 8e0640b..7a9734c 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | |||
@@ -38,6 +38,10 @@ using OpenSim.Region.Physics.Manager; | |||
38 | 38 | ||
39 | namespace OpenSim.Region.Physics.OdePlugin | 39 | namespace OpenSim.Region.Physics.OdePlugin |
40 | { | 40 | { |
41 | /// <summary> | ||
42 | /// Various properties that ODE uses for AMotors but isn't exposed in ODE.NET so we must define them ourselves. | ||
43 | /// </summary> | ||
44 | |||
41 | public class OdePrim : PhysicsActor | 45 | public class OdePrim : PhysicsActor |
42 | { | 46 | { |
43 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
@@ -55,6 +59,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
55 | private PhysicsVector m_taintsize; | 59 | private PhysicsVector m_taintsize; |
56 | private PhysicsVector m_taintVelocity = PhysicsVector.Zero; | 60 | private PhysicsVector m_taintVelocity = PhysicsVector.Zero; |
57 | private Quaternion m_taintrot; | 61 | private Quaternion m_taintrot; |
62 | private PhysicsVector m_angularlock = new PhysicsVector(1f, 1f, 1f); | ||
63 | private PhysicsVector m_taintAngularLock = new PhysicsVector(1f, 1f, 1f); | ||
64 | private IntPtr Amotor = IntPtr.Zero; | ||
58 | 65 | ||
59 | private PhysicsVector m_PIDTarget = new PhysicsVector(0, 0, 0); | 66 | private PhysicsVector m_PIDTarget = new PhysicsVector(0, 0, 0); |
60 | private float m_PIDTau = 0f; | 67 | private float m_PIDTau = 0f; |
@@ -309,6 +316,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
309 | m_collisionscore = 0; | 316 | m_collisionscore = 0; |
310 | m_disabled = false; | 317 | m_disabled = false; |
311 | 318 | ||
319 | // The body doesn't already have a finite rotation mode set here | ||
320 | if ((!m_angularlock.IsIdentical(PhysicsVector.Zero, 0)) && _parent == null) | ||
321 | { | ||
322 | createAMotor(m_angularlock); | ||
323 | } | ||
324 | |||
312 | _parent_scene.addActivePrim(this); | 325 | _parent_scene.addActivePrim(this); |
313 | } | 326 | } |
314 | 327 | ||
@@ -722,7 +735,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
722 | } | 735 | } |
723 | if (prim_geom != (IntPtr)0) | 736 | if (prim_geom != (IntPtr)0) |
724 | { | 737 | { |
725 | if (m_taintposition != _position) | 738 | if (!_position.IsIdentical(m_taintposition,0f)) |
726 | changemove(timestep); | 739 | changemove(timestep); |
727 | 740 | ||
728 | if (m_taintrot != _orientation) | 741 | if (m_taintrot != _orientation) |
@@ -733,7 +746,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
733 | changePhysicsStatus(timestep); | 746 | changePhysicsStatus(timestep); |
734 | // | 747 | // |
735 | 748 | ||
736 | if (m_taintsize != _size) | 749 | if (!_size.IsIdentical(m_taintsize,0)) |
737 | changesize(timestep); | 750 | changesize(timestep); |
738 | // | 751 | // |
739 | 752 | ||
@@ -750,7 +763,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
750 | if (m_taintselected != m_isSelected) | 763 | if (m_taintselected != m_isSelected) |
751 | changeSelectedStatus(timestep); | 764 | changeSelectedStatus(timestep); |
752 | 765 | ||
753 | if (m_taintVelocity != PhysicsVector.Zero) | 766 | if (!m_taintVelocity.IsIdentical(PhysicsVector.Zero,0)) |
754 | changevelocity(timestep); | 767 | changevelocity(timestep); |
755 | 768 | ||
756 | if (m_taintparent != _parent) | 769 | if (m_taintparent != _parent) |
@@ -759,6 +772,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
759 | if (m_taintCollidesWater != m_collidesWater) | 772 | if (m_taintCollidesWater != m_collidesWater) |
760 | changefloatonwater(timestep); | 773 | changefloatonwater(timestep); |
761 | 774 | ||
775 | if (!m_angularlock.IsIdentical(m_taintAngularLock,0)) | ||
776 | changeAngularLock(timestep); | ||
762 | 777 | ||
763 | } | 778 | } |
764 | else | 779 | else |
@@ -767,6 +782,35 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
767 | } | 782 | } |
768 | } | 783 | } |
769 | 784 | ||
785 | private void changeAngularLock(float timestep) | ||
786 | { | ||
787 | // do we have a Physical object? | ||
788 | if (Body != IntPtr.Zero) | ||
789 | { | ||
790 | //Check that we have a Parent | ||
791 | //If we have a parent then we're not authorative here | ||
792 | if (_parent == null) | ||
793 | { | ||
794 | if (!m_taintAngularLock.IsIdentical(new PhysicsVector(1f,1f,1f), 0)) | ||
795 | { | ||
796 | //d.BodySetFiniteRotationMode(Body, 0); | ||
797 | //d.BodySetFiniteRotationAxis(Body,m_taintAngularLock.X,m_taintAngularLock.Y,m_taintAngularLock.Z); | ||
798 | createAMotor(m_taintAngularLock); | ||
799 | } | ||
800 | else | ||
801 | { | ||
802 | if (Amotor != IntPtr.Zero) | ||
803 | { | ||
804 | d.JointDestroy(Amotor); | ||
805 | Amotor = (IntPtr)0; | ||
806 | } | ||
807 | } | ||
808 | } | ||
809 | } | ||
810 | // Store this for later in case we get turned into a separate body | ||
811 | m_angularlock = new PhysicsVector(m_taintAngularLock.X,m_angularlock.Y,m_angularlock.Z); | ||
812 | } | ||
813 | |||
770 | private void changelink(float timestep) | 814 | private void changelink(float timestep) |
771 | { | 815 | { |
772 | 816 | ||
@@ -1241,6 +1285,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1241 | if (m_isphysical && Body != (IntPtr) 0) | 1285 | if (m_isphysical && Body != (IntPtr) 0) |
1242 | { | 1286 | { |
1243 | d.BodySetQuaternion(Body, ref myrot); | 1287 | d.BodySetQuaternion(Body, ref myrot); |
1288 | if (!m_angularlock.IsIdentical(new PhysicsVector(1, 1, 1), 0)) | ||
1289 | createAMotor(m_angularlock); | ||
1244 | } | 1290 | } |
1245 | 1291 | ||
1246 | resetCollisionAccounting(); | 1292 | resetCollisionAccounting(); |
@@ -1880,6 +1926,17 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1880 | m_taintparent = null; | 1926 | m_taintparent = null; |
1881 | } | 1927 | } |
1882 | 1928 | ||
1929 | |||
1930 | public override void LockAngularMotion(PhysicsVector axis) | ||
1931 | { | ||
1932 | // reverse the zero/non zero values for ODE. | ||
1933 | |||
1934 | axis.X = (axis.X > 0) ? 1f : 0f; | ||
1935 | axis.Y = (axis.Y > 0) ? 1f : 0f; | ||
1936 | axis.Z = (axis.Z > 0) ? 1f : 0f; | ||
1937 | m_taintAngularLock = new PhysicsVector(axis.X, axis.Y, axis.Z); ; | ||
1938 | } | ||
1939 | |||
1883 | public void UpdatePositionAndVelocity() | 1940 | public void UpdatePositionAndVelocity() |
1884 | { | 1941 | { |
1885 | // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! | 1942 | // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! |
@@ -2078,5 +2135,83 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2078 | public override PhysicsVector PIDTarget { set { m_PIDTarget = value; ; } } | 2135 | public override PhysicsVector PIDTarget { set { m_PIDTarget = value; ; } } |
2079 | public override bool PIDActive { set { m_usePID = value; } } | 2136 | public override bool PIDActive { set { m_usePID = value; } } |
2080 | public override float PIDTau { set { m_PIDTau = (value * 0.6f); } } | 2137 | public override float PIDTau { set { m_PIDTau = (value * 0.6f); } } |
2138 | |||
2139 | private void createAMotor(PhysicsVector axis) | ||
2140 | { | ||
2141 | if (Body == IntPtr.Zero) | ||
2142 | return; | ||
2143 | |||
2144 | if (Amotor != IntPtr.Zero) | ||
2145 | { | ||
2146 | d.JointDestroy(Amotor); | ||
2147 | Amotor = IntPtr.Zero; | ||
2148 | } | ||
2149 | |||
2150 | float m_tensor = 0f; | ||
2151 | if (Environment.OSVersion.Platform == PlatformID.Unix) | ||
2152 | { | ||
2153 | m_tensor = 2f; | ||
2154 | } | ||
2155 | else | ||
2156 | { | ||
2157 | m_tensor = 5f; | ||
2158 | } | ||
2159 | |||
2160 | float axisnum = 3; | ||
2161 | |||
2162 | axisnum = (axisnum - (axis.X + axis.Y + axis.Z)); | ||
2163 | |||
2164 | if (axisnum <= 0) | ||
2165 | return; | ||
2166 | int dAMotorEuler = 1; | ||
2167 | |||
2168 | Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero); | ||
2169 | d.JointAttach(Amotor, Body, IntPtr.Zero); | ||
2170 | d.JointSetAMotorMode(Amotor, dAMotorEuler); | ||
2171 | |||
2172 | |||
2173 | |||
2174 | d.JointSetAMotorNumAxes(Amotor,(int)axisnum); | ||
2175 | int i = 0; | ||
2176 | |||
2177 | if (axis.X == 0) | ||
2178 | { | ||
2179 | d.JointSetAMotorAxis(Amotor, i, 0, 1, 0, 0); | ||
2180 | i++; | ||
2181 | } | ||
2182 | |||
2183 | if (axis.Y == 0) | ||
2184 | { | ||
2185 | d.JointSetAMotorAxis(Amotor, i, 0, 0, 1, 0); | ||
2186 | i++; | ||
2187 | } | ||
2188 | |||
2189 | |||
2190 | if (axis.Z == 0) | ||
2191 | { | ||
2192 | d.JointSetAMotorAxis(Amotor, i, 0, 0, 0, 1); | ||
2193 | i++; | ||
2194 | } | ||
2195 | for (int j = 0; j < (int)axisnum; j++) | ||
2196 | { | ||
2197 | //d.JointSetAMotorAngle(Amotor, j, 0); | ||
2198 | } | ||
2199 | // | ||
2200 | //d.JointSetAMotorAngle(Amotor, 1, 0); | ||
2201 | //d.JointSetAMotorAngle(Amotor, 2, 0); | ||
2202 | |||
2203 | // These lowstops and high stops are effectively (no wiggle room) | ||
2204 | d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -0.000000000001f); | ||
2205 | d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0.000000000001f); | ||
2206 | d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -0.000000000001f); | ||
2207 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.000000000001f); | ||
2208 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0.000000000001f); | ||
2209 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.000000000001f); | ||
2210 | |||
2211 | |||
2212 | d.JointSetAMotorParam(Amotor, (int)dParam.FudgeFactor, 0f); | ||
2213 | d.JointSetAMotorParam(Amotor, (int)dParam.FMax, m_tensor); | ||
2214 | |||
2215 | } | ||
2081 | } | 2216 | } |
2082 | } | 2217 | } |