aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs41
-rw-r--r--OpenSim/Region/PhysicsModules/SharedBase/PhysicsActor.cs36
-rw-r--r--OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs253
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs213
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs26
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;
38using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; 38using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
39using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 39using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
40 40
41
41namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces 42namespace 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}