diff options
Diffstat (limited to 'OpenSim')
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs | 4 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs | 22 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs | 365 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | 131 |
4 files changed, 425 insertions, 97 deletions
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs index 9a22331..4266fda 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs | |||
@@ -137,7 +137,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
137 | public bool bad = false; | 137 | public bool bad = false; |
138 | 138 | ||
139 | float mu; | 139 | float mu; |
140 | float bounce; | ||
141 | 140 | ||
142 | public OdeCharacter(String avName, OdeScene parent_scene, Vector3 pos, Vector3 size, float pid_d, float pid_p, float capsule_radius, float density, float walk_divisor, float rundivisor) | 141 | public OdeCharacter(String avName, OdeScene parent_scene, Vector3 pos, Vector3 size, float pid_d, float pid_p, float capsule_radius, float density, float walk_divisor, float rundivisor) |
143 | { | 142 | { |
@@ -170,7 +169,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
170 | m_mass = 80f; // sure we have a default | 169 | m_mass = 80f; // sure we have a default |
171 | 170 | ||
172 | mu = parent_scene.AvatarFriction; | 171 | mu = parent_scene.AvatarFriction; |
173 | bounce = parent_scene.AvatarBounce; | ||
174 | 172 | ||
175 | walkDivisor = walk_divisor; | 173 | walkDivisor = walk_divisor; |
176 | runDivisor = rundivisor; | 174 | runDivisor = rundivisor; |
@@ -194,7 +192,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
194 | public override void getContactData(ref ContactData cdata) | 192 | public override void getContactData(ref ContactData cdata) |
195 | { | 193 | { |
196 | cdata.mu = mu; | 194 | cdata.mu = mu; |
197 | cdata.bounce = bounce; | 195 | cdata.bounce = 0; |
198 | cdata.softcolide = false; | 196 | cdata.softcolide = false; |
199 | } | 197 | } |
200 | 198 | ||
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs index d0b4546..dcd02e2 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs | |||
@@ -153,7 +153,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
153 | if (m_linearFrictionTimescale.Z < timestep) m_linearFrictionTimescale.Z = timestep; | 153 | if (m_linearFrictionTimescale.Z < timestep) m_linearFrictionTimescale.Z = timestep; |
154 | 154 | ||
155 | m_linearMotorDecayTimescale = vd.m_linearMotorDecayTimescale; | 155 | m_linearMotorDecayTimescale = vd.m_linearMotorDecayTimescale; |
156 | if (m_linearMotorDecayTimescale < 0.5f) m_linearMotorDecayTimescale = 0.5f; | 156 | if (m_linearMotorDecayTimescale < timestep) m_linearMotorDecayTimescale = timestep; |
157 | m_linearMotorDecayTimescale *= invtimestep; | 157 | m_linearMotorDecayTimescale *= invtimestep; |
158 | 158 | ||
159 | m_linearMotorTimescale = vd.m_linearMotorTimescale; | 159 | m_linearMotorTimescale = vd.m_linearMotorTimescale; |
@@ -168,7 +168,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
168 | if (m_angularMotorTimescale < timestep) m_angularMotorTimescale = timestep; | 168 | if (m_angularMotorTimescale < timestep) m_angularMotorTimescale = timestep; |
169 | 169 | ||
170 | m_angularMotorDecayTimescale = vd.m_angularMotorDecayTimescale; | 170 | m_angularMotorDecayTimescale = vd.m_angularMotorDecayTimescale; |
171 | if (m_angularMotorDecayTimescale < 0.5f) m_angularMotorDecayTimescale = 0.5f; | 171 | if (m_angularMotorDecayTimescale < timestep) m_angularMotorDecayTimescale = timestep; |
172 | m_angularMotorDecayTimescale *= invtimestep; | 172 | m_angularMotorDecayTimescale *= invtimestep; |
173 | 173 | ||
174 | m_angularFrictionTimescale = vd.m_angularFrictionTimescale; | 174 | m_angularFrictionTimescale = vd.m_angularFrictionTimescale; |
@@ -230,9 +230,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
230 | m_angularDeflectionTimescale = pValue; | 230 | m_angularDeflectionTimescale = pValue; |
231 | break; | 231 | break; |
232 | case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE: | 232 | case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE: |
233 | // if (pValue < timestep) pValue = timestep; | 233 | if (pValue < timestep) pValue = timestep; |
234 | // try to make impulses to work a bit better | 234 | // try to make impulses to work a bit better |
235 | if (pValue < 0.5f) pValue = 0.5f; | 235 | // if (pValue < 0.5f) pValue = 0.5f; |
236 | else if (pValue > 120) pValue = 120; | 236 | else if (pValue > 120) pValue = 120; |
237 | m_angularMotorDecayTimescale = pValue * invtimestep; | 237 | m_angularMotorDecayTimescale = pValue * invtimestep; |
238 | break; | 238 | break; |
@@ -281,9 +281,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
281 | m_linearDeflectionTimescale = pValue; | 281 | m_linearDeflectionTimescale = pValue; |
282 | break; | 282 | break; |
283 | case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE: | 283 | case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE: |
284 | // if (pValue < timestep) pValue = timestep; | 284 | if (pValue < timestep) pValue = timestep; |
285 | // try to make impulses to work a bit better | 285 | // try to make impulses to work a bit better |
286 | if (pValue < 0.5f) pValue = 0.5f; | 286 | //if (pValue < 0.5f) pValue = 0.5f; |
287 | else if (pValue > 120) pValue = 120; | 287 | else if (pValue > 120) pValue = 120; |
288 | m_linearMotorDecayTimescale = pValue * invtimestep; | 288 | m_linearMotorDecayTimescale = pValue * invtimestep; |
289 | break; | 289 | break; |
@@ -444,9 +444,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
444 | m_linearFrictionTimescale = new Vector3(1000, 1000, 1000); | 444 | m_linearFrictionTimescale = new Vector3(1000, 1000, 1000); |
445 | m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); | 445 | m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); |
446 | m_linearMotorTimescale = 1000; | 446 | m_linearMotorTimescale = 1000; |
447 | m_linearMotorDecayTimescale = 120; | 447 | m_linearMotorDecayTimescale = 120 * invtimestep; |
448 | m_angularMotorTimescale = 1000; | 448 | m_angularMotorTimescale = 1000; |
449 | m_angularMotorDecayTimescale = 1000; | 449 | m_angularMotorDecayTimescale = 1000 * invtimestep; |
450 | m_VhoverHeight = 0; | 450 | m_VhoverHeight = 0; |
451 | m_VhoverEfficiency = 1; | 451 | m_VhoverEfficiency = 1; |
452 | m_VhoverTimescale = 1000; | 452 | m_VhoverTimescale = 1000; |
@@ -901,7 +901,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
901 | GetRollPitch(irotq, out roll, out pitch); | 901 | GetRollPitch(irotq, out roll, out pitch); |
902 | 902 | ||
903 | float ftmp = 1.0f / m_verticalAttractionTimescale / m_verticalAttractionTimescale / _pParentScene.ODE_STEPSIZE; | 903 | float ftmp = 1.0f / m_verticalAttractionTimescale / m_verticalAttractionTimescale / _pParentScene.ODE_STEPSIZE; |
904 | float ftmp2 = m_verticalAttractionEfficiency / _pParentScene.ODE_STEPSIZE; | 904 | float ftmp2; |
905 | if (m_bankingEfficiency == 0) | ||
906 | ftmp2 = m_verticalAttractionEfficiency / _pParentScene.ODE_STEPSIZE; | ||
907 | else | ||
908 | ftmp2 = 0; | ||
905 | 909 | ||
906 | if (roll > halfpi) | 910 | if (roll > halfpi) |
907 | roll = pi - roll; | 911 | roll = pi - roll; |
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs index 71aec4c..c4dc793 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs | |||
@@ -70,6 +70,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
70 | private bool m_fakeisphantom; | 70 | private bool m_fakeisphantom; |
71 | 71 | ||
72 | protected bool m_building; | 72 | protected bool m_building; |
73 | protected bool m_forcePosOrRotation; | ||
74 | |||
73 | private Quaternion m_lastorientation = new Quaternion(); | 75 | private Quaternion m_lastorientation = new Quaternion(); |
74 | private Quaternion _orientation; | 76 | private Quaternion _orientation; |
75 | 77 | ||
@@ -128,9 +130,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
128 | 130 | ||
129 | public bool m_disabled; | 131 | public bool m_disabled; |
130 | 132 | ||
131 | |||
132 | public uint m_localID; | 133 | public uint m_localID; |
133 | 134 | ||
135 | private IMesh m_mesh; | ||
136 | private object m_meshlock = new object(); | ||
134 | private PrimitiveBaseShape _pbs; | 137 | private PrimitiveBaseShape _pbs; |
135 | public OdeScene _parent_scene; | 138 | public OdeScene _parent_scene; |
136 | 139 | ||
@@ -482,6 +485,24 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
482 | { | 485 | { |
483 | set | 486 | set |
484 | { | 487 | { |
488 | /* | ||
489 | IMesh mesh = null; | ||
490 | if (_parent_scene.needsMeshing(value)) | ||
491 | { | ||
492 | bool convex; | ||
493 | if (m_shapetype == 0) | ||
494 | convex = false; | ||
495 | else | ||
496 | convex = true; | ||
497 | mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, (int)LevelOfDetail.High, true, convex); | ||
498 | } | ||
499 | |||
500 | if (mesh != null) | ||
501 | { | ||
502 | lock (m_meshlock) | ||
503 | m_mesh = mesh; | ||
504 | } | ||
505 | */ | ||
485 | AddChange(changes.Shape, value); | 506 | AddChange(changes.Shape, value); |
486 | } | 507 | } |
487 | } | 508 | } |
@@ -497,7 +518,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
497 | m_shapetype = value; | 518 | m_shapetype = value; |
498 | AddChange(changes.Shape, null); | 519 | AddChange(changes.Shape, null); |
499 | } | 520 | } |
500 | } | 521 | } |
522 | |||
501 | 523 | ||
502 | public override Vector3 Velocity | 524 | public override Vector3 Velocity |
503 | { | 525 | { |
@@ -947,6 +969,19 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
947 | 969 | ||
948 | CalcPrimBodyData(); | 970 | CalcPrimBodyData(); |
949 | 971 | ||
972 | m_mesh = null; | ||
973 | if (_parent_scene.needsMeshing(pbs)) | ||
974 | { | ||
975 | bool convex; | ||
976 | if (m_shapetype == 0) | ||
977 | convex = false; | ||
978 | else | ||
979 | convex = true; | ||
980 | |||
981 | m_mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, (int)LevelOfDetail.High, true, convex); | ||
982 | } | ||
983 | |||
984 | |||
950 | m_building = true; // control must set this to false when done | 985 | m_building = true; // control must set this to false when done |
951 | 986 | ||
952 | AddChange(changes.Add, null); | 987 | AddChange(changes.Add, null); |
@@ -1049,6 +1084,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1049 | 1084 | ||
1050 | private bool setMesh(OdeScene parent_scene) | 1085 | private bool setMesh(OdeScene parent_scene) |
1051 | { | 1086 | { |
1087 | IntPtr vertices, indices; | ||
1088 | int vertexCount, indexCount; | ||
1089 | int vertexStride, triStride; | ||
1090 | |||
1052 | if (Body != IntPtr.Zero) | 1091 | if (Body != IntPtr.Zero) |
1053 | { | 1092 | { |
1054 | if (childPrim) | 1093 | if (childPrim) |
@@ -1065,38 +1104,50 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1065 | } | 1104 | } |
1066 | } | 1105 | } |
1067 | 1106 | ||
1068 | bool convex; | 1107 | IMesh mesh = null; |
1069 | if (m_shapetype == 0) | 1108 | |
1070 | convex = false; | ||
1071 | else | ||
1072 | convex = true; | ||
1073 | 1109 | ||
1074 | IMesh mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, (int)LevelOfDetail.High, true,convex); | 1110 | lock (m_meshlock) |
1075 | if (mesh == null) | ||
1076 | { | 1111 | { |
1077 | m_log.WarnFormat("[PHYSICS]: CreateMesh Failed on prim {0} at <{1},{2},{3}>.", Name, _position.X, _position.Y, _position.Z); | 1112 | if (m_mesh == null) |
1078 | return false; | 1113 | { |
1079 | } | 1114 | bool convex; |
1115 | if (m_shapetype == 0) | ||
1116 | convex = false; | ||
1117 | else | ||
1118 | convex = true; | ||
1080 | 1119 | ||
1081 | IntPtr vertices, indices; | 1120 | mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, (int)LevelOfDetail.High, true, convex); |
1082 | int vertexCount, indexCount; | 1121 | } |
1083 | int vertexStride, triStride; | 1122 | else |
1123 | { | ||
1124 | mesh = m_mesh; | ||
1125 | } | ||
1084 | 1126 | ||
1085 | mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap | 1127 | if (mesh == null) |
1086 | mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage | 1128 | { |
1129 | m_log.WarnFormat("[PHYSICS]: CreateMesh Failed on prim {0} at <{1},{2},{3}>.", Name, _position.X, _position.Y, _position.Z); | ||
1130 | return false; | ||
1131 | } | ||
1087 | 1132 | ||
1088 | if (vertexCount == 0 || indexCount == 0) | ||
1089 | { | ||
1090 | m_log.WarnFormat("[PHYSICS]: Got invalid mesh on prim {0} at <{1},{2},{3}>. mesh UUID {4}", | ||
1091 | Name, _position.X, _position.Y, _position.Z, _pbs.SculptTexture.ToString()); | ||
1092 | mesh.releaseSourceMeshData(); | ||
1093 | return false; | ||
1094 | } | ||
1095 | 1133 | ||
1096 | primOOBoffset = mesh.GetCentroid(); | 1134 | mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap |
1097 | hasOOBoffsetFromMesh = true; | 1135 | mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage |
1098 | 1136 | ||
1099 | mesh.releaseSourceMeshData(); | 1137 | if (vertexCount == 0 || indexCount == 0) |
1138 | { | ||
1139 | m_log.WarnFormat("[PHYSICS]: Got invalid mesh on prim {0} at <{1},{2},{3}>. mesh UUID {4}", | ||
1140 | Name, _position.X, _position.Y, _position.Z, _pbs.SculptTexture.ToString()); | ||
1141 | mesh.releaseSourceMeshData(); | ||
1142 | return false; | ||
1143 | } | ||
1144 | |||
1145 | primOOBoffset = mesh.GetCentroid(); | ||
1146 | hasOOBoffsetFromMesh = true; | ||
1147 | |||
1148 | mesh.releaseSourceMeshData(); | ||
1149 | m_mesh = null; | ||
1150 | } | ||
1100 | 1151 | ||
1101 | IntPtr geo = IntPtr.Zero; | 1152 | IntPtr geo = IntPtr.Zero; |
1102 | 1153 | ||
@@ -1429,7 +1480,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1429 | d.RfromQ(out mymat, ref myrot); | 1480 | d.RfromQ(out mymat, ref myrot); |
1430 | d.MassRotate(ref objdmass, ref mymat); | 1481 | d.MassRotate(ref objdmass, ref mymat); |
1431 | 1482 | ||
1432 | // set the body rotation and position | 1483 | // set the body rotation |
1433 | d.BodySetRotation(Body, ref mymat); | 1484 | d.BodySetRotation(Body, ref mymat); |
1434 | 1485 | ||
1435 | // recompute full object inertia if needed | 1486 | // recompute full object inertia if needed |
@@ -1725,6 +1776,215 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1725 | m_collisionscore = 0; | 1776 | m_collisionscore = 0; |
1726 | } | 1777 | } |
1727 | 1778 | ||
1779 | private void FixInertia(Vector3 NewPos,Quaternion newrot) | ||
1780 | { | ||
1781 | d.Matrix3 mat = new d.Matrix3(); | ||
1782 | d.Quaternion quat = new d.Quaternion(); | ||
1783 | |||
1784 | d.Mass tmpdmass = new d.Mass { }; | ||
1785 | d.Mass objdmass = new d.Mass { }; | ||
1786 | |||
1787 | d.BodyGetMass(Body, out tmpdmass); | ||
1788 | objdmass = tmpdmass; | ||
1789 | |||
1790 | d.Vector3 dobjpos; | ||
1791 | d.Vector3 thispos; | ||
1792 | |||
1793 | // get current object position and rotation | ||
1794 | dobjpos = d.BodyGetPosition(Body); | ||
1795 | |||
1796 | // get prim own inertia in its local frame | ||
1797 | tmpdmass = primdMass; | ||
1798 | |||
1799 | // transform to object frame | ||
1800 | mat = d.GeomGetOffsetRotation(prim_geom); | ||
1801 | d.MassRotate(ref tmpdmass, ref mat); | ||
1802 | |||
1803 | thispos = d.GeomGetOffsetPosition(prim_geom); | ||
1804 | d.MassTranslate(ref tmpdmass, | ||
1805 | thispos.X, | ||
1806 | thispos.Y, | ||
1807 | thispos.Z); | ||
1808 | |||
1809 | // subtract current prim inertia from object | ||
1810 | DMassSubPartFromObj(ref tmpdmass, ref objdmass); | ||
1811 | |||
1812 | // back prim own inertia | ||
1813 | tmpdmass = primdMass; | ||
1814 | |||
1815 | // update to new position and orientation | ||
1816 | _position = NewPos; | ||
1817 | d.GeomSetOffsetWorldPosition(prim_geom, NewPos.X, NewPos.Y, NewPos.Z); | ||
1818 | _orientation = newrot; | ||
1819 | quat.X = newrot.X; | ||
1820 | quat.Y = newrot.Y; | ||
1821 | quat.Z = newrot.Z; | ||
1822 | quat.W = newrot.W; | ||
1823 | d.GeomSetOffsetWorldQuaternion(prim_geom, ref quat); | ||
1824 | |||
1825 | mat = d.GeomGetOffsetRotation(prim_geom); | ||
1826 | d.MassRotate(ref tmpdmass, ref mat); | ||
1827 | |||
1828 | thispos = d.GeomGetOffsetPosition(prim_geom); | ||
1829 | d.MassTranslate(ref tmpdmass, | ||
1830 | thispos.X, | ||
1831 | thispos.Y, | ||
1832 | thispos.Z); | ||
1833 | |||
1834 | d.MassAdd(ref objdmass, ref tmpdmass); | ||
1835 | |||
1836 | // fix all positions | ||
1837 | IntPtr g = d.BodyGetFirstGeom(Body); | ||
1838 | while (g != IntPtr.Zero) | ||
1839 | { | ||
1840 | thispos = d.GeomGetOffsetPosition(g); | ||
1841 | thispos.X -= objdmass.c.X; | ||
1842 | thispos.Y -= objdmass.c.Y; | ||
1843 | thispos.Z -= objdmass.c.Z; | ||
1844 | d.GeomSetOffsetPosition(g, thispos.X, thispos.Y, thispos.Z); | ||
1845 | g = d.dBodyGetNextGeom(g); | ||
1846 | } | ||
1847 | d.BodyVectorToWorld(Body,objdmass.c.X, objdmass.c.Y, objdmass.c.Z,out thispos); | ||
1848 | |||
1849 | d.BodySetPosition(Body, dobjpos.X + thispos.X, dobjpos.Y + thispos.Y, dobjpos.Z + thispos.Z); | ||
1850 | d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body | ||
1851 | d.BodySetMass(Body, ref objdmass); | ||
1852 | _mass = objdmass.mass; | ||
1853 | } | ||
1854 | |||
1855 | |||
1856 | |||
1857 | private void FixInertia(Vector3 NewPos) | ||
1858 | { | ||
1859 | d.Matrix3 primmat = new d.Matrix3(); | ||
1860 | d.Mass tmpdmass = new d.Mass { }; | ||
1861 | d.Mass objdmass = new d.Mass { }; | ||
1862 | d.Mass primmass = new d.Mass { }; | ||
1863 | |||
1864 | d.Vector3 dobjpos; | ||
1865 | d.Vector3 thispos; | ||
1866 | |||
1867 | d.BodyGetMass(Body, out objdmass); | ||
1868 | |||
1869 | // get prim own inertia in its local frame | ||
1870 | primmass = primdMass; | ||
1871 | // transform to object frame | ||
1872 | primmat = d.GeomGetOffsetRotation(prim_geom); | ||
1873 | d.MassRotate(ref primmass, ref primmat); | ||
1874 | |||
1875 | tmpdmass = primmass; | ||
1876 | |||
1877 | thispos = d.GeomGetOffsetPosition(prim_geom); | ||
1878 | d.MassTranslate(ref tmpdmass, | ||
1879 | thispos.X, | ||
1880 | thispos.Y, | ||
1881 | thispos.Z); | ||
1882 | |||
1883 | // subtract current prim inertia from object | ||
1884 | DMassSubPartFromObj(ref tmpdmass, ref objdmass); | ||
1885 | |||
1886 | // update to new position | ||
1887 | _position = NewPos; | ||
1888 | d.GeomSetOffsetWorldPosition(prim_geom, NewPos.X, NewPos.Y, NewPos.Z); | ||
1889 | |||
1890 | thispos = d.GeomGetOffsetPosition(prim_geom); | ||
1891 | d.MassTranslate(ref primmass, | ||
1892 | thispos.X, | ||
1893 | thispos.Y, | ||
1894 | thispos.Z); | ||
1895 | |||
1896 | d.MassAdd(ref objdmass, ref primmass); | ||
1897 | |||
1898 | // fix all positions | ||
1899 | IntPtr g = d.BodyGetFirstGeom(Body); | ||
1900 | while (g != IntPtr.Zero) | ||
1901 | { | ||
1902 | thispos = d.GeomGetOffsetPosition(g); | ||
1903 | thispos.X -= objdmass.c.X; | ||
1904 | thispos.Y -= objdmass.c.Y; | ||
1905 | thispos.Z -= objdmass.c.Z; | ||
1906 | d.GeomSetOffsetPosition(g, thispos.X, thispos.Y, thispos.Z); | ||
1907 | g = d.dBodyGetNextGeom(g); | ||
1908 | } | ||
1909 | |||
1910 | d.BodyVectorToWorld(Body, objdmass.c.X, objdmass.c.Y, objdmass.c.Z, out thispos); | ||
1911 | |||
1912 | // get current object position and rotation | ||
1913 | dobjpos = d.BodyGetPosition(Body); | ||
1914 | |||
1915 | d.BodySetPosition(Body, dobjpos.X + thispos.X, dobjpos.Y + thispos.Y, dobjpos.Z + thispos.Z); | ||
1916 | d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body | ||
1917 | d.BodySetMass(Body, ref objdmass); | ||
1918 | _mass = objdmass.mass; | ||
1919 | } | ||
1920 | |||
1921 | private void FixInertia(Quaternion newrot) | ||
1922 | { | ||
1923 | d.Matrix3 mat = new d.Matrix3(); | ||
1924 | d.Quaternion quat = new d.Quaternion(); | ||
1925 | |||
1926 | d.Mass tmpdmass = new d.Mass { }; | ||
1927 | d.Mass objdmass = new d.Mass { }; | ||
1928 | d.Vector3 dobjpos; | ||
1929 | d.Vector3 thispos; | ||
1930 | |||
1931 | d.BodyGetMass(Body, out objdmass); | ||
1932 | |||
1933 | // get prim own inertia in its local frame | ||
1934 | tmpdmass = primdMass; | ||
1935 | mat = d.GeomGetOffsetRotation(prim_geom); | ||
1936 | d.MassRotate(ref tmpdmass, ref mat); | ||
1937 | // transform to object frame | ||
1938 | thispos = d.GeomGetOffsetPosition(prim_geom); | ||
1939 | d.MassTranslate(ref tmpdmass, | ||
1940 | thispos.X, | ||
1941 | thispos.Y, | ||
1942 | thispos.Z); | ||
1943 | |||
1944 | // subtract current prim inertia from object | ||
1945 | DMassSubPartFromObj(ref tmpdmass, ref objdmass); | ||
1946 | |||
1947 | // update to new orientation | ||
1948 | _orientation = newrot; | ||
1949 | quat.X = newrot.X; | ||
1950 | quat.Y = newrot.Y; | ||
1951 | quat.Z = newrot.Z; | ||
1952 | quat.W = newrot.W; | ||
1953 | d.GeomSetOffsetWorldQuaternion(prim_geom, ref quat); | ||
1954 | |||
1955 | tmpdmass = primdMass; | ||
1956 | mat = d.GeomGetOffsetRotation(prim_geom); | ||
1957 | d.MassRotate(ref tmpdmass, ref mat); | ||
1958 | d.MassTranslate(ref tmpdmass, | ||
1959 | thispos.X, | ||
1960 | thispos.Y, | ||
1961 | thispos.Z); | ||
1962 | |||
1963 | d.MassAdd(ref objdmass, ref tmpdmass); | ||
1964 | |||
1965 | // fix all positions | ||
1966 | IntPtr g = d.BodyGetFirstGeom(Body); | ||
1967 | while (g != IntPtr.Zero) | ||
1968 | { | ||
1969 | thispos = d.GeomGetOffsetPosition(g); | ||
1970 | thispos.X -= objdmass.c.X; | ||
1971 | thispos.Y -= objdmass.c.Y; | ||
1972 | thispos.Z -= objdmass.c.Z; | ||
1973 | d.GeomSetOffsetPosition(g, thispos.X, thispos.Y, thispos.Z); | ||
1974 | g = d.dBodyGetNextGeom(g); | ||
1975 | } | ||
1976 | |||
1977 | d.BodyVectorToWorld(Body, objdmass.c.X, objdmass.c.Y, objdmass.c.Z, out thispos); | ||
1978 | // get current object position and rotation | ||
1979 | dobjpos = d.BodyGetPosition(Body); | ||
1980 | |||
1981 | d.BodySetPosition(Body, dobjpos.X + thispos.X, dobjpos.Y + thispos.Y, dobjpos.Z + thispos.Z); | ||
1982 | d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body | ||
1983 | d.BodySetMass(Body, ref objdmass); | ||
1984 | _mass = objdmass.mass; | ||
1985 | } | ||
1986 | |||
1987 | |||
1728 | #region Mass Calculation | 1988 | #region Mass Calculation |
1729 | 1989 | ||
1730 | private float CalculatePrimVolume() | 1990 | private float CalculatePrimVolume() |
@@ -2126,17 +2386,18 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2126 | { | 2386 | { |
2127 | if (prim_geom != IntPtr.Zero) | 2387 | if (prim_geom != IntPtr.Zero) |
2128 | { | 2388 | { |
2129 | d.Vector3 lpos; | ||
2130 | d.GeomCopyPosition(prim_geom, out lpos); | ||
2131 | _position.X = lpos.X; | ||
2132 | _position.Y = lpos.Y; | ||
2133 | _position.Z = lpos.Z; | ||
2134 | d.Quaternion qtmp = new d.Quaternion { }; | 2389 | d.Quaternion qtmp = new d.Quaternion { }; |
2135 | d.GeomCopyQuaternion(prim_geom, out qtmp); | 2390 | d.GeomCopyQuaternion(prim_geom, out qtmp); |
2136 | _orientation.W = qtmp.W; | 2391 | _orientation.W = qtmp.W; |
2137 | _orientation.X = qtmp.X; | 2392 | _orientation.X = qtmp.X; |
2138 | _orientation.Y = qtmp.Y; | 2393 | _orientation.Y = qtmp.Y; |
2139 | _orientation.Z = qtmp.Z; | 2394 | _orientation.Z = qtmp.Z; |
2395 | |||
2396 | d.Vector3 lpos; | ||
2397 | d.GeomCopyPosition(prim_geom, out lpos); | ||
2398 | _position.X = lpos.X; | ||
2399 | _position.Y = lpos.Y; | ||
2400 | _position.Z = lpos.Z; | ||
2140 | } | 2401 | } |
2141 | } | 2402 | } |
2142 | 2403 | ||
@@ -2593,6 +2854,13 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2593 | { | 2854 | { |
2594 | _position = newPos; | 2855 | _position = newPos; |
2595 | } | 2856 | } |
2857 | |||
2858 | else if (m_forcePosOrRotation && _position != newPos && Body != IntPtr.Zero) | ||
2859 | { | ||
2860 | FixInertia(newPos); | ||
2861 | if (!d.BodyIsEnabled(Body)) | ||
2862 | d.BodyEnable(Body); | ||
2863 | } | ||
2596 | } | 2864 | } |
2597 | else | 2865 | else |
2598 | { | 2866 | { |
@@ -2637,6 +2905,14 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2637 | { | 2905 | { |
2638 | _orientation = newOri; | 2906 | _orientation = newOri; |
2639 | } | 2907 | } |
2908 | /* | ||
2909 | else if (m_forcePosOrRotation && _orientation != newOri && Body != IntPtr.Zero) | ||
2910 | { | ||
2911 | FixInertia(_position, newOri); | ||
2912 | if (!d.BodyIsEnabled(Body)) | ||
2913 | d.BodyEnable(Body); | ||
2914 | } | ||
2915 | */ | ||
2640 | } | 2916 | } |
2641 | else | 2917 | else |
2642 | { | 2918 | { |
@@ -3512,6 +3788,29 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3512 | dst.I.M22 = src.I.M22; | 3788 | dst.I.M22 = src.I.M22; |
3513 | } | 3789 | } |
3514 | 3790 | ||
3791 | internal static void DMassSubPartFromObj(ref d.Mass part, ref d.Mass theobj) | ||
3792 | { | ||
3793 | // assumes object center of mass is zero | ||
3794 | float smass = part.mass; | ||
3795 | theobj.mass -= smass; | ||
3796 | |||
3797 | smass *= 1.0f / (theobj.mass); ; | ||
3798 | |||
3799 | theobj.c.X -= part.c.X * smass; | ||
3800 | theobj.c.Y -= part.c.Y * smass; | ||
3801 | theobj.c.Z -= part.c.Z * smass; | ||
3802 | |||
3803 | theobj.I.M00 -= part.I.M00; | ||
3804 | theobj.I.M01 -= part.I.M01; | ||
3805 | theobj.I.M02 -= part.I.M02; | ||
3806 | theobj.I.M10 -= part.I.M10; | ||
3807 | theobj.I.M11 -= part.I.M11; | ||
3808 | theobj.I.M12 -= part.I.M12; | ||
3809 | theobj.I.M20 -= part.I.M20; | ||
3810 | theobj.I.M21 -= part.I.M21; | ||
3811 | theobj.I.M22 -= part.I.M22; | ||
3812 | } | ||
3813 | |||
3515 | private static void DMassDup(ref d.Mass src, out d.Mass dst) | 3814 | private static void DMassDup(ref d.Mass src, out d.Mass dst) |
3516 | { | 3815 | { |
3517 | dst = new d.Mass { }; | 3816 | dst = new d.Mass { }; |
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index 76d7746..1a6907d 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | |||
@@ -160,8 +160,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
160 | private Random fluidRandomizer = new Random(Environment.TickCount); | 160 | private Random fluidRandomizer = new Random(Environment.TickCount); |
161 | 161 | ||
162 | const d.ContactFlags comumContactFlags = d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM |d.ContactFlags.Approx1 | d.ContactFlags.Bounce; | 162 | const d.ContactFlags comumContactFlags = d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM |d.ContactFlags.Approx1 | d.ContactFlags.Bounce; |
163 | const float comumContactERP = 0.6f; | 163 | const float MaxERP = 0.8f; |
164 | const float comumSoftContactERP = 0.1f; | 164 | const float minERP = 0.1f; |
165 | const float comumContactCFM = 0.0001f; | 165 | const float comumContactCFM = 0.0001f; |
166 | 166 | ||
167 | float frictionMovementMult = 0.3f; | 167 | float frictionMovementMult = 0.3f; |
@@ -169,7 +169,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
169 | float TerrainBounce = 0.1f; | 169 | float TerrainBounce = 0.1f; |
170 | float TerrainFriction = 0.3f; | 170 | float TerrainFriction = 0.3f; |
171 | 171 | ||
172 | public float AvatarBounce = 0.3f; | ||
173 | public float AvatarFriction = 0;// 0.9f * 0.5f; | 172 | public float AvatarFriction = 0;// 0.9f * 0.5f; |
174 | 173 | ||
175 | private const uint m_regionWidth = Constants.RegionSize; | 174 | private const uint m_regionWidth = Constants.RegionSize; |
@@ -528,7 +527,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
528 | 527 | ||
529 | // sets a global contact for a joint for contactgeom , and base contact description) | 528 | // sets a global contact for a joint for contactgeom , and base contact description) |
530 | 529 | ||
531 | private IntPtr CreateContacJoint(ref d.ContactGeom contactGeom, float mu, float bounce, bool softerp) | 530 | private IntPtr CreateContacJoint(ref d.ContactGeom contactGeom, float mu, float bounce,float cfm,float erp) |
532 | { | 531 | { |
533 | if (GlobalContactsArray == IntPtr.Zero || m_global_contactcount >= maxContactsbeforedeath) | 532 | if (GlobalContactsArray == IntPtr.Zero || m_global_contactcount >= maxContactsbeforedeath) |
534 | return IntPtr.Zero; | 533 | return IntPtr.Zero; |
@@ -546,11 +545,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
546 | newcontact.surface.mode = comumContactFlags; | 545 | newcontact.surface.mode = comumContactFlags; |
547 | newcontact.surface.mu = mu; | 546 | newcontact.surface.mu = mu; |
548 | newcontact.surface.bounce = bounce; | 547 | newcontact.surface.bounce = bounce; |
549 | newcontact.surface.soft_cfm = comumContactCFM; | 548 | newcontact.surface.soft_cfm = cfm; |
550 | if (softerp) | 549 | newcontact.surface.soft_erp = erp; |
551 | newcontact.surface.soft_erp = comumSoftContactERP; | ||
552 | else | ||
553 | newcontact.surface.soft_erp = comumContactERP; | ||
554 | 550 | ||
555 | IntPtr contact = new IntPtr(GlobalContactsArray.ToInt64() + (Int64)(m_global_contactcount * d.Contact.unmanagedSizeOf)); | 551 | IntPtr contact = new IntPtr(GlobalContactsArray.ToInt64() + (Int64)(m_global_contactcount * d.Contact.unmanagedSizeOf)); |
556 | Marshal.StructureToPtr(newcontact, contact, true); | 552 | Marshal.StructureToPtr(newcontact, contact, true); |
@@ -694,9 +690,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
694 | // big messy collision analises | 690 | // big messy collision analises |
695 | float mu = 0; | 691 | float mu = 0; |
696 | float bounce = 0; | 692 | float bounce = 0; |
693 | float cfm = 0.0001f; | ||
694 | float erp = 0.1f; | ||
695 | |||
697 | ContactData contactdata1 = new ContactData(0, 0, false); | 696 | ContactData contactdata1 = new ContactData(0, 0, false); |
698 | ContactData contactdata2 = new ContactData(0, 0, false); | 697 | ContactData contactdata2 = new ContactData(0, 0, false); |
699 | bool erpSoft = false; | ||
700 | 698 | ||
701 | String name = null; | 699 | String name = null; |
702 | bool dop1foot = false; | 700 | bool dop1foot = false; |
@@ -706,59 +704,65 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
706 | switch (p1.PhysicsActorType) | 704 | switch (p1.PhysicsActorType) |
707 | { | 705 | { |
708 | case (int)ActorTypes.Agent: | 706 | case (int)ActorTypes.Agent: |
709 | switch (p2.PhysicsActorType) | ||
710 | { | 707 | { |
711 | case (int)ActorTypes.Agent: | 708 | bounce = 0; |
712 | p1.getContactData(ref contactdata1); | 709 | mu = 0; |
713 | p2.getContactData(ref contactdata2); | 710 | cfm = 0.0001f; |
714 | |||
715 | bounce = contactdata1.bounce * contactdata2.bounce; | ||
716 | |||
717 | mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); | ||
718 | 711 | ||
719 | if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f)) | 712 | switch (p2.PhysicsActorType) |
720 | mu *= frictionMovementMult; | 713 | { |
714 | case (int)ActorTypes.Agent: | ||
715 | /* | ||
716 | p1.getContactData(ref contactdata1); | ||
717 | p2.getContactData(ref contactdata2); | ||
721 | 718 | ||
722 | erpSoft = contactdata1.softcolide | contactdata2.softcolide; | 719 | mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); |
723 | p1.CollidingObj = true; | ||
724 | p2.CollidingObj = true; | ||
725 | break; | ||
726 | case (int)ActorTypes.Prim: | ||
727 | p1.getContactData(ref contactdata1); | ||
728 | p2.getContactData(ref contactdata2); | ||
729 | bounce = contactdata1.bounce * contactdata2.bounce; | ||
730 | |||
731 | mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); | ||
732 | 720 | ||
733 | if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f)) | 721 | if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f)) |
734 | mu *= frictionMovementMult; | 722 | mu *= frictionMovementMult; |
735 | if (p2.Velocity.LengthSquared() > 0.0f) | 723 | */ |
724 | p1.CollidingObj = true; | ||
736 | p2.CollidingObj = true; | 725 | p2.CollidingObj = true; |
726 | break; | ||
727 | case (int)ActorTypes.Prim: | ||
728 | /* | ||
729 | p1.getContactData(ref contactdata1); | ||
730 | p2.getContactData(ref contactdata2); | ||
737 | 731 | ||
738 | erpSoft = contactdata1.softcolide | contactdata2.softcolide; | ||
739 | 732 | ||
740 | dop1foot = true; | 733 | mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); |
741 | break; | 734 | |
742 | default: | 735 | if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f)) |
743 | ignore=true; // avatar to terrain and water ignored | 736 | mu *= frictionMovementMult; |
744 | break; | 737 | */ |
738 | if (p2.Velocity.LengthSquared() > 0.0f) | ||
739 | p2.CollidingObj = true; | ||
740 | |||
741 | dop1foot = true; | ||
742 | break; | ||
743 | default: | ||
744 | ignore = true; // avatar to terrain and water ignored | ||
745 | break; | ||
746 | } | ||
747 | break; | ||
745 | } | 748 | } |
746 | break; | ||
747 | 749 | ||
748 | case (int)ActorTypes.Prim: | 750 | case (int)ActorTypes.Prim: |
749 | switch (p2.PhysicsActorType) | 751 | switch (p2.PhysicsActorType) |
750 | { | 752 | { |
751 | case (int)ActorTypes.Agent: | 753 | case (int)ActorTypes.Agent: |
752 | p1.getContactData(ref contactdata1); | 754 | // p1.getContactData(ref contactdata1); |
753 | p2.getContactData(ref contactdata2); | 755 | // p2.getContactData(ref contactdata2); |
754 | bounce = contactdata1.bounce * contactdata2.bounce; | 756 | |
755 | 757 | bounce = 0; | |
758 | mu = 0; | ||
759 | cfm = 0.0001f; | ||
760 | /* | ||
756 | mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); | 761 | mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); |
757 | 762 | ||
758 | if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f)) | 763 | if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f)) |
759 | mu *= frictionMovementMult; | 764 | mu *= frictionMovementMult; |
760 | 765 | */ | |
761 | erpSoft = contactdata1.softcolide | contactdata2.softcolide; | ||
762 | dop2foot = true; | 766 | dop2foot = true; |
763 | if (p1.Velocity.LengthSquared() > 0.0f) | 767 | if (p1.Velocity.LengthSquared() > 0.0f) |
764 | p1.CollidingObj = true; | 768 | p1.CollidingObj = true; |
@@ -772,9 +776,16 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
772 | p1.getContactData(ref contactdata1); | 776 | p1.getContactData(ref contactdata1); |
773 | p2.getContactData(ref contactdata2); | 777 | p2.getContactData(ref contactdata2); |
774 | bounce = contactdata1.bounce * contactdata2.bounce; | 778 | bounce = contactdata1.bounce * contactdata2.bounce; |
775 | erpSoft = contactdata1.softcolide | contactdata2.softcolide; | ||
776 | mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); | 779 | mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); |
777 | 780 | ||
781 | cfm = p1.Mass; | ||
782 | if (cfm > p2.Mass) | ||
783 | cfm = p2.Mass; | ||
784 | cfm = (float)Math.Sqrt(cfm); | ||
785 | cfm *= 0.0001f; | ||
786 | if (cfm > 0.8f) | ||
787 | cfm = 0.8f; | ||
788 | |||
778 | if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f)) | 789 | if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f)) |
779 | mu *= frictionMovementMult; | 790 | mu *= frictionMovementMult; |
780 | 791 | ||
@@ -789,12 +800,17 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
789 | mu = (float)Math.Sqrt(contactdata1.mu * TerrainFriction); | 800 | mu = (float)Math.Sqrt(contactdata1.mu * TerrainFriction); |
790 | if (Math.Abs(p1.Velocity.X) > 0.1f || Math.Abs(p1.Velocity.Y) > 0.1f) | 801 | if (Math.Abs(p1.Velocity.X) > 0.1f || Math.Abs(p1.Velocity.Y) > 0.1f) |
791 | mu *= frictionMovementMult; | 802 | mu *= frictionMovementMult; |
792 | erpSoft = contactdata1.softcolide; | ||
793 | p1.CollidingGround = true; | 803 | p1.CollidingGround = true; |
804 | cfm = p1.Mass; | ||
805 | cfm = (float)Math.Sqrt(cfm); | ||
806 | cfm *= 0.0001f; | ||
807 | if (cfm > 0.8f) | ||
808 | cfm = 0.8f; | ||
809 | |||
794 | } | 810 | } |
795 | else if (name == "Water") | 811 | else if (name == "Water") |
796 | { | 812 | { |
797 | erpSoft = true; | 813 | ignore = true; |
798 | } | 814 | } |
799 | } | 815 | } |
800 | else | 816 | else |
@@ -814,7 +830,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
814 | p2.getContactData(ref contactdata2); | 830 | p2.getContactData(ref contactdata2); |
815 | bounce = contactdata2.bounce * TerrainBounce; | 831 | bounce = contactdata2.bounce * TerrainBounce; |
816 | mu = (float)Math.Sqrt(contactdata2.mu * TerrainFriction); | 832 | mu = (float)Math.Sqrt(contactdata2.mu * TerrainFriction); |
817 | erpSoft = contactdata2.softcolide; | 833 | cfm = p2.Mass; |
834 | cfm = (float)Math.Sqrt(cfm); | ||
835 | cfm *= 0.0001f; | ||
836 | if (cfm > 0.8f) | ||
837 | cfm = 0.8f; | ||
818 | 838 | ||
819 | if (Math.Abs(p2.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y) > 0.1f) | 839 | if (Math.Abs(p2.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y) > 0.1f) |
820 | mu *= frictionMovementMult; | 840 | mu *= frictionMovementMult; |
@@ -826,7 +846,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
826 | else if (name == "Water" && | 846 | else if (name == "Water" && |
827 | (p2.PhysicsActorType == (int)ActorTypes.Prim || p2.PhysicsActorType == (int)ActorTypes.Agent)) | 847 | (p2.PhysicsActorType == (int)ActorTypes.Prim || p2.PhysicsActorType == (int)ActorTypes.Agent)) |
828 | { | 848 | { |
829 | erpSoft = true; | 849 | ignore = true; |
830 | } | 850 | } |
831 | } | 851 | } |
832 | else | 852 | else |
@@ -847,7 +867,14 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
847 | if (dop2foot && (p2.Position.Z - curContact.pos.Z) > (p2.Size.Z - avCapRadius) * 0.5f) | 867 | if (dop2foot && (p2.Position.Z - curContact.pos.Z) > (p2.Size.Z - avCapRadius) * 0.5f) |
848 | p2.IsColliding = true; | 868 | p2.IsColliding = true; |
849 | 869 | ||
850 | Joint = CreateContacJoint(ref curContact, mu, bounce, erpSoft); | 870 | |
871 | erp = curContact.depth; | ||
872 | if (erp < minERP) | ||
873 | erp = minERP; | ||
874 | else if (erp > MaxERP) | ||
875 | erp = MaxERP; | ||
876 | |||
877 | Joint = CreateContacJoint(ref curContact, mu, bounce,cfm,erp); | ||
851 | d.JointAttach(Joint, b1, b2); | 878 | d.JointAttach(Joint, b1, b2); |
852 | 879 | ||
853 | if (++m_global_contactcount >= maxContactsbeforedeath) | 880 | if (++m_global_contactcount >= maxContactsbeforedeath) |