aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs30
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs439
-rw-r--r--OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs11
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs2
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs53
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs318
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs31
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs5
9 files changed, 541 insertions, 351 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index ced3fb5..6f3a084 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -3955,7 +3955,35 @@ namespace OpenSim.Region.Framework.Scenes
3955 } 3955 }
3956 } 3956 }
3957 } 3957 }
3958 3958
3959 public Vector3 GetGeometricCenter()
3960 {
3961 // this is not real geometric center but a average of positions relative to root prim acording to
3962 // http://wiki.secondlife.com/wiki/llGetGeometricCenter
3963 // ignoring tortured prims details since sl also seems to ignore
3964 // so no real use in doing it on physics
3965
3966 Vector3 gc = Vector3.Zero;
3967
3968 int nparts = m_parts.Count;
3969 if (nparts <= 1)
3970 return gc;
3971
3972 SceneObjectPart[] parts = m_parts.GetArray();
3973 nparts = parts.Length; // just in case it changed
3974 if (nparts <= 1)
3975 return gc;
3976
3977 // average all parts positions
3978 for (int i = 0; i < nparts; i++)
3979 gc += parts[i].GetWorldPosition();
3980 gc /= nparts;
3981
3982 // relative to root:
3983 gc -= AbsolutePosition;
3984 return gc;
3985 }
3986
3959 public float GetMass() 3987 public float GetMass()
3960 { 3988 {
3961 float retmass = 0f; 3989 float retmass = 0f;
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 969ddaf..511ab19 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -122,6 +122,11 @@ namespace OpenSim.Region.Framework.Scenes
122 /// Denote all sides of the prim 122 /// Denote all sides of the prim
123 /// </value> 123 /// </value>
124 public const int ALL_SIDES = -1; 124 public const int ALL_SIDES = -1;
125
126 private const scriptEvents PhyscicsNeededSubsEvents = (
127 scriptEvents.collision | scriptEvents.collision_start | scriptEvents.collision_end |
128 scriptEvents.land_collision | scriptEvents.land_collision_start | scriptEvents.land_collision_end
129 );
125 130
126 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 131 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
127 132
@@ -1821,18 +1826,20 @@ namespace OpenSim.Region.Framework.Scenes
1821 /// </summary> 1826 /// </summary>
1822 /// <param name="rootObjectFlags"></param> 1827 /// <param name="rootObjectFlags"></param>
1823 /// <param name="VolumeDetectActive"></param> 1828 /// <param name="VolumeDetectActive"></param>
1829 /// <param name="building"></param>
1824 1830
1825 public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive, bool building) 1831 public void ApplyPhysics(uint _ObjectFlags, bool _VolumeDetectActive, bool building)
1826 { 1832 {
1833 VolumeDetectActive = _VolumeDetectActive; //?? as is used this is redundante
1834
1827 if (!ParentGroup.Scene.CollidablePrims) 1835 if (!ParentGroup.Scene.CollidablePrims)
1828 return; 1836 return;
1829 1837
1830 if (PhysicsShapeType == (byte)PhysShapeType.none) 1838 if (PhysicsShapeType == (byte)PhysShapeType.none)
1831 return; 1839 return;
1832 1840
1833 bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0; 1841 bool isPhysical = (_ObjectFlags & (uint) PrimFlags.Physics) != 0;
1834 bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0; 1842 bool isPhantom = (_ObjectFlags & (uint) PrimFlags.Phantom) != 0;
1835
1836 1843
1837 if (IsJoint()) 1844 if (IsJoint())
1838 { 1845 {
@@ -1840,68 +1847,11 @@ namespace OpenSim.Region.Framework.Scenes
1840 } 1847 }
1841 else 1848 else
1842 { 1849 {
1843 // Special case for VolumeDetection: If VolumeDetection is set, the phantom flag is locally ignored 1850 if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment
1844// if (VolumeDetectActive) 1851 && !(Shape.PathCurve == (byte)Extrusion.Flexible))
1845// isPhantom = false; 1852 AddToPhysics(isPhysical, isPhantom, building, true);
1846 1853 else
1847 // The only time the physics scene shouldn't know about the prim is if it's phantom or an attachment, which is phantom by definition 1854 PhysActor = null; // just to be sure
1848 // or flexible
1849 // if (!isPhantom && !ParentGroup.IsAttachment && !(Shape.PathCurve == (byte)Extrusion.Flexible))
1850 if ((!isPhantom || isPhysical || VolumeDetectActive) && !ParentGroup.IsAttachment && !(Shape.PathCurve == (byte)Extrusion.Flexible))
1851 {
1852 Vector3 velocity = Velocity;
1853 Vector3 rotationalVelocity = AngularVelocity;
1854 try
1855 {
1856 PhysActor = ParentGroup.Scene.PhysicsScene.AddPrimShape(
1857 string.Format("{0}/{1}", Name, UUID),
1858 Shape,
1859 AbsolutePosition,
1860 Scale,
1861 GetWorldRotation(),
1862 isPhysical,
1863 isPhantom,
1864 PhysicsShapeType,
1865 m_localId);
1866 }
1867 catch
1868 {
1869 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom.", m_uuid);
1870 PhysActor = null;
1871 }
1872
1873 PhysicsActor pa = PhysActor;
1874
1875 if (pa != null)
1876 {
1877 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
1878 pa.SetMaterial(Material);
1879
1880 // if root part apply vehicle
1881 if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
1882 m_vehicle.SetVehicle(pa);
1883
1884 DoPhysicsPropertyUpdate(isPhysical, true);
1885 if(VolumeDetectActive) // change if not the default only
1886 pa.SetVolumeDetect(1);
1887
1888 if (!building)
1889 pa.Building = false;
1890
1891 Velocity = velocity;
1892 AngularVelocity = rotationalVelocity;
1893 pa.Velocity = velocity;
1894 pa.RotationalVelocity = rotationalVelocity;
1895
1896 // if not vehicle and root part apply force and torque
1897 if ((m_vehicle == null || m_vehicle.Type == Vehicle.TYPE_NONE)
1898 && LocalId == ParentGroup.RootPart.LocalId)
1899 {
1900 pa.Force = Force;
1901 pa.Torque = Torque;
1902 }
1903 }
1904 }
1905 } 1855 }
1906 } 1856 }
1907 1857
@@ -2310,18 +2260,29 @@ namespace OpenSim.Region.Framework.Scenes
2310 2260
2311 public Vector3 GetGeometricCenter() 2261 public Vector3 GetGeometricCenter()
2312 { 2262 {
2313 PhysicsActor pa = PhysActor; 2263 // this is not real geometric center but a average of positions relative to root prim acording to
2314 2264 // http://wiki.secondlife.com/wiki/llGetGeometricCenter
2315 if (pa != null) 2265 // ignoring tortured prims details since sl also seems to ignore
2316 { 2266 // so no real use in doing it on physics
2317 Vector3 vtmp = pa.CenterOfMass; 2267 if (ParentGroup.IsDeleted)
2318 return vtmp;
2319 }
2320 else
2321 return new Vector3(0, 0, 0); 2268 return new Vector3(0, 0, 0);
2269
2270 return ParentGroup.GetGeometricCenter();
2271
2272 /*
2273 PhysicsActor pa = PhysActor;
2274
2275 if (pa != null)
2276 {
2277 Vector3 vtmp = pa.CenterOfMass;
2278 return vtmp;
2279 }
2280 else
2281 return new Vector3(0, 0, 0);
2282 */
2322 } 2283 }
2323 2284
2324 public float GetMass() 2285 public float GetMass()
2325 { 2286 {
2326 PhysicsActor pa = PhysActor; 2287 PhysicsActor pa = PhysActor;
2327 2288
@@ -4628,7 +4589,6 @@ namespace OpenSim.Region.Framework.Scenes
4628 /// <param name="SetTemporary"></param> 4589 /// <param name="SetTemporary"></param>
4629 /// <param name="SetPhantom"></param> 4590 /// <param name="SetPhantom"></param>
4630 /// <param name="SetVD"></param> 4591 /// <param name="SetVD"></param>
4631// public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD)
4632 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD, bool building) 4592 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD, bool building)
4633 { 4593 {
4634 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0); 4594 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
@@ -4639,209 +4599,92 @@ namespace OpenSim.Region.Framework.Scenes
4639 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD)) 4599 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD))
4640 return; 4600 return;
4641 4601
4642 // do this first
4643 if (building && PhysActor != null && PhysActor.Building != building)
4644 PhysActor.Building = building;
4645
4646 // Special cases for VD. VD can only be called from a script
4647 // and can't be combined with changes to other states. So we can rely
4648 // that...
4649 // ... if VD is changed, all others are not.
4650 // ... if one of the others is changed, VD is not.
4651
4652/*
4653 if (SetVD) // VD is active, special logic applies
4654
4655 volume detection is now independent of phantom in sl
4656
4657 {
4658 // State machine logic for VolumeDetect
4659 // More logic below
4660
4661
4662 bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
4663
4664 if (phanReset) // Phantom changes from on to off switch VD off too
4665 {
4666 SetVD = false; // Switch it of for the course of this routine
4667 VolumeDetectActive = false; // and also permanently
4668 if (PhysActor != null)
4669 PhysActor.SetVolumeDetect(0); // Let physics know about it too
4670 }
4671 else
4672 {
4673 // If volumedetect is active we don't want phantom to be applied.
4674 // If this is a new call to VD out of the state "phantom"
4675 // this will also cause the prim to be visible to physics
4676 SetPhantom = false;
4677 }
4678 }
4679 else if (wasVD)
4680 {
4681 // Correspondingly, if VD is turned off, also turn off phantom
4682 SetPhantom = false;
4683 }
4684
4685 if (UsePhysics && IsJoint())
4686 {
4687 SetPhantom = true;
4688 }
4689*/
4690 if (UsePhysics) 4602 if (UsePhysics)
4691 {
4692 AddFlag(PrimFlags.Physics); 4603 AddFlag(PrimFlags.Physics);
4693/*
4694 if (!wasUsingPhysics)
4695 {
4696 DoPhysicsPropertyUpdate(UsePhysics, false);
4697
4698 if (!ParentGroup.IsDeleted)
4699 {
4700 if (LocalId == ParentGroup.RootPart.LocalId)
4701 {
4702 ParentGroup.CheckSculptAndLoad();
4703 }
4704 }
4705 }
4706 */
4707 }
4708 else 4604 else
4709 {
4710 RemFlag(PrimFlags.Physics); 4605 RemFlag(PrimFlags.Physics);
4711/*
4712 if (wasUsingPhysics)
4713 {
4714 DoPhysicsPropertyUpdate(UsePhysics, false);
4715 }
4716*/
4717 }
4718 4606
4719 if (SetPhantom) 4607 if (SetPhantom)
4720 AddFlag(PrimFlags.Phantom); 4608 AddFlag(PrimFlags.Phantom);
4721 else 4609 else
4722 RemFlag(PrimFlags.Phantom); 4610 RemFlag(PrimFlags.Phantom);
4723 4611
4612 if (SetTemporary)
4613 AddFlag(PrimFlags.TemporaryOnRez);
4614 else
4615 RemFlag(PrimFlags.TemporaryOnRez);
4616
4617 VolumeDetectActive = SetVD;
4618
4619 if (ParentGroup.Scene == null)
4620 return;
4621
4622 PhysicsActor pa = PhysActor;
4623
4624 if (pa != null && building && pa.Building != building)
4625 pa.Building = building;
4626
4724 if ((SetPhantom && !UsePhysics) || ParentGroup.IsAttachment || PhysicsShapeType == (byte)PhysShapeType.none 4627 if ((SetPhantom && !UsePhysics) || ParentGroup.IsAttachment || PhysicsShapeType == (byte)PhysShapeType.none
4725 || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints 4628 || (Shape.PathCurve == (byte)Extrusion.Flexible))
4726 { 4629 {
4727// AddFlag(PrimFlags.Phantom); 4630 if (pa != null)
4631 {
4632 ParentGroup.Scene.RemovePhysicalPrim(1);
4633 RemoveFromPhysics();
4634 }
4728 4635
4729 Velocity = new Vector3(0, 0, 0); 4636 Velocity = new Vector3(0, 0, 0);
4730 Acceleration = new Vector3(0, 0, 0); 4637 Acceleration = new Vector3(0, 0, 0);
4731 if (ParentGroup.RootPart == this) 4638 if (ParentGroup.RootPart == this)
4732 AngularVelocity = new Vector3(0, 0, 0); 4639 AngularVelocity = new Vector3(0, 0, 0);
4733
4734 if (PhysActor != null)
4735 {
4736 ParentGroup.Scene.RemovePhysicalPrim(1);
4737 RemoveFromPhysics();
4738 }
4739 } 4640 }
4740 else 4641 else
4741 { 4642 {
4742 if (ParentGroup.Scene == null)
4743 return;
4744
4745 if (ParentGroup.Scene.CollidablePrims) 4643 if (ParentGroup.Scene.CollidablePrims)
4746 { 4644 {
4747 if (PhysActor == null) 4645 if (pa == null)
4748 { 4646 {
4749 PhysActor = ParentGroup.Scene.PhysicsScene.AddPrimShape( 4647 AddToPhysics(UsePhysics, SetPhantom, building , false);
4750 string.Format("{0}/{1}", Name, UUID), 4648 pa = PhysActor;
4751 Shape, 4649
4752 AbsolutePosition, 4650 if (pa != null)
4753 Scale,
4754 GetWorldRotation(), //physics wants world rotation like all other functions send
4755 UsePhysics,
4756 SetPhantom,
4757 PhysicsShapeType,
4758 m_localId);
4759
4760 PhysActor.SetMaterial(Material);
4761
4762 // if root part apply vehicle
4763 if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
4764 m_vehicle.SetVehicle(PhysActor);
4765
4766 DoPhysicsPropertyUpdate(UsePhysics, true);
4767
4768 if (!ParentGroup.IsDeleted)
4769 { 4651 {
4770 if (LocalId == ParentGroup.RootPart.LocalId) 4652 if (
4653// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4654// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4655// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4656// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4657// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4658// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4659 ((AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
4660// (CollisionSound != UUID.Zero)
4661 )
4771 { 4662 {
4772 ParentGroup.CheckSculptAndLoad(); 4663 pa.OnCollisionUpdate += PhysicsCollision;
4664 pa.SubscribeEvents(1000);
4773 } 4665 }
4774 } 4666 }
4775
4776 if (
4777 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4778 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4779 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4780 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4781 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4782 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4783 (CollisionSound != UUID.Zero)
4784 )
4785 {
4786 PhysActor.OnCollisionUpdate += PhysicsCollision;
4787 PhysActor.SubscribeEvents(1000);
4788 }
4789 } 4667 }
4668
4790 else // it already has a physical representation 4669 else // it already has a physical representation
4791 { 4670 {
4792 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. 4671 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status.
4793 4672
4794 if (!ParentGroup.IsDeleted) 4673 if(VolumeDetectActive)
4795 { 4674 pa.SetVolumeDetect(1);
4796 if (LocalId == ParentGroup.RootPart.LocalId) 4675 else
4797 { 4676 pa.SetVolumeDetect(0);
4798 ParentGroup.CheckSculptAndLoad();
4799 }
4800 }
4801 }
4802 }
4803 }
4804 4677
4805 PhysicsActor pa = PhysActor; 4678 if (pa.Building != building)
4806 if (SetVD) 4679 pa.Building = building;
4807 { 4680 }
4808 // If the above logic worked (this is urgent candidate to unit tests!)
4809 // we now have a physicsactor.
4810 // Defensive programming calls for a check here.
4811 // Better would be throwing an exception that could be catched by a unit test as the internal
4812 // logic should make sure, this Physactor is always here.
4813 if (pa != null)
4814 {
4815 pa.SetVolumeDetect(1);
4816// AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active
4817 this.VolumeDetectActive = true;
4818 }
4819 }
4820 else
4821 {
4822 // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like
4823 // (mumbles, well, at least if you have infinte CPU powers :-))
4824 if (pa != null)
4825 {
4826 pa.SetVolumeDetect(0);
4827 this.VolumeDetectActive = false;
4828 } 4681 }
4829 } 4682 }
4830
4831 if (SetTemporary)
4832 {
4833 AddFlag(PrimFlags.TemporaryOnRez);
4834 }
4835 else
4836 {
4837 RemFlag(PrimFlags.TemporaryOnRez);
4838 }
4839 4683
4840 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString()); 4684 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4841 4685
4842 // and last in case we have a new actor and not building 4686 // and last in case we have a new actor and not building
4843 if (pa != null && pa.Building != building) 4687
4844 pa.Building = building;
4845 if (ParentGroup != null) 4688 if (ParentGroup != null)
4846 { 4689 {
4847 ParentGroup.HasGroupChanged = true; 4690 ParentGroup.HasGroupChanged = true;
@@ -4853,48 +4696,104 @@ namespace OpenSim.Region.Framework.Scenes
4853 4696
4854 /// <summary> 4697 /// <summary>
4855 /// Adds this part to the physics scene. 4698 /// Adds this part to the physics scene.
4699 /// and sets the PhysActor property
4856 /// </summary> 4700 /// </summary>
4857 /// <remarks>This method also sets the PhysActor property.</remarks> 4701 /// <param name="isPhysical">Add this prim as physical.</param>
4858 /// <param name="rigidBody">Add this prim with a rigid body.</param> 4702 /// <param name="isPhantom">Add this prim as phantom.</param>
4859 /// <returns> 4703 /// <param name="building">tells physics to delay full construction of object</param>
4860 /// The physics actor. null if there was a failure. 4704 /// <param name="applyDynamics">applies velocities, force and torque</param>
4861 /// </returns> 4705 private void AddToPhysics(bool isPhysical, bool isPhantom, bool building, bool applyDynamics)
4862 private PhysicsActor AddToPhysics(bool rigidBody) 4706 {
4863 {
4864 PhysicsActor pa; 4707 PhysicsActor pa;
4865 4708
4709 Vector3 velocity = Velocity;
4710 Vector3 rotationalVelocity = AngularVelocity;;
4711
4866 try 4712 try
4867 { 4713 {
4868 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape( 4714 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape(
4869 string.Format("{0}/{1}", Name, UUID), 4715 string.Format("{0}/{1}", Name, UUID),
4870 Shape, 4716 Shape,
4871 AbsolutePosition, 4717 AbsolutePosition,
4872 Scale, 4718 Scale,
4873 RotationOffset, 4719 GetWorldRotation(),
4874 rigidBody, 4720 isPhysical,
4875 m_localId); 4721 isPhantom,
4722 PhysicsShapeType,
4723 m_localId);
4876 } 4724 }
4877 catch 4725 catch (Exception ex)
4878 { 4726 {
4879 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom.", m_uuid); 4727 m_log.ErrorFormat("[SCENE]: AddToPhysics object {0} failed: {1}", m_uuid, ex.Message);
4880 pa = null; 4728 pa = null;
4881 } 4729 }
4882 4730
4883 // FIXME: Ideally we wouldn't set the property here to reduce situations where threads changing physical
4884 // properties can stop on each other. However, DoPhysicsPropertyUpdate() currently relies on PhysActor
4885 // being set.
4886 PhysActor = pa;
4887
4888 // Basic Physics can also return null as well as an exception catch.
4889 if (pa != null) 4731 if (pa != null)
4890 { 4732 {
4891 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info 4733 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
4892 pa.SetMaterial(Material); 4734 pa.SetMaterial(Material);
4893 DoPhysicsPropertyUpdate(rigidBody, true); 4735
4736 if (VolumeDetectActive) // change if not the default only
4737 pa.SetVolumeDetect(1);
4738
4739 if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
4740 m_vehicle.SetVehicle(pa);
4741
4742 // we are going to tell rest of code about physics so better have this here
4743 PhysActor = pa;
4744
4745 // DoPhysicsPropertyUpdate(isPhysical, true);
4746 // lets expand it here just with what it really needs to do
4747
4748 if (isPhysical)
4749 {
4750 if (ParentGroup.RootPart.KeyframeMotion != null)
4751 ParentGroup.RootPart.KeyframeMotion.Stop();
4752 ParentGroup.RootPart.KeyframeMotion = null;
4753 ParentGroup.Scene.AddPhysicalPrim(1);
4754
4755 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
4756 pa.OnOutOfBounds += PhysicsOutOfBounds;
4757
4758 if (ParentID != 0 && ParentID != LocalId)
4759 {
4760 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
4761
4762 if (parentPa != null)
4763 {
4764 pa.link(parentPa);
4765 }
4766 }
4767 }
4768
4769 if (applyDynamics)
4770 // do independent of isphysical so parameters get setted (at least some)
4771 {
4772 Velocity = velocity;
4773 AngularVelocity = rotationalVelocity;
4774 pa.Velocity = velocity;
4775 pa.RotationalVelocity = rotationalVelocity;
4776
4777 // if not vehicle and root part apply force and torque
4778 if ((m_vehicle == null || m_vehicle.Type == Vehicle.TYPE_NONE)
4779 && LocalId == ParentGroup.RootPart.LocalId)
4780 {
4781 pa.Force = Force;
4782 pa.Torque = Torque;
4783 }
4784 }
4785
4786 if (Shape.SculptEntry)
4787 CheckSculptAndLoad();
4788 else
4789 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
4790
4791 if (!building)
4792 pa.Building = false;
4894 } 4793 }
4895 4794
4896 return pa; 4795 PhysActor = pa;
4897 } 4796 }
4898 4797
4899 /// <summary> 4798 /// <summary>
4900 /// This removes the part from the physics scene. 4799 /// This removes the part from the physics scene.
@@ -5103,10 +5002,6 @@ namespace OpenSim.Region.Framework.Scenes
5103 PhysicsActor pa = PhysActor; 5002 PhysicsActor pa = PhysActor;
5104 if (pa != null) 5003 if (pa != null)
5105 { 5004 {
5106 const scriptEvents NeededSubsEvents = (
5107 scriptEvents.collision | scriptEvents.collision_start| scriptEvents.collision_end |
5108 scriptEvents.land_collision | scriptEvents.land_collision_start | scriptEvents.land_collision_end
5109 );
5110 if ( 5005 if (
5111// ((AggregateScriptEvents & scriptEvents.collision) != 0) || 5006// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
5112// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || 5007// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
@@ -5114,7 +5009,7 @@ namespace OpenSim.Region.Framework.Scenes
5114// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || 5009// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
5115// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || 5010// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
5116// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || 5011// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
5117 ((AggregateScriptEvents & NeededSubsEvents) != 0) || (CollisionSound != UUID.Zero) 5012 ((AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
5118 ) 5013 )
5119 { 5014 {
5120 // subscribe to physics updates. 5015 // subscribe to physics updates.
diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
index 3e2b71c..77ea2af 100644
--- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
@@ -179,6 +179,8 @@ namespace OpenSim.Region.Physics.OdePlugin
179 public bool m_outofBounds; 179 public bool m_outofBounds;
180 private float m_density = 10.000006836f; // Aluminum g/cm3; 180 private float m_density = 10.000006836f; // Aluminum g/cm3;
181 181
182 private float m_primMass = 10.000006836f; // Aluminum g/cm3;
183
182 private byte m_shapetype; 184 private byte m_shapetype;
183 private byte m_taintshapetype; 185 private byte m_taintshapetype;
184 186
@@ -538,7 +540,11 @@ namespace OpenSim.Region.Physics.OdePlugin
538 540
539 public override float Mass 541 public override float Mass
540 { 542 {
541 get { return CalculateMass(); } 543 get
544 {
545 CalculateMass();
546 return m_primMass;
547 }
542 } 548 }
543 549
544 public override Vector3 Force 550 public override Vector3 Force
@@ -1316,6 +1322,9 @@ namespace OpenSim.Region.Physics.OdePlugin
1316 1322
1317 1323
1318 1324
1325 m_primMass = returnMass;
1326 if (m_primMass > _parent_scene.maximumMassObject)
1327 m_primMass = _parent_scene.maximumMassObject;
1319 1328
1320 // Recursively calculate mass 1329 // Recursively calculate mass
1321 bool HasChildPrim = false; 1330 bool HasChildPrim = false;
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
index c4dc793..f739183 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
@@ -395,7 +395,7 @@ namespace OpenSim.Region.Physics.OdePlugin
395 395
396 public override float Mass 396 public override float Mass
397 { 397 {
398 get { return _mass; } 398 get { return primMass; }
399 } 399 }
400 400
401 public override Vector3 Force 401 public override Vector3 Force
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs
index 2b6bc59..f5129cb 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs
@@ -107,16 +107,17 @@ namespace OdeAPI
107 ConvexClass, 107 ConvexClass,
108 GeomTransformClass, 108 GeomTransformClass,
109 TriMeshClass, 109 TriMeshClass,
110 HeightfieldClass, 110 HeightfieldClass,
111 FirstSpaceClass, 111 FirstSpaceClass,
112 SimpleSpaceClass = FirstSpaceClass, 112 SimpleSpaceClass = FirstSpaceClass,
113 HashSpaceClass, 113 HashSpaceClass,
114 QuadTreeSpaceClass, 114 QuadTreeSpaceClass,
115 LastSpaceClass = QuadTreeSpaceClass, 115 LastSpaceClass = QuadTreeSpaceClass,
116 UbitTerrainClass,
116 FirstUserClass, 117 FirstUserClass,
117 LastUserClass = FirstUserClass + MaxUserClasses - 1, 118 LastUserClass = FirstUserClass + MaxUserClasses - 1,
118 NumClasses, 119 NumClasses,
119 MaxUserClasses = 4 120 MaxUserClasses = 5
120 } 121 }
121 122
122 public enum JointType : int 123 public enum JointType : int
@@ -201,8 +202,11 @@ namespace OdeAPI
201 [UnmanagedFunctionPointer(CallingConvention.Cdecl)] 202 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
202 public delegate void GeomDtorFn(IntPtr o); 203 public delegate void GeomDtorFn(IntPtr o);
203 204
204 [UnmanagedFunctionPointer(CallingConvention.Cdecl)] 205 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
205 public delegate dReal HeightfieldGetHeight(IntPtr p_user_data, int x, int z); 206 public delegate dReal HeightfieldGetHeight(IntPtr p_user_data, int x, int z);
207
208 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
209 public delegate dReal UbitTerrainGetHeight(IntPtr p_user_data, int x, int z);
206 210
207 [UnmanagedFunctionPointer(CallingConvention.Cdecl)] 211 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
208 public delegate void NearCallback(IntPtr data, IntPtr geom1, IntPtr geom2); 212 public delegate void NearCallback(IntPtr data, IntPtr geom1, IntPtr geom2);
@@ -729,6 +733,18 @@ namespace OdeAPI
729 return CreateiHeightfield(space, data, bPlaceable); 733 return CreateiHeightfield(space, data, bPlaceable);
730 } 734 }
731 735
736 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateUbitTerrain"), SuppressUnmanagedCodeSecurity]
737 public static extern IntPtr CreateiUbitTerrain(IntPtr space, IntPtr data, int bPlaceable);
738 public static IntPtr CreateUbitTerrain(IntPtr space, IntPtr data, int bPlaceable)
739 {
740 NTotalGeoms++;
741 return CreateiUbitTerrain(space, data, bPlaceable);
742 }
743
744
745
746
747
732 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateGeom"), SuppressUnmanagedCodeSecurity] 748 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateGeom"), SuppressUnmanagedCodeSecurity]
733 public static extern IntPtr CreateiGeom(int classnum); 749 public static extern IntPtr CreateiGeom(int classnum);
734 public static IntPtr CreateGeom(int classnum) 750 public static IntPtr CreateGeom(int classnum)
@@ -964,6 +980,8 @@ namespace OdeAPI
964 dReal width, dReal depth, int widthSamples, int depthSamples, 980 dReal width, dReal depth, int widthSamples, int depthSamples,
965 dReal scale, dReal offset, dReal thickness, int bWrap); 981 dReal scale, dReal offset, dReal thickness, int bWrap);
966 982
983
984
967 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildDouble"), SuppressUnmanagedCodeSecurity] 985 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildDouble"), SuppressUnmanagedCodeSecurity]
968 public static extern void GeomHeightfieldDataBuildDouble(IntPtr d, double[] pHeightData, int bCopyHeightData, 986 public static extern void GeomHeightfieldDataBuildDouble(IntPtr d, double[] pHeightData, int bCopyHeightData,
969 dReal width, dReal depth, int widthSamples, int depthSamples, 987 dReal width, dReal depth, int widthSamples, int depthSamples,
@@ -989,6 +1007,33 @@ namespace OdeAPI
989 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldSetHeightfieldData"), SuppressUnmanagedCodeSecurity] 1007 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldSetHeightfieldData"), SuppressUnmanagedCodeSecurity]
990 public static extern void GeomHeightfieldSetHeightfieldData(IntPtr g, IntPtr d); 1008 public static extern void GeomHeightfieldSetHeightfieldData(IntPtr g, IntPtr d);
991 1009
1010
1011 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomUbitTerrainDataBuild"), SuppressUnmanagedCodeSecurity]
1012 public static extern void GeomUbitTerrainDataBuild(IntPtr d, float[] pHeightData, int bCopyHeightData,
1013 dReal sampleSize, int widthSamples, int depthSamples,
1014 dReal offset, dReal thickness, int bWrap);
1015
1016 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomUbitTerrainDataBuild"), SuppressUnmanagedCodeSecurity]
1017 public static extern void GeomUbitTerrainDataBuild(IntPtr d, IntPtr pHeightData, int bCopyHeightData,
1018 dReal sampleSize, int widthSamples, int depthSamples,
1019 dReal thickness, int bWrap);
1020
1021 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomUbitTerrainDataCreate"), SuppressUnmanagedCodeSecurity]
1022 public static extern IntPtr GeomUbitTerrainDataCreate();
1023
1024 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomUbitTerrainDataDestroy"), SuppressUnmanagedCodeSecurity]
1025 public static extern void GeomUbitTerrainDataDestroy(IntPtr d);
1026
1027 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomUbitTerrainDataSetBounds"), SuppressUnmanagedCodeSecurity]
1028 public static extern void GeomUbitTerrainDataSetBounds(IntPtr d, dReal minHeight, dReal maxHeight);
1029
1030 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomUbitTerrainGetHeightfieldData"), SuppressUnmanagedCodeSecurity]
1031 public static extern IntPtr GeomUbitTerrainGetHeightfieldData(IntPtr g);
1032
1033 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomUbitTerrainSetHeightfieldData"), SuppressUnmanagedCodeSecurity]
1034 public static extern void GeomUbitTerrainSetHeightfieldData(IntPtr g, IntPtr d);
1035
1036
992 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomIsEnabled"), SuppressUnmanagedCodeSecurity] 1037 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomIsEnabled"), SuppressUnmanagedCodeSecurity]
993 public static extern bool GeomIsEnabled(IntPtr geom); 1038 public static extern bool GeomIsEnabled(IntPtr geom);
994 1039
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
index 1a6907d..3e0ccef 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
@@ -156,6 +156,7 @@ namespace OpenSim.Region.Physics.OdePlugin
156 private readonly ILog m_log; 156 private readonly ILog m_log;
157 // private Dictionary<string, sCollisionData> m_storedCollisions = new Dictionary<string, sCollisionData>(); 157 // private Dictionary<string, sCollisionData> m_storedCollisions = new Dictionary<string, sCollisionData>();
158 158
159 public bool OdeUbitLib = false;
159// private int threadid = 0; 160// private int threadid = 0;
160 private Random fluidRandomizer = new Random(Environment.TickCount); 161 private Random fluidRandomizer = new Random(Environment.TickCount);
161 162
@@ -374,7 +375,14 @@ namespace OpenSim.Region.Physics.OdePlugin
374 mesher = meshmerizer; 375 mesher = meshmerizer;
375 m_config = config; 376 m_config = config;
376 377
377// m_log.WarnFormat("ODE configuration: {0}", d.GetConfiguration("ODE")); 378 string ode_config = d.GetConfiguration("ODE");
379 m_log.WarnFormat("ODE configuration: {0}", ode_config);
380
381 if (ode_config.Contains("ODE_Ubit"))
382 {
383 OdeUbitLib = true;
384 }
385
378 /* 386 /*
379 if (region != null) 387 if (region != null)
380 { 388 {
@@ -527,13 +535,24 @@ namespace OpenSim.Region.Physics.OdePlugin
527 535
528 // sets a global contact for a joint for contactgeom , and base contact description) 536 // sets a global contact for a joint for contactgeom , and base contact description)
529 537
530 private IntPtr CreateContacJoint(ref d.ContactGeom contactGeom, float mu, float bounce,float cfm,float erp) 538 private IntPtr CreateContacJoint(ref d.ContactGeom contactGeom, float mu, float bounce, float cfm, float erpscale, float dscale)
531 { 539 {
532 if (GlobalContactsArray == IntPtr.Zero || m_global_contactcount >= maxContactsbeforedeath) 540 if (GlobalContactsArray == IntPtr.Zero || m_global_contactcount >= maxContactsbeforedeath)
533 return IntPtr.Zero; 541 return IntPtr.Zero;
534 542
543 float erp = contactGeom.depth;
544 erp *= erpscale;
545 if (erp < minERP)
546 erp = minERP;
547 else if (erp > MaxERP)
548 erp = MaxERP;
549
550 float depth = contactGeom.depth * dscale;
551 if (depth > 0.5f)
552 depth = 0.5f;
553
535 d.Contact newcontact = new d.Contact(); 554 d.Contact newcontact = new d.Contact();
536 newcontact.geom.depth = contactGeom.depth; 555 newcontact.geom.depth = depth;
537 newcontact.geom.g1 = contactGeom.g1; 556 newcontact.geom.g1 = contactGeom.g1;
538 newcontact.geom.g2 = contactGeom.g2; 557 newcontact.geom.g2 = contactGeom.g2;
539 newcontact.geom.pos = contactGeom.pos; 558 newcontact.geom.pos = contactGeom.pos;
@@ -692,6 +711,10 @@ namespace OpenSim.Region.Physics.OdePlugin
692 float bounce = 0; 711 float bounce = 0;
693 float cfm = 0.0001f; 712 float cfm = 0.0001f;
694 float erp = 0.1f; 713 float erp = 0.1f;
714 float erpscale = 1.0f;
715 float dscale = 1.0f;
716 bool IgnoreNegSides = false;
717
695 718
696 ContactData contactdata1 = new ContactData(0, 0, false); 719 ContactData contactdata1 = new ContactData(0, 0, false);
697 ContactData contactdata2 = new ContactData(0, 0, false); 720 ContactData contactdata2 = new ContactData(0, 0, false);
@@ -781,10 +804,14 @@ namespace OpenSim.Region.Physics.OdePlugin
781 cfm = p1.Mass; 804 cfm = p1.Mass;
782 if (cfm > p2.Mass) 805 if (cfm > p2.Mass)
783 cfm = p2.Mass; 806 cfm = p2.Mass;
784 cfm = (float)Math.Sqrt(cfm); 807 dscale = 10 / cfm;
785 cfm *= 0.0001f; 808 dscale = (float)Math.Sqrt(dscale);
786 if (cfm > 0.8f) 809 if (dscale > 1.0f)
787 cfm = 0.8f; 810 dscale = 1.0f;
811 erpscale = cfm * 0.01f;
812 cfm = 0.0001f / cfm;
813 if (cfm > 0.01f)
814 cfm = 0.01f;
788 815
789 if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f)) 816 if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f))
790 mu *= frictionMovementMult; 817 mu *= frictionMovementMult;
@@ -801,11 +828,22 @@ namespace OpenSim.Region.Physics.OdePlugin
801 if (Math.Abs(p1.Velocity.X) > 0.1f || Math.Abs(p1.Velocity.Y) > 0.1f) 828 if (Math.Abs(p1.Velocity.X) > 0.1f || Math.Abs(p1.Velocity.Y) > 0.1f)
802 mu *= frictionMovementMult; 829 mu *= frictionMovementMult;
803 p1.CollidingGround = true; 830 p1.CollidingGround = true;
831
804 cfm = p1.Mass; 832 cfm = p1.Mass;
805 cfm = (float)Math.Sqrt(cfm); 833 dscale = 10 / cfm;
806 cfm *= 0.0001f; 834 dscale = (float)Math.Sqrt(dscale);
807 if (cfm > 0.8f) 835 if (dscale > 1.0f)
808 cfm = 0.8f; 836 dscale = 1.0f;
837 erpscale = cfm * 0.01f;
838 cfm = 0.0001f / cfm;
839 if (cfm > 0.01f)
840 cfm = 0.01f;
841
842 if (d.GeomGetClass(g1) == d.GeomClassID.TriMeshClass)
843 {
844 if (curContact.side1 > 0)
845 IgnoreNegSides = true;
846 }
809 847
810 } 848 }
811 else if (name == "Water") 849 else if (name == "Water")
@@ -830,11 +868,21 @@ namespace OpenSim.Region.Physics.OdePlugin
830 p2.getContactData(ref contactdata2); 868 p2.getContactData(ref contactdata2);
831 bounce = contactdata2.bounce * TerrainBounce; 869 bounce = contactdata2.bounce * TerrainBounce;
832 mu = (float)Math.Sqrt(contactdata2.mu * TerrainFriction); 870 mu = (float)Math.Sqrt(contactdata2.mu * TerrainFriction);
871
833 cfm = p2.Mass; 872 cfm = p2.Mass;
834 cfm = (float)Math.Sqrt(cfm); 873 dscale = 10 / cfm;
835 cfm *= 0.0001f; 874 dscale = (float)Math.Sqrt(dscale);
836 if (cfm > 0.8f) 875
837 cfm = 0.8f; 876 if (dscale > 1.0f)
877 dscale = 1.0f;
878
879 erpscale = cfm * 0.01f;
880 cfm = 0.0001f / cfm;
881 if (cfm > 0.01f)
882 cfm = 0.01f;
883
884 if (curContact.side1 > 0) // should be 2 ?
885 IgnoreNegSides = true;
838 886
839 if (Math.Abs(p2.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y) > 0.1f) 887 if (Math.Abs(p2.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y) > 0.1f)
840 mu *= frictionMovementMult; 888 mu *= frictionMovementMult;
@@ -862,39 +910,45 @@ namespace OpenSim.Region.Physics.OdePlugin
862 int i = 0; 910 int i = 0;
863 while(true) 911 while(true)
864 { 912 {
865 if (dop1foot && (p1.Position.Z - curContact.pos.Z) > (p1.Size.Z - avCapRadius) * 0.5f)
866 p1.IsColliding = true;
867 if (dop2foot && (p2.Position.Z - curContact.pos.Z) > (p2.Size.Z - avCapRadius) * 0.5f)
868 p2.IsColliding = true;
869 913
914 if (IgnoreNegSides && curContact.side1 < 0)
915 {
916 if (++i >= count)
917 break;
870 918
871 erp = curContact.depth; 919 if (!GetCurContactGeom(i, ref curContact))
872 if (erp < minERP) 920 break;
873 erp = minERP; 921 }
874 else if (erp > MaxERP) 922 else
875 erp = MaxERP;
876 923
877 Joint = CreateContacJoint(ref curContact, mu, bounce,cfm,erp); 924 {
878 d.JointAttach(Joint, b1, b2); 925 if (dop1foot && (p1.Position.Z - curContact.pos.Z) > (p1.Size.Z - avCapRadius) * 0.5f)
926 p1.IsColliding = true;
927 if (dop2foot && (p2.Position.Z - curContact.pos.Z) > (p2.Size.Z - avCapRadius) * 0.5f)
928 p2.IsColliding = true;
879 929
880 if (++m_global_contactcount >= maxContactsbeforedeath) 930 Joint = CreateContacJoint(ref curContact, mu, bounce, cfm, erpscale, dscale);
881 break; 931 d.JointAttach(Joint, b1, b2);
882 932
883 if(++i >= count) 933 if (++m_global_contactcount >= maxContactsbeforedeath)
884 break; 934 break;
885 935
886 if (!GetCurContactGeom(i, ref curContact)) 936 if (++i >= count)
887 break; 937 break;
888 938
889 if (curContact.depth > maxDepthContact.PenetrationDepth) 939 if (!GetCurContactGeom(i, ref curContact))
890 { 940 break;
891 maxDepthContact.Position.X = curContact.pos.X; 941
892 maxDepthContact.Position.Y = curContact.pos.Y; 942 if (curContact.depth > maxDepthContact.PenetrationDepth)
893 maxDepthContact.Position.Z = curContact.pos.Z; 943 {
894 maxDepthContact.SurfaceNormal.X = curContact.normal.X; 944 maxDepthContact.Position.X = curContact.pos.X;
895 maxDepthContact.SurfaceNormal.Y = curContact.normal.Y; 945 maxDepthContact.Position.Y = curContact.pos.Y;
896 maxDepthContact.SurfaceNormal.Z = curContact.normal.Z; 946 maxDepthContact.Position.Z = curContact.pos.Z;
897 maxDepthContact.PenetrationDepth = curContact.depth; 947 maxDepthContact.SurfaceNormal.X = curContact.normal.X;
948 maxDepthContact.SurfaceNormal.Y = curContact.normal.Y;
949 maxDepthContact.SurfaceNormal.Z = curContact.normal.Z;
950 maxDepthContact.PenetrationDepth = curContact.depth;
951 }
898 } 952 }
899 } 953 }
900 954
@@ -1865,13 +1919,12 @@ namespace OpenSim.Region.Physics.OdePlugin
1865 1919
1866 public float GetTerrainHeightAtXY(float x, float y) 1920 public float GetTerrainHeightAtXY(float x, float y)
1867 { 1921 {
1868 // assumes 1m size grid and constante size square regions 1922
1869 // needs to know about sims around in future
1870 // region offset in mega position
1871 1923
1872 int offsetX = ((int)(x / (int)Constants.RegionSize)) * (int)Constants.RegionSize; 1924 int offsetX = ((int)(x / (int)Constants.RegionSize)) * (int)Constants.RegionSize;
1873 int offsetY = ((int)(y / (int)Constants.RegionSize)) * (int)Constants.RegionSize; 1925 int offsetY = ((int)(y / (int)Constants.RegionSize)) * (int)Constants.RegionSize;
1874 1926
1927
1875 IntPtr heightFieldGeom = IntPtr.Zero; 1928 IntPtr heightFieldGeom = IntPtr.Zero;
1876 1929
1877 // get region map 1930 // get region map
@@ -1903,28 +1956,55 @@ namespace OpenSim.Region.Physics.OdePlugin
1903 1956
1904 int regsize = (int)Constants.RegionSize + 3; // map size see setterrain number of samples 1957 int regsize = (int)Constants.RegionSize + 3; // map size see setterrain number of samples
1905 1958
1906 // we still have square fixed size regions 1959 if (OdeUbitLib)
1907 // also flip x and y because of how map is done for ODE fliped axis
1908 // so ix,iy,dx and dy are inter exchanged
1909 if (x < regsize - 1)
1910 {
1911 iy = (int)x;
1912 dy = x - (float)iy;
1913 }
1914 else // out world use external height
1915 { 1960 {
1916 iy = regsize - 1; 1961 if (x < regsize - 1)
1917 dy = 0; 1962 {
1918 } 1963 ix = (int)x;
1919 if (y < regsize - 1) 1964 dx = x - (float)ix;
1920 { 1965 }
1921 ix = (int)y; 1966 else // out world use external height
1922 dx = y - (float)ix; 1967 {
1968 ix = regsize - 1;
1969 dx = 0;
1970 }
1971 if (y < regsize - 1)
1972 {
1973 iy = (int)y;
1974 dy = y - (float)iy;
1975 }
1976 else
1977 {
1978 iy = regsize - 1;
1979 dy = 0;
1980 }
1923 } 1981 }
1982
1924 else 1983 else
1925 { 1984 {
1926 ix = regsize - 1; 1985 // we still have square fixed size regions
1927 dx = 0; 1986 // also flip x and y because of how map is done for ODE fliped axis
1987 // so ix,iy,dx and dy are inter exchanged
1988 if (x < regsize - 1)
1989 {
1990 iy = (int)x;
1991 dy = x - (float)iy;
1992 }
1993 else // out world use external height
1994 {
1995 iy = regsize - 1;
1996 dy = 0;
1997 }
1998 if (y < regsize - 1)
1999 {
2000 ix = (int)y;
2001 dx = y - (float)ix;
2002 }
2003 else
2004 {
2005 ix = regsize - 1;
2006 dx = 0;
2007 }
1928 } 2008 }
1929 2009
1930 float h0; 2010 float h0;
@@ -1951,6 +2031,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1951 2031
1952 return h0 + h1 + h2; 2032 return h0 + h1 + h2;
1953 } 2033 }
2034
2035
1954 public override void SetTerrain(float[] heightMap) 2036 public override void SetTerrain(float[] heightMap)
1955 { 2037 {
1956 if (m_worldOffset != Vector3.Zero && m_parentScene != null) 2038 if (m_worldOffset != Vector3.Zero && m_parentScene != null)
@@ -1972,7 +2054,15 @@ namespace OpenSim.Region.Physics.OdePlugin
1972 } 2054 }
1973 2055
1974 public void SetTerrain(float[] heightMap, Vector3 pOffset) 2056 public void SetTerrain(float[] heightMap, Vector3 pOffset)
1975 { 2057 {
2058 if (OdeUbitLib)
2059 UbitSetTerrain(heightMap, pOffset);
2060 else
2061 OriSetTerrain(heightMap, pOffset);
2062 }
2063
2064 public void OriSetTerrain(float[] heightMap, Vector3 pOffset)
2065 {
1976 // assumes 1m size grid and constante size square regions 2066 // assumes 1m size grid and constante size square regions
1977 // needs to know about sims around in future 2067 // needs to know about sims around in future
1978 2068
@@ -2086,6 +2176,108 @@ namespace OpenSim.Region.Physics.OdePlugin
2086 } 2176 }
2087 } 2177 }
2088 2178
2179 public void UbitSetTerrain(float[] heightMap, Vector3 pOffset)
2180 {
2181 // assumes 1m size grid and constante size square regions
2182 // needs to know about sims around in future
2183
2184 float[] _heightmap;
2185
2186 uint heightmapWidth = Constants.RegionSize + 2;
2187 uint heightmapHeight = Constants.RegionSize + 2;
2188
2189 uint heightmapWidthSamples = heightmapWidth + 1;
2190 uint heightmapHeightSamples = heightmapHeight + 1;
2191
2192 _heightmap = new float[heightmapWidthSamples * heightmapHeightSamples];
2193
2194
2195 uint regionsize = Constants.RegionSize;
2196
2197 float hfmin = float.MaxValue;
2198// float hfmax = float.MinValue;
2199 float val;
2200
2201
2202 uint maxXXYY = regionsize - 1;
2203 // adding one margin all around so things don't fall in edges
2204
2205 uint xx;
2206 uint yy = 0;
2207 uint yt = 0;
2208
2209 for (uint y = 0; y < heightmapHeightSamples; y++)
2210 {
2211 if (y > 1 && y < maxXXYY)
2212 yy += regionsize;
2213 xx = 0;
2214 for (uint x = 0; x < heightmapWidthSamples; x++)
2215 {
2216 if (x > 1 && x < maxXXYY)
2217 xx++;
2218
2219 val = heightMap[yy + xx];
2220 if (val < 0.0f)
2221 val = 0.0f; // no neg terrain as in chode
2222 _heightmap[yt + x] = val;
2223
2224 if (hfmin > val)
2225 hfmin = val;
2226// if (hfmax < val)
2227// hfmax = val;
2228 }
2229 yt += heightmapWidthSamples;
2230 }
2231 lock (OdeLock)
2232 {
2233 IntPtr GroundGeom = IntPtr.Zero;
2234 if (RegionTerrain.TryGetValue(pOffset, out GroundGeom))
2235 {
2236 RegionTerrain.Remove(pOffset);
2237 if (GroundGeom != IntPtr.Zero)
2238 {
2239 if (TerrainHeightFieldHeights.ContainsKey(GroundGeom))
2240 {
2241 TerrainHeightFieldHeightsHandlers[GroundGeom].Free();
2242 TerrainHeightFieldHeightsHandlers.Remove(GroundGeom);
2243 TerrainHeightFieldHeights.Remove(GroundGeom);
2244 }
2245 d.SpaceRemove(StaticSpace, GroundGeom);
2246 d.GeomDestroy(GroundGeom);
2247 }
2248 }
2249 IntPtr HeightmapData = d.GeomHeightfieldDataCreate();
2250
2251 const int wrap = 0;
2252 float thickness = hfmin;
2253 if (thickness < 0)
2254 thickness = 1;
2255
2256 GCHandle _heightmaphandler = GCHandle.Alloc(_heightmap, GCHandleType.Pinned);
2257
2258 d.GeomUbitTerrainDataBuild(HeightmapData, _heightmaphandler.AddrOfPinnedObject(), 0, 1.0f,
2259 (int)heightmapWidthSamples, (int)heightmapHeightSamples,
2260 thickness, wrap);
2261
2262// d.GeomUbitTerrainDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1);
2263 GroundGeom = d.CreateUbitTerrain(StaticSpace, HeightmapData, 1);
2264 if (GroundGeom != IntPtr.Zero)
2265 {
2266 d.GeomSetCategoryBits(GroundGeom, (int)(CollisionCategories.Land));
2267 d.GeomSetCollideBits(GroundGeom, (int)(CollisionCategories.Space));
2268
2269 }
2270 geom_name_map[GroundGeom] = "Terrain";
2271
2272 d.GeomSetPosition(GroundGeom, pOffset.X + (float)Constants.RegionSize * 0.5f, pOffset.Y + (float)Constants.RegionSize * 0.5f, 0);
2273 RegionTerrain.Add(pOffset, GroundGeom, GroundGeom);
2274 // TerrainHeightFieldHeights.Add(GroundGeom, ODElandMap);
2275 TerrainHeightFieldHeights.Add(GroundGeom, _heightmap);
2276 TerrainHeightFieldHeightsHandlers.Add(GroundGeom, _heightmaphandler);
2277 }
2278 }
2279
2280
2089 public override void DeleteTerrain() 2281 public override void DeleteTerrain()
2090 { 2282 {
2091 } 2283 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 783650c..23158b9 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -3176,17 +3176,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3176 } 3176 }
3177 else 3177 else
3178 { 3178 {
3179 if (m_host.IsRoot) 3179 // new SL always returns object mass
3180 { 3180// if (m_host.IsRoot)
3181// {
3181 return m_host.ParentGroup.GetMass(); 3182 return m_host.ParentGroup.GetMass();
3182 } 3183// }
3183 else 3184// else
3184 { 3185// {
3185 return m_host.GetMass(); 3186// return m_host.GetMass();
3186 } 3187// }
3187 } 3188 }
3188 } 3189 }
3189 3190
3191
3192 public LSL_Float llGetMassMKS()
3193 {
3194 return 100f * llGetMass();
3195 }
3196
3190 public void llCollisionFilter(string name, string id, int accept) 3197 public void llCollisionFilter(string name, string id, int accept)
3191 { 3198 {
3192 m_host.AddScriptLPS(1); 3199 m_host.AddScriptLPS(1);
@@ -4959,7 +4966,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4959 { 4966 {
4960 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4967 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4961 float distance_term = distance * distance * distance; // Script Energy 4968 float distance_term = distance * distance * distance; // Script Energy
4962 float pusher_mass = m_host.GetMass(); 4969 // use total object mass and not part
4970 float pusher_mass = m_host.ParentGroup.GetMass();
4963 4971
4964 float PUSH_ATTENUATION_DISTANCE = 17f; 4972 float PUSH_ATTENUATION_DISTANCE = 17f;
4965 float PUSH_ATTENUATION_SCALE = 5f; 4973 float PUSH_ATTENUATION_SCALE = 5f;
@@ -9964,9 +9972,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9964 { 9972 {
9965 try 9973 try
9966 { 9974 {
9975 /*
9967 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 9976 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9968 if (obj != null) 9977 if (obj != null)
9969 return (double)obj.GetMass(); 9978 return (double)obj.GetMass();
9979 */
9980 // return total object mass
9981 SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
9982 if (obj != null)
9983 return (double)obj.GetMass();
9984
9970 // the object is null so the key is for an avatar 9985 // the object is null so the key is for an avatar
9971 ScenePresence avatar = World.GetScenePresence(key); 9986 ScenePresence avatar = World.GetScenePresence(key);
9972 if (avatar != null) 9987 if (avatar != null)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index b976dc3..5c528977 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -148,7 +148,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
148 LSL_Vector llGetLocalPos(); 148 LSL_Vector llGetLocalPos();
149 LSL_Rotation llGetLocalRot(); 149 LSL_Rotation llGetLocalRot();
150 LSL_Float llGetMass(); 150 LSL_Float llGetMass();
151 void llGetNextEmail(string address, string subject); 151 LSL_Float llGetMassMKS();
152 void llGetNextEmail(string address, string subject);
152 LSL_String llGetNotecardLine(string name, int line); 153 LSL_String llGetNotecardLine(string name, int line);
153 LSL_Key llGetNumberOfNotecardLines(string name); 154 LSL_Key llGetNumberOfNotecardLines(string name);
154 LSL_Integer llGetNumberOfPrims(); 155 LSL_Integer llGetNumberOfPrims();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index bf58d13..70c5fcd 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -581,6 +581,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
581 return m_LSL_Functions.llGetMass(); 581 return m_LSL_Functions.llGetMass();
582 } 582 }
583 583
584 public LSL_Float llGetMassMKS()
585 {
586 return m_LSL_Functions.llGetMassMKS();
587 }
588
584 public void llGetNextEmail(string address, string subject) 589 public void llGetNextEmail(string address, string subject)
585 { 590 {
586 m_LSL_Functions.llGetNextEmail(address, subject); 591 m_LSL_Functions.llGetNextEmail(address, subject);