diff options
author | UbitUmarov | 2017-03-31 20:55:48 +0100 |
---|---|---|
committer | UbitUmarov | 2017-03-31 20:55:48 +0100 |
commit | 6a35a965ff7085b5962745437a10d798c0fb611d (patch) | |
tree | 029843113cec9fe04e733049c6232d2d36c2a106 | |
parent | Adapt to a variable name that has changed in core (diff) | |
download | opensim-SC_OLD-6a35a965ff7085b5962745437a10d798c0fb611d.zip opensim-SC_OLD-6a35a965ff7085b5962745437a10d798c0fb611d.tar.gz opensim-SC_OLD-6a35a965ff7085b5962745437a10d798c0fb611d.tar.bz2 opensim-SC_OLD-6a35a965ff7085b5962745437a10d798c0fb611d.tar.xz |
add OSSL functions to override linksets total mass, center of mass and inertia. replacing the crude automatic estimation based on prims known to physics and density. Changed parameters are still not saved, and are lost on region crossings. only suported by UbODE. EXPERIMENTAL feature, only test it for now.. don't try to use in products.
6 files changed, 531 insertions, 46 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index bf4d60c..77658ef 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -5010,6 +5010,47 @@ namespace OpenSim.Region.Framework.Scenes | |||
5010 | return Ptot; | 5010 | return Ptot; |
5011 | } | 5011 | } |
5012 | 5012 | ||
5013 | public void GetInertiaData(out float TotalMass, out Vector3 CenterOfMass, out Vector3 Inertia, out Vector4 aux ) | ||
5014 | { | ||
5015 | PhysicsActor pa = RootPart.PhysActor; | ||
5016 | |||
5017 | if(((RootPart.Flags & PrimFlags.Physics) !=0) && pa !=null) | ||
5018 | { | ||
5019 | PhysicsInertiaData inertia; | ||
5020 | |||
5021 | inertia = pa.GetInertiaData(); | ||
5022 | |||
5023 | TotalMass = inertia.TotalMass; | ||
5024 | CenterOfMass = inertia.CenterOfMass; | ||
5025 | Inertia = inertia.Inertia; | ||
5026 | aux = inertia.InertiaRotation; | ||
5027 | |||
5028 | return; | ||
5029 | } | ||
5030 | |||
5031 | TotalMass = GetMass(); | ||
5032 | CenterOfMass = GetCenterOfMass() - AbsolutePosition; | ||
5033 | CenterOfMass *= Quaternion.Conjugate(RootPart.RotationOffset); | ||
5034 | Inertia = Vector3.Zero; | ||
5035 | aux = Vector4.Zero; | ||
5036 | } | ||
5037 | |||
5038 | public void SetInertiaData(float TotalMass, Vector3 CenterOfMass, Vector3 Inertia, Vector4 aux ) | ||
5039 | { | ||
5040 | PhysicsActor pa = RootPart.PhysActor; | ||
5041 | |||
5042 | if(pa !=null) | ||
5043 | { | ||
5044 | PhysicsInertiaData inertia = new PhysicsInertiaData(); | ||
5045 | inertia.TotalMass = TotalMass; | ||
5046 | inertia.CenterOfMass = CenterOfMass; | ||
5047 | inertia.Inertia = Inertia; | ||
5048 | inertia.InertiaRotation = aux; | ||
5049 | pa.SetInertiaData(inertia); | ||
5050 | } | ||
5051 | } | ||
5052 | |||
5053 | |||
5013 | /// <summary> | 5054 | /// <summary> |
5014 | /// Set the user group to which this scene object belongs. | 5055 | /// Set the user group to which this scene object belongs. |
5015 | /// </summary> | 5056 | /// </summary> |
diff --git a/OpenSim/Region/PhysicsModules/SharedBase/PhysicsActor.cs b/OpenSim/Region/PhysicsModules/SharedBase/PhysicsActor.cs index 33f0337..ad9b28f 100644 --- a/OpenSim/Region/PhysicsModules/SharedBase/PhysicsActor.cs +++ b/OpenSim/Region/PhysicsModules/SharedBase/PhysicsActor.cs | |||
@@ -55,6 +55,28 @@ namespace OpenSim.Region.PhysicsModules.SharedBase | |||
55 | Absolute | 55 | Absolute |
56 | } | 56 | } |
57 | 57 | ||
58 | public class PhysicsInertiaData | ||
59 | { | ||
60 | public float TotalMass; // the total mass of a linkset | ||
61 | public Vector3 CenterOfMass; // the center of mass position relative to root part position | ||
62 | public Vector3 Inertia; // (Ixx, Iyy, Izz) moment of inertia relative to center of mass and principal axis in local coords | ||
63 | public Vector4 InertiaRotation; // if principal axis don't match local axis, the principal axis rotation | ||
64 | // or the upper triangle of the inertia tensor | ||
65 | // Ixy (= Iyx), Ixz (= Izx), Iyz (= Izy)) | ||
66 | |||
67 | public PhysicsInertiaData() | ||
68 | { | ||
69 | } | ||
70 | |||
71 | public PhysicsInertiaData(PhysicsInertiaData source) | ||
72 | { | ||
73 | TotalMass = source.TotalMass; | ||
74 | CenterOfMass = source.CenterOfMass; | ||
75 | Inertia = source.Inertia; | ||
76 | InertiaRotation = source.InertiaRotation; | ||
77 | } | ||
78 | } | ||
79 | |||
58 | public struct CameraData | 80 | public struct CameraData |
59 | { | 81 | { |
60 | public Quaternion CameraRotation; | 82 | public Quaternion CameraRotation; |
@@ -463,6 +485,20 @@ namespace OpenSim.Region.PhysicsModules.SharedBase | |||
463 | 485 | ||
464 | public virtual void AddCollisionEvent(uint CollidedWith, ContactPoint contact) { } | 486 | public virtual void AddCollisionEvent(uint CollidedWith, ContactPoint contact) { } |
465 | 487 | ||
488 | public virtual PhysicsInertiaData GetInertiaData() | ||
489 | { | ||
490 | PhysicsInertiaData data = new PhysicsInertiaData(); | ||
491 | data.TotalMass = this.Mass; | ||
492 | data.CenterOfMass = CenterOfMass - Position; | ||
493 | data.Inertia = Vector3.Zero; | ||
494 | data.InertiaRotation = Vector4.Zero; | ||
495 | return data; | ||
496 | } | ||
497 | |||
498 | public virtual void SetInertiaData(PhysicsInertiaData inertia) | ||
499 | { | ||
500 | } | ||
501 | |||
466 | // Warning in a parent part it returns itself, not null | 502 | // Warning in a parent part it returns itself, not null |
467 | public virtual PhysicsActor ParentActor { get { return this; } } | 503 | public virtual PhysicsActor ParentActor { get { return this; } } |
468 | 504 | ||
diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs index 45ef273..d560b41 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs | |||
@@ -182,14 +182,16 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
182 | private float m_streamCost; | 182 | private float m_streamCost; |
183 | 183 | ||
184 | public d.Mass primdMass; // prim inertia information on it's own referencial | 184 | public d.Mass primdMass; // prim inertia information on it's own referencial |
185 | private PhysicsInertiaData m_InertiaOverride; | ||
185 | float primMass; // prim own mass | 186 | float primMass; // prim own mass |
186 | float primVolume; // prim own volume; | 187 | float primVolume; // prim own volume; |
187 | float _mass; // object mass acording to case | 188 | float m_mass; // object mass acording to case |
188 | 189 | ||
189 | public int givefakepos; | 190 | public int givefakepos; |
190 | private Vector3 fakepos; | 191 | private Vector3 fakepos; |
191 | public int givefakeori; | 192 | public int givefakeori; |
192 | private Quaternion fakeori; | 193 | private Quaternion fakeori; |
194 | private PhysicsInertiaData m_fakeInertiaOverride; | ||
193 | 195 | ||
194 | private int m_eventsubscription; | 196 | private int m_eventsubscription; |
195 | private int m_cureventsubscription; | 197 | private int m_cureventsubscription; |
@@ -465,10 +467,110 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
465 | } | 467 | } |
466 | } | 468 | } |
467 | 469 | ||
470 | public override PhysicsInertiaData GetInertiaData() | ||
471 | { | ||
472 | PhysicsInertiaData inertia; | ||
473 | if(childPrim) | ||
474 | { | ||
475 | if(_parent != null) | ||
476 | return _parent.GetInertiaData(); | ||
477 | else | ||
478 | { | ||
479 | inertia = new PhysicsInertiaData(); | ||
480 | inertia.TotalMass = -1; | ||
481 | return inertia; | ||
482 | } | ||
483 | } | ||
484 | |||
485 | inertia = new PhysicsInertiaData(); | ||
486 | |||
487 | // double buffering | ||
488 | if(m_fakeInertiaOverride != null) | ||
489 | { | ||
490 | d.Mass objdmass = new d.Mass(); | ||
491 | objdmass.I.M00 = m_fakeInertiaOverride.Inertia.X; | ||
492 | objdmass.I.M11 = m_fakeInertiaOverride.Inertia.Y; | ||
493 | objdmass.I.M22 = m_fakeInertiaOverride.Inertia.Z; | ||
494 | |||
495 | objdmass.mass = m_fakeInertiaOverride.TotalMass; | ||
496 | |||
497 | if(Math.Abs(m_fakeInertiaOverride.InertiaRotation.W) < 0.999) | ||
498 | { | ||
499 | d.Matrix3 inertiarotmat = new d.Matrix3(); | ||
500 | d.Quaternion inertiarot = new d.Quaternion(); | ||
501 | |||
502 | inertiarot.X = m_fakeInertiaOverride.InertiaRotation.X; | ||
503 | inertiarot.Y = m_fakeInertiaOverride.InertiaRotation.Y; | ||
504 | inertiarot.Z = m_fakeInertiaOverride.InertiaRotation.Z; | ||
505 | inertiarot.W = m_fakeInertiaOverride.InertiaRotation.W; | ||
506 | d.RfromQ(out inertiarotmat, ref inertiarot); | ||
507 | d.MassRotate(ref objdmass, ref inertiarotmat); | ||
508 | } | ||
509 | |||
510 | inertia.TotalMass = m_fakeInertiaOverride.TotalMass; | ||
511 | inertia.CenterOfMass = m_fakeInertiaOverride.CenterOfMass; | ||
512 | inertia.Inertia.X = objdmass.I.M00; | ||
513 | inertia.Inertia.Y = objdmass.I.M11; | ||
514 | inertia.Inertia.Z = objdmass.I.M22; | ||
515 | inertia.InertiaRotation.X = objdmass.I.M01; | ||
516 | inertia.InertiaRotation.Y = objdmass.I.M02; | ||
517 | inertia.InertiaRotation.Z = objdmass.I.M12; | ||
518 | return inertia; | ||
519 | } | ||
520 | |||
521 | inertia.TotalMass = m_mass; | ||
522 | |||
523 | if(Body == IntPtr.Zero || prim_geom == IntPtr.Zero) | ||
524 | { | ||
525 | inertia.CenterOfMass = Vector3.Zero; | ||
526 | inertia.Inertia = Vector3.Zero; | ||
527 | inertia.InertiaRotation = Vector4.Zero; | ||
528 | return inertia; | ||
529 | } | ||
530 | |||
531 | d.Vector3 dtmp; | ||
532 | d.Mass m = new d.Mass(); | ||
533 | lock(_parent_scene.OdeLock) | ||
534 | { | ||
535 | d.AllocateODEDataForThread(0); | ||
536 | dtmp = d.GeomGetOffsetPosition(prim_geom); | ||
537 | d.BodyGetMass(Body, out m); | ||
538 | } | ||
539 | |||
540 | Vector3 cm = new Vector3(-dtmp.X, -dtmp.Y, -dtmp.Z); | ||
541 | inertia.CenterOfMass = cm; | ||
542 | inertia.Inertia = new Vector3(m.I.M00, m.I.M11, m.I.M22); | ||
543 | inertia.InertiaRotation = new Vector4(m.I.M01, m.I.M02 , m.I.M12, 0); | ||
544 | |||
545 | return inertia; | ||
546 | } | ||
547 | |||
548 | public override void SetInertiaData(PhysicsInertiaData inertia) | ||
549 | { | ||
550 | if(childPrim) | ||
551 | { | ||
552 | if(_parent != null) | ||
553 | _parent.SetInertiaData(inertia); | ||
554 | return; | ||
555 | } | ||
556 | |||
557 | if(inertia.TotalMass > 0) | ||
558 | m_fakeInertiaOverride = new PhysicsInertiaData(inertia); | ||
559 | else | ||
560 | m_fakeInertiaOverride = null; | ||
561 | |||
562 | if (inertia.TotalMass > _parent_scene.maximumMassObject) | ||
563 | inertia.TotalMass = _parent_scene.maximumMassObject; | ||
564 | AddChange(changes.SetInertia,(object)m_fakeInertiaOverride); | ||
565 | } | ||
566 | |||
468 | public override Vector3 CenterOfMass | 567 | public override Vector3 CenterOfMass |
469 | { | 568 | { |
470 | get | 569 | get |
471 | { | 570 | { |
571 | if(!childPrim && m_fakeInertiaOverride != null) | ||
572 | return m_fakeInertiaOverride.CenterOfMass; | ||
573 | |||
472 | lock (_parent_scene.OdeLock) | 574 | lock (_parent_scene.OdeLock) |
473 | { | 575 | { |
474 | d.AllocateODEDataForThread(0); | 576 | d.AllocateODEDataForThread(0); |
@@ -922,8 +1024,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
922 | { | 1024 | { |
923 | float old = m_density; | 1025 | float old = m_density; |
924 | m_density = value / 100f; | 1026 | m_density = value / 100f; |
925 | if(m_density != old) | 1027 | // if(m_density != old) |
926 | UpdatePrimBodyData(); | 1028 | // UpdatePrimBodyData(); |
927 | } | 1029 | } |
928 | } | 1030 | } |
929 | public override float GravModifier | 1031 | public override float GravModifier |
@@ -1716,26 +1818,29 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1716 | m_log.Warn("[PHYSICS]: MakeBody root geom already had a body"); | 1818 | m_log.Warn("[PHYSICS]: MakeBody root geom already had a body"); |
1717 | } | 1819 | } |
1718 | 1820 | ||
1719 | d.Matrix3 mymat = new d.Matrix3(); | 1821 | bool noInertiaOverride = (m_InertiaOverride == null); |
1720 | d.Quaternion myrot = new d.Quaternion(); | ||
1721 | d.Mass objdmass = new d.Mass { }; | ||
1722 | 1822 | ||
1723 | Body = d.BodyCreate(_parent_scene.world); | 1823 | Body = d.BodyCreate(_parent_scene.world); |
1724 | 1824 | ||
1725 | objdmass = primdMass; | 1825 | d.Matrix3 mymat = new d.Matrix3(); |
1826 | d.Quaternion myrot = new d.Quaternion(); | ||
1827 | d.Mass objdmass = new d.Mass { }; | ||
1726 | 1828 | ||
1727 | // rotate inertia | ||
1728 | myrot.X = _orientation.X; | 1829 | myrot.X = _orientation.X; |
1729 | myrot.Y = _orientation.Y; | 1830 | myrot.Y = _orientation.Y; |
1730 | myrot.Z = _orientation.Z; | 1831 | myrot.Z = _orientation.Z; |
1731 | myrot.W = _orientation.W; | 1832 | myrot.W = _orientation.W; |
1732 | |||
1733 | d.RfromQ(out mymat, ref myrot); | 1833 | d.RfromQ(out mymat, ref myrot); |
1734 | d.MassRotate(ref objdmass, ref mymat); | ||
1735 | 1834 | ||
1736 | // set the body rotation | 1835 | // set the body rotation |
1737 | d.BodySetRotation(Body, ref mymat); | 1836 | d.BodySetRotation(Body, ref mymat); |
1738 | 1837 | ||
1838 | if(noInertiaOverride) | ||
1839 | { | ||
1840 | objdmass = primdMass; | ||
1841 | d.MassRotate(ref objdmass, ref mymat); | ||
1842 | } | ||
1843 | |||
1739 | // recompute full object inertia if needed | 1844 | // recompute full object inertia if needed |
1740 | if (childrenPrim.Count > 0) | 1845 | if (childrenPrim.Count > 0) |
1741 | { | 1846 | { |
@@ -1758,27 +1863,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1758 | continue; | 1863 | continue; |
1759 | } | 1864 | } |
1760 | 1865 | ||
1761 | tmpdmass = prm.primdMass; | ||
1762 | |||
1763 | // apply prim current rotation to inertia | ||
1764 | quat.X = prm._orientation.X; | 1866 | quat.X = prm._orientation.X; |
1765 | quat.Y = prm._orientation.Y; | 1867 | quat.Y = prm._orientation.Y; |
1766 | quat.Z = prm._orientation.Z; | 1868 | quat.Z = prm._orientation.Z; |
1767 | quat.W = prm._orientation.W; | 1869 | quat.W = prm._orientation.W; |
1768 | d.RfromQ(out mat, ref quat); | 1870 | d.RfromQ(out mat, ref quat); |
1769 | d.MassRotate(ref tmpdmass, ref mat); | 1871 | |
1770 | |||
1771 | Vector3 ppos = prm._position; | ||
1772 | ppos.X -= rcm.X; | ||
1773 | ppos.Y -= rcm.Y; | ||
1774 | ppos.Z -= rcm.Z; | ||
1775 | // refer inertia to root prim center of mass position | ||
1776 | d.MassTranslate(ref tmpdmass, | ||
1777 | ppos.X, | ||
1778 | ppos.Y, | ||
1779 | ppos.Z); | ||
1780 | |||
1781 | d.MassAdd(ref objdmass, ref tmpdmass); // add to total object inertia | ||
1782 | // fix prim colision cats | 1872 | // fix prim colision cats |
1783 | 1873 | ||
1784 | if (d.GeomGetBody(prm.prim_geom) != IntPtr.Zero) | 1874 | if (d.GeomGetBody(prm.prim_geom) != IntPtr.Zero) |
@@ -1791,6 +1881,24 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1791 | d.GeomSetBody(prm.prim_geom, Body); | 1881 | d.GeomSetBody(prm.prim_geom, Body); |
1792 | prm.Body = Body; | 1882 | prm.Body = Body; |
1793 | d.GeomSetOffsetWorldRotation(prm.prim_geom, ref mat); // set relative rotation | 1883 | d.GeomSetOffsetWorldRotation(prm.prim_geom, ref mat); // set relative rotation |
1884 | |||
1885 | if(noInertiaOverride) | ||
1886 | { | ||
1887 | tmpdmass = prm.primdMass; | ||
1888 | |||
1889 | d.MassRotate(ref tmpdmass, ref mat); | ||
1890 | Vector3 ppos = prm._position; | ||
1891 | ppos.X -= rcm.X; | ||
1892 | ppos.Y -= rcm.Y; | ||
1893 | ppos.Z -= rcm.Z; | ||
1894 | // refer inertia to root prim center of mass position | ||
1895 | d.MassTranslate(ref tmpdmass, | ||
1896 | ppos.X, | ||
1897 | ppos.Y, | ||
1898 | ppos.Z); | ||
1899 | |||
1900 | d.MassAdd(ref objdmass, ref tmpdmass); // add to total object inertia | ||
1901 | } | ||
1794 | } | 1902 | } |
1795 | } | 1903 | } |
1796 | } | 1904 | } |
@@ -1799,19 +1907,60 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1799 | // associate root geom with body | 1907 | // associate root geom with body |
1800 | d.GeomSetBody(prim_geom, Body); | 1908 | d.GeomSetBody(prim_geom, Body); |
1801 | 1909 | ||
1802 | d.BodySetPosition(Body, _position.X + objdmass.c.X, _position.Y + objdmass.c.Y, _position.Z + objdmass.c.Z); | 1910 | if(noInertiaOverride) |
1911 | d.BodySetPosition(Body, _position.X + objdmass.c.X, _position.Y + objdmass.c.Y, _position.Z + objdmass.c.Z); | ||
1912 | else | ||
1913 | { | ||
1914 | Vector3 ncm = m_InertiaOverride.CenterOfMass * _orientation; | ||
1915 | d.BodySetPosition(Body, | ||
1916 | _position.X + ncm.X, | ||
1917 | _position.Y + ncm.Y, | ||
1918 | _position.Z + ncm.Z); | ||
1919 | } | ||
1920 | |||
1803 | d.GeomSetOffsetWorldPosition(prim_geom, _position.X, _position.Y, _position.Z); | 1921 | d.GeomSetOffsetWorldPosition(prim_geom, _position.X, _position.Y, _position.Z); |
1804 | 1922 | ||
1805 | d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body | 1923 | if(noInertiaOverride) |
1806 | myrot.X = -myrot.X; | 1924 | { |
1807 | myrot.Y = -myrot.Y; | 1925 | d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body |
1808 | myrot.Z = -myrot.Z; | 1926 | myrot.X = -myrot.X; |
1927 | myrot.Y = -myrot.Y; | ||
1928 | myrot.Z = -myrot.Z; | ||
1809 | 1929 | ||
1810 | d.RfromQ(out mymat, ref myrot); | 1930 | d.RfromQ(out mymat, ref myrot); |
1811 | d.MassRotate(ref objdmass, ref mymat); | 1931 | d.MassRotate(ref objdmass, ref mymat); |
1812 | 1932 | ||
1813 | d.BodySetMass(Body, ref objdmass); | 1933 | d.BodySetMass(Body, ref objdmass); |
1814 | _mass = objdmass.mass; | 1934 | m_mass = objdmass.mass; |
1935 | } | ||
1936 | else | ||
1937 | { | ||
1938 | objdmass.c.X = 0; | ||
1939 | objdmass.c.Y = 0; | ||
1940 | objdmass.c.Z = 0; | ||
1941 | |||
1942 | objdmass.I.M00 = m_InertiaOverride.Inertia.X; | ||
1943 | objdmass.I.M11 = m_InertiaOverride.Inertia.Y; | ||
1944 | objdmass.I.M22 = m_InertiaOverride.Inertia.Z; | ||
1945 | |||
1946 | objdmass.mass = m_InertiaOverride.TotalMass; | ||
1947 | |||
1948 | if(Math.Abs(m_InertiaOverride.InertiaRotation.W) < 0.999) | ||
1949 | { | ||
1950 | d.Matrix3 inertiarotmat = new d.Matrix3(); | ||
1951 | d.Quaternion inertiarot = new d.Quaternion(); | ||
1952 | |||
1953 | inertiarot.X = m_InertiaOverride.InertiaRotation.X; | ||
1954 | inertiarot.Y = m_InertiaOverride.InertiaRotation.Y; | ||
1955 | inertiarot.Z = m_InertiaOverride.InertiaRotation.Z; | ||
1956 | inertiarot.W = m_InertiaOverride.InertiaRotation.W; | ||
1957 | d.RfromQ(out inertiarotmat, ref inertiarot); | ||
1958 | d.MassRotate(ref objdmass, ref inertiarotmat); | ||
1959 | } | ||
1960 | d.BodySetMass(Body, ref objdmass); | ||
1961 | |||
1962 | m_mass = objdmass.mass; | ||
1963 | } | ||
1815 | 1964 | ||
1816 | // disconnect from world gravity so we can apply buoyancy | 1965 | // disconnect from world gravity so we can apply buoyancy |
1817 | d.BodySetGravityMode(Body, false); | 1966 | d.BodySetGravityMode(Body, false); |
@@ -1990,7 +2139,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1990 | SetInStaticSpace(prm); | 2139 | SetInStaticSpace(prm); |
1991 | } | 2140 | } |
1992 | prm.Body = IntPtr.Zero; | 2141 | prm.Body = IntPtr.Zero; |
1993 | prm._mass = prm.primMass; | 2142 | prm.m_mass = prm.primMass; |
1994 | prm.m_collisionscore = 0; | 2143 | prm.m_collisionscore = 0; |
1995 | } | 2144 | } |
1996 | } | 2145 | } |
@@ -2004,7 +2153,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2004 | } | 2153 | } |
2005 | Body = IntPtr.Zero; | 2154 | Body = IntPtr.Zero; |
2006 | } | 2155 | } |
2007 | _mass = primMass; | 2156 | m_mass = primMass; |
2008 | m_collisionscore = 0; | 2157 | m_collisionscore = 0; |
2009 | } | 2158 | } |
2010 | 2159 | ||
@@ -2081,7 +2230,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2081 | d.BodySetPosition(Body, dobjpos.X + thispos.X, dobjpos.Y + thispos.Y, dobjpos.Z + thispos.Z); | 2230 | d.BodySetPosition(Body, dobjpos.X + thispos.X, dobjpos.Y + thispos.Y, dobjpos.Z + thispos.Z); |
2082 | d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body | 2231 | d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body |
2083 | d.BodySetMass(Body, ref objdmass); | 2232 | d.BodySetMass(Body, ref objdmass); |
2084 | _mass = objdmass.mass; | 2233 | m_mass = objdmass.mass; |
2085 | } | 2234 | } |
2086 | 2235 | ||
2087 | private void FixInertia(Vector3 NewPos) | 2236 | private void FixInertia(Vector3 NewPos) |
@@ -2145,7 +2294,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2145 | d.BodySetPosition(Body, dobjpos.X + thispos.X, dobjpos.Y + thispos.Y, dobjpos.Z + thispos.Z); | 2294 | d.BodySetPosition(Body, dobjpos.X + thispos.X, dobjpos.Y + thispos.Y, dobjpos.Z + thispos.Z); |
2146 | d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body | 2295 | d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body |
2147 | d.BodySetMass(Body, ref objdmass); | 2296 | d.BodySetMass(Body, ref objdmass); |
2148 | _mass = objdmass.mass; | 2297 | m_mass = objdmass.mass; |
2149 | } | 2298 | } |
2150 | 2299 | ||
2151 | private void FixInertia(Quaternion newrot) | 2300 | private void FixInertia(Quaternion newrot) |
@@ -2211,7 +2360,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2211 | d.BodySetPosition(Body, dobjpos.X + thispos.X, dobjpos.Y + thispos.Y, dobjpos.Z + thispos.Z); | 2360 | d.BodySetPosition(Body, dobjpos.X + thispos.X, dobjpos.Y + thispos.Y, dobjpos.Z + thispos.Z); |
2212 | d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body | 2361 | d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body |
2213 | d.BodySetMass(Body, ref objdmass); | 2362 | d.BodySetMass(Body, ref objdmass); |
2214 | _mass = objdmass.mass; | 2363 | m_mass = objdmass.mass; |
2215 | } | 2364 | } |
2216 | 2365 | ||
2217 | 2366 | ||
@@ -2226,7 +2375,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2226 | if (primMass > _parent_scene.maximumMassObject) | 2375 | if (primMass > _parent_scene.maximumMassObject) |
2227 | primMass = _parent_scene.maximumMassObject; | 2376 | primMass = _parent_scene.maximumMassObject; |
2228 | 2377 | ||
2229 | _mass = primMass; // just in case | 2378 | m_mass = primMass; // just in case |
2230 | 2379 | ||
2231 | d.MassSetBoxTotal(out primdMass, primMass, 2.0f * m_OBB.X, 2.0f * m_OBB.Y, 2.0f * m_OBB.Z); | 2380 | d.MassSetBoxTotal(out primdMass, primMass, 2.0f * m_OBB.X, 2.0f * m_OBB.Y, 2.0f * m_OBB.Z); |
2232 | 2381 | ||
@@ -3306,6 +3455,15 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
3306 | m_useHoverPID = active; | 3455 | m_useHoverPID = active; |
3307 | } | 3456 | } |
3308 | 3457 | ||
3458 | private void changeInertia(PhysicsInertiaData inertia) | ||
3459 | { | ||
3460 | m_InertiaOverride = inertia; | ||
3461 | |||
3462 | if (Body != IntPtr.Zero) | ||
3463 | DestroyBody(); | ||
3464 | MakeBody(); | ||
3465 | } | ||
3466 | |||
3309 | #endregion | 3467 | #endregion |
3310 | 3468 | ||
3311 | public void Move() | 3469 | public void Move() |
@@ -3346,7 +3504,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
3346 | float fy = 0; | 3504 | float fy = 0; |
3347 | float fz = 0; | 3505 | float fz = 0; |
3348 | 3506 | ||
3349 | float m_mass = _mass; | 3507 | float mass = m_mass; |
3350 | 3508 | ||
3351 | if (m_usePID && m_PIDTau > 0) | 3509 | if (m_usePID && m_PIDTau > 0) |
3352 | { | 3510 | { |
@@ -3453,9 +3611,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
3453 | fz = _parent_scene.gravityz * b; | 3611 | fz = _parent_scene.gravityz * b; |
3454 | } | 3612 | } |
3455 | 3613 | ||
3456 | fx *= m_mass; | 3614 | fx *= mass; |
3457 | fy *= m_mass; | 3615 | fy *= mass; |
3458 | fz *= m_mass; | 3616 | fz *= mass; |
3459 | 3617 | ||
3460 | // constant force | 3618 | // constant force |
3461 | fx += m_force.X; | 3619 | fx += m_force.X; |
@@ -3941,6 +4099,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
3941 | changePIDHoverActive((bool)arg); | 4099 | changePIDHoverActive((bool)arg); |
3942 | break; | 4100 | break; |
3943 | 4101 | ||
4102 | case changes.SetInertia: | ||
4103 | changeInertia((PhysicsInertiaData) arg); | ||
4104 | break; | ||
4105 | |||
3944 | case changes.Null: | 4106 | case changes.Null: |
3945 | donullchange(); | 4107 | donullchange(); |
3946 | break; | 4108 | break; |
@@ -3957,7 +4119,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
3957 | _parent_scene.AddChange((PhysicsActor) this, what, arg); | 4119 | _parent_scene.AddChange((PhysicsActor) this, what, arg); |
3958 | } | 4120 | } |
3959 | 4121 | ||
3960 | |||
3961 | private struct strVehicleBoolParam | 4122 | private struct strVehicleBoolParam |
3962 | { | 4123 | { |
3963 | public int param; | 4124 | public int param; |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 4c3f7ee..6c094ee 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | |||
@@ -4404,5 +4404,218 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4404 | m_host.ScriptSetVolumeDetect(detect != 0); | 4404 | m_host.ScriptSetVolumeDetect(detect != 0); |
4405 | } | 4405 | } |
4406 | 4406 | ||
4407 | /// <summary> | ||
4408 | /// Get inertial data | ||
4409 | /// </summary> | ||
4410 | /// <remarks> | ||
4411 | /// </remarks> | ||
4412 | /// <returns> | ||
4413 | /// a LSL list with contents: | ||
4414 | /// LSL_Float mass, the total mass of a linkset | ||
4415 | /// LSL_Vector CenterOfMass, center mass relative to root prim | ||
4416 | /// LSL_Vector Inertia, elements of diagonal of inertia Ixx,Iyy,Izz divided by total mass | ||
4417 | /// LSL_Vector aux, elements of upper triagle of inertia Ixy (= Iyx), Ixz (= Izx), Iyz(= Izy) divided by total mass | ||
4418 | /// </returns> | ||
4419 | public LSL_List osGetInertiaData() | ||
4420 | { | ||
4421 | LSL_List result = new LSL_List(); | ||
4422 | float TotalMass; | ||
4423 | Vector3 CenterOfMass; | ||
4424 | Vector3 Inertia; | ||
4425 | Vector4 aux; | ||
4426 | |||
4427 | SceneObjectGroup sog = m_host.ParentGroup; | ||
4428 | if(sog== null || sog.IsDeleted) | ||
4429 | return result; | ||
4430 | |||
4431 | sog.GetInertiaData(out TotalMass, out CenterOfMass, out Inertia, out aux ); | ||
4432 | if(TotalMass > 0) | ||
4433 | { | ||
4434 | float t = 1.0f/TotalMass; | ||
4435 | Inertia.X *= t; | ||
4436 | Inertia.Y *= t; | ||
4437 | Inertia.Z *= t; | ||
4438 | |||
4439 | aux.X *= t; | ||
4440 | aux.Y *= t; | ||
4441 | aux.Z *= t; | ||
4442 | } | ||
4443 | |||
4444 | result.Add(new LSL_Float(TotalMass)); | ||
4445 | result.Add(new LSL_Vector(CenterOfMass.X, CenterOfMass.Y, CenterOfMass.Z)); | ||
4446 | result.Add(new LSL_Vector(Inertia.X, Inertia.Y, Inertia.Z)); | ||
4447 | result.Add(new LSL_Vector(aux.X, aux.Y, aux.Z)); | ||
4448 | return result; | ||
4449 | } | ||
4450 | |||
4451 | /// <summary> | ||
4452 | /// set inertial data | ||
4453 | /// replaces the automatic calculation of mass, center of mass and inertia | ||
4454 | /// | ||
4455 | /// </summary> | ||
4456 | /// <param name="Mass">total mass of linkset</param> | ||
4457 | /// <param name="centerOfMass">location of center of mass relative to root prim in local coords</param> | ||
4458 | /// <param name="principalInertiaScaled">moment of inertia relative to principal axis and center of mass,Ixx, Iyy, Izz divided by mass</param> | ||
4459 | /// <param name="lslrot">rotation of the inertia, relative to local axis</param> | ||
4460 | /// <remarks> | ||
4461 | /// the inertia argument is is inertia divided by mass, so corresponds only to the geometric distribution of mass and both can be changed independently. | ||
4462 | /// </remarks> | ||
4463 | |||
4464 | public void osSetInertia(LSL_Float mass, LSL_Vector centerOfMass, LSL_Vector principalInertiaScaled, LSL_Rotation lslrot) | ||
4465 | { | ||
4466 | SceneObjectGroup sog = m_host.ParentGroup; | ||
4467 | if(sog== null || sog.IsDeleted) | ||
4468 | return; | ||
4469 | |||
4470 | if(mass < 0 || principalInertiaScaled.x < 0 || principalInertiaScaled.y < 0 || principalInertiaScaled.z < 0) | ||
4471 | return; | ||
4472 | |||
4473 | // need more checks | ||
4474 | |||
4475 | Vector3 CenterOfMass = new Vector3((float)centerOfMass.x,(float)centerOfMass.y,(float)centerOfMass.z); | ||
4476 | Vector3 Inertia; | ||
4477 | float m = (float)mass; | ||
4478 | |||
4479 | Inertia.X = m * (float)principalInertiaScaled.x; | ||
4480 | Inertia.Y = m * (float)principalInertiaScaled.y; | ||
4481 | Inertia.Z = m * (float)principalInertiaScaled.z; | ||
4482 | |||
4483 | Vector4 rot = new Vector4((float)lslrot.x, (float)lslrot.y, (float)lslrot.y, (float)lslrot.s); | ||
4484 | rot.Normalize(); | ||
4485 | |||
4486 | sog.SetInertiaData(m, CenterOfMass, Inertia, rot ); | ||
4487 | } | ||
4488 | |||
4489 | /// <summary> | ||
4490 | /// set inertial data as a sphere | ||
4491 | /// replaces the automatic calculation of mass, center of mass and inertia | ||
4492 | /// | ||
4493 | /// </summary> | ||
4494 | /// <param name="Mass">total mass of linkset</param> | ||
4495 | /// <param name="boxsize">size of the Box</param> | ||
4496 | /// <param name="centerOfMass">location of center of mass relative to root prim in local coords</param> | ||
4497 | /// <param name="lslrot">rotation of the box, and so inertia, relative to local axis</param> | ||
4498 | /// <remarks> | ||
4499 | /// </remarks> | ||
4500 | public void osSetInertiaAsBox(LSL_Float mass, LSL_Vector boxSize, LSL_Vector centerOfMass, LSL_Rotation lslrot) | ||
4501 | { | ||
4502 | SceneObjectGroup sog = m_host.ParentGroup; | ||
4503 | if(sog== null || sog.IsDeleted) | ||
4504 | return; | ||
4505 | |||
4506 | if(mass < 0) | ||
4507 | return; | ||
4508 | |||
4509 | // need more checks | ||
4510 | |||
4511 | Vector3 CenterOfMass = new Vector3((float)centerOfMass.x,(float)centerOfMass.y,(float)centerOfMass.z); | ||
4512 | Vector3 Inertia; | ||
4513 | float lx = (float)boxSize.x; | ||
4514 | float ly = (float)boxSize.y; | ||
4515 | float lz = (float)boxSize.z; | ||
4516 | float m = (float)mass; | ||
4517 | float t = m / 12.0f; | ||
4518 | |||
4519 | Inertia.X = t * (ly*ly + lz*lz); | ||
4520 | Inertia.Y = t * (lx*lx + lz*lz); | ||
4521 | Inertia.Z = t * (lx*lx + ly*ly); | ||
4522 | |||
4523 | Vector4 rot = new Vector4((float)lslrot.x, (float)lslrot.y, (float)lslrot.z, (float)lslrot.s); | ||
4524 | rot.Normalize(); | ||
4525 | |||
4526 | sog.SetInertiaData(m, CenterOfMass, Inertia, rot ); | ||
4527 | } | ||
4528 | |||
4529 | /// <summary> | ||
4530 | /// set inertial data as a sphere | ||
4531 | /// replaces the automatic calculation of mass, center of mass and inertia | ||
4532 | /// | ||
4533 | /// </summary> | ||
4534 | /// <param name="Mass">total mass of linkset</param> | ||
4535 | /// <param name="radius">radius of the sphere</param> | ||
4536 | /// <param name="centerOfMass">location of center of mass relative to root prim in local coords</param> | ||
4537 | /// <remarks> | ||
4538 | /// </remarks> | ||
4539 | public void osSetInertiaAsSphere(LSL_Float mass, LSL_Float radius, LSL_Vector centerOfMass) | ||
4540 | { | ||
4541 | SceneObjectGroup sog = m_host.ParentGroup; | ||
4542 | if(sog== null || sog.IsDeleted) | ||
4543 | return; | ||
4544 | |||
4545 | if(mass < 0) | ||
4546 | return; | ||
4547 | |||
4548 | // need more checks | ||
4549 | |||
4550 | Vector3 CenterOfMass = new Vector3((float)centerOfMass.x,(float)centerOfMass.y,(float)centerOfMass.z); | ||
4551 | Vector3 Inertia; | ||
4552 | float r = (float)radius; | ||
4553 | float m = (float)mass; | ||
4554 | float t = 0.4f * m * r * r; | ||
4555 | |||
4556 | Inertia.X = t; | ||
4557 | Inertia.Y = t; | ||
4558 | Inertia.Z = t; | ||
4559 | |||
4560 | sog.SetInertiaData(m, CenterOfMass, Inertia, new Vector4(0f, 0f, 0f,1.0f)); | ||
4561 | } | ||
4562 | |||
4563 | /// <summary> | ||
4564 | /// set inertial data as a cylinder | ||
4565 | /// replaces the automatic calculation of mass, center of mass and inertia | ||
4566 | /// | ||
4567 | /// </summary> | ||
4568 | /// <param name="Mass">total mass of linkset</param> | ||
4569 | /// <param name="radius">radius of the cylinder</param> | ||
4570 | /// <param name="lenght">lenght of the cylinder</param> | ||
4571 | /// <param name="centerOfMass">location of center of mass relative to root prim in local coords</param> | ||
4572 | /// <param name="lslrot">rotation of the cylinder, and so inertia, relative to local axis</param> | ||
4573 | /// <remarks> | ||
4574 | /// cylinder axis aligned with Z axis. For other orientations provide the rotation. | ||
4575 | /// </remarks> | ||
4576 | public void osSetInertiaAsCylinder(LSL_Float mass, LSL_Float radius, LSL_Float lenght, LSL_Vector centerOfMass, LSL_Rotation lslrot) | ||
4577 | { | ||
4578 | SceneObjectGroup sog = m_host.ParentGroup; | ||
4579 | if(sog== null || sog.IsDeleted) | ||
4580 | return; | ||
4581 | |||
4582 | if(mass < 0) | ||
4583 | return; | ||
4584 | |||
4585 | // need more checks | ||
4586 | |||
4587 | Vector3 CenterOfMass = new Vector3((float)centerOfMass.x,(float)centerOfMass.y,(float)centerOfMass.z); | ||
4588 | Vector3 Inertia; | ||
4589 | float m = (float)mass; | ||
4590 | float r = (float)radius; | ||
4591 | r *= r; | ||
4592 | Inertia.Z = 0.5f * m * r; | ||
4593 | float t = (float)lenght; | ||
4594 | t *= t; | ||
4595 | t += 3.0f * r; | ||
4596 | t *= 8.333333e-2f * m; | ||
4597 | |||
4598 | Inertia.X = t; | ||
4599 | Inertia.Y = t; | ||
4600 | |||
4601 | Vector4 rot = new Vector4((float)lslrot.x, (float)lslrot.y, (float)lslrot.z, (float)lslrot.s); | ||
4602 | rot.Normalize(); | ||
4603 | |||
4604 | sog.SetInertiaData(m, CenterOfMass, Inertia, rot); | ||
4605 | } | ||
4606 | |||
4607 | /// <summary> | ||
4608 | /// removes inertial data manual override | ||
4609 | /// default automatic calculation is used again | ||
4610 | /// | ||
4611 | /// </summary> | ||
4612 | public void osClearInertia() | ||
4613 | { | ||
4614 | SceneObjectGroup sog = m_host.ParentGroup; | ||
4615 | if(sog== null || sog.IsDeleted) | ||
4616 | return; | ||
4617 | |||
4618 | sog.SetInertiaData(-1, Vector3.Zero, Vector3.Zero, Vector4.Zero ); | ||
4619 | } | ||
4407 | } | 4620 | } |
4408 | } | 4621 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index bee060a..f76ff7f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | |||
@@ -38,6 +38,7 @@ using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; | |||
38 | using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; | 38 | using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; |
39 | using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; | 39 | using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; |
40 | 40 | ||
41 | |||
41 | namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces | 42 | namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces |
42 | { | 43 | { |
43 | /// <summary> | 44 | /// <summary> |
@@ -486,6 +487,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces | |||
486 | LSL_String osRequestURL(LSL_List options); | 487 | LSL_String osRequestURL(LSL_List options); |
487 | LSL_String osRequestSecureURL(LSL_List options); | 488 | LSL_String osRequestSecureURL(LSL_List options); |
488 | void osCollisionSound(string impact_sound, double impact_volume); | 489 | void osCollisionSound(string impact_sound, double impact_volume); |
490 | |||
489 | void osVolumeDetect(int detect); | 491 | void osVolumeDetect(int detect); |
492 | |||
493 | LSL_List osGetInertiaData(); | ||
494 | void osClearInertia(); | ||
495 | void osSetInertiaAsBox(LSL_Float mass, vector boxSize, vector centerOfMass, rotation rot); | ||
496 | void osSetInertiaAsSphere(LSL_Float mass, LSL_Float radius, vector centerOfMass); | ||
497 | void osSetInertiaAsCylinder(LSL_Float mass, LSL_Float radius, LSL_Float lenght, vector centerOfMass,rotation lslrot); | ||
490 | } | 498 | } |
491 | } | 499 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 6164734..09337e5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | |||
@@ -1114,5 +1114,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
1114 | { | 1114 | { |
1115 | m_OSSL_Functions.osVolumeDetect(detect); | 1115 | m_OSSL_Functions.osVolumeDetect(detect); |
1116 | } | 1116 | } |
1117 | |||
1118 | public LSL_List osGetInertiaData() | ||
1119 | { | ||
1120 | return m_OSSL_Functions.osGetInertiaData(); | ||
1121 | } | ||
1122 | |||
1123 | public void osSetInertiaAsBox(LSL_Float mass, vector boxSize, vector centerOfMass, rotation rot) | ||
1124 | { | ||
1125 | m_OSSL_Functions.osSetInertiaAsBox(mass, boxSize, centerOfMass, rot); | ||
1126 | } | ||
1127 | |||
1128 | public void osSetInertiaAsSphere(LSL_Float mass, LSL_Float radius, vector centerOfMass) | ||
1129 | { | ||
1130 | m_OSSL_Functions.osSetInertiaAsSphere(mass, radius, centerOfMass); | ||
1131 | } | ||
1132 | |||
1133 | public void osSetInertiaAsCylinder(LSL_Float mass, LSL_Float radius, LSL_Float lenght, vector centerOfMass,rotation lslrot) | ||
1134 | { | ||
1135 | m_OSSL_Functions.osSetInertiaAsCylinder( mass, radius, lenght, centerOfMass, lslrot); | ||
1136 | } | ||
1137 | |||
1138 | public void osClearInertia() | ||
1139 | { | ||
1140 | m_OSSL_Functions.osClearInertia(); | ||
1141 | } | ||
1142 | |||
1117 | } | 1143 | } |
1118 | } | 1144 | } |