aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs4
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs22
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs365
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs131
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)