aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs9
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs126
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs457
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdeScene.cs3
5 files changed, 351 insertions, 247 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index cb0a57a..2882463 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -2673,6 +2673,7 @@ namespace OpenSim.Region.Framework.Scenes
2673 } 2673 }
2674 2674
2675 linkPart.LinkNum = linkNum++; 2675 linkPart.LinkNum = linkNum++;
2676 linkPart.UpdatePrimFlags(UsesPhysics, IsTemporary, IsPhantom, IsVolumeDetect);
2676 2677
2677 SceneObjectPart[] ogParts = objectGroup.Parts; 2678 SceneObjectPart[] ogParts = objectGroup.Parts;
2678 Array.Sort(ogParts, delegate(SceneObjectPart a, SceneObjectPart b) 2679 Array.Sort(ogParts, delegate(SceneObjectPart a, SceneObjectPart b)
@@ -2908,6 +2909,8 @@ namespace OpenSim.Region.Framework.Scenes
2908 oldRot = part.RotationOffset; 2909 oldRot = part.RotationOffset;
2909 Quaternion newRot = Quaternion.Inverse(parentRot) * worldRot; 2910 Quaternion newRot = Quaternion.Inverse(parentRot) * worldRot;
2910 part.RotationOffset = newRot; 2911 part.RotationOffset = newRot;
2912
2913 part.UpdatePrimFlags(UsesPhysics, IsTemporary, IsPhantom, IsVolumeDetect);
2911 } 2914 }
2912 2915
2913 /// <summary> 2916 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index c73fc98..cd22def 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -2074,6 +2074,9 @@ namespace OpenSim.Region.Framework.Scenes
2074 /// <param name="isNew"></param> 2074 /// <param name="isNew"></param>
2075 public void DoPhysicsPropertyUpdate(bool UsePhysics, bool isNew) 2075 public void DoPhysicsPropertyUpdate(bool UsePhysics, bool isNew)
2076 { 2076 {
2077 if (ParentGroup.Scene == null)
2078 return;
2079
2077 if (!ParentGroup.Scene.PhysicalPrims && UsePhysics) 2080 if (!ParentGroup.Scene.PhysicalPrims && UsePhysics)
2078 return; 2081 return;
2079 2082
@@ -4531,7 +4534,7 @@ namespace OpenSim.Region.Framework.Scenes
4531 // For now, we use the NINJA naming scheme for identifying joints. 4534 // For now, we use the NINJA naming scheme for identifying joints.
4532 // In the future, we can support other joint specification schemes such as a 4535 // In the future, we can support other joint specification schemes such as a
4533 // custom checkbox in the viewer GUI. 4536 // custom checkbox in the viewer GUI.
4534 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints) 4537 if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
4535 { 4538 {
4536 string hingeString = "hingejoint"; 4539 string hingeString = "hingejoint";
4537 return (Name.Length >= hingeString.Length && Name.Substring(0, hingeString.Length) == hingeString); 4540 return (Name.Length >= hingeString.Length && Name.Substring(0, hingeString.Length) == hingeString);
@@ -4547,7 +4550,7 @@ namespace OpenSim.Region.Framework.Scenes
4547 // For now, we use the NINJA naming scheme for identifying joints. 4550 // For now, we use the NINJA naming scheme for identifying joints.
4548 // In the future, we can support other joint specification schemes such as a 4551 // In the future, we can support other joint specification schemes such as a
4549 // custom checkbox in the viewer GUI. 4552 // custom checkbox in the viewer GUI.
4550 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints) 4553 if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
4551 { 4554 {
4552 string ballString = "balljoint"; 4555 string ballString = "balljoint";
4553 return (Name.Length >= ballString.Length && Name.Substring(0, ballString.Length) == ballString); 4556 return (Name.Length >= ballString.Length && Name.Substring(0, ballString.Length) == ballString);
@@ -4563,7 +4566,7 @@ namespace OpenSim.Region.Framework.Scenes
4563 // For now, we use the NINJA naming scheme for identifying joints. 4566 // For now, we use the NINJA naming scheme for identifying joints.
4564 // In the future, we can support other joint specification schemes such as a 4567 // In the future, we can support other joint specification schemes such as a
4565 // custom checkbox in the viewer GUI. 4568 // custom checkbox in the viewer GUI.
4566 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints) 4569 if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
4567 { 4570 {
4568 return IsHingeJoint() || IsBallJoint(); 4571 return IsHingeJoint() || IsBallJoint();
4569 } 4572 }
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs
index 2a342d5..882031c 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic;
29using System.Reflection; 30using System.Reflection;
30using NUnit.Framework; 31using NUnit.Framework;
31using OpenMetaverse; 32using OpenMetaverse;
@@ -43,24 +44,137 @@ namespace OpenSim.Region.Framework.Scenes.Tests
43 [TestFixture] 44 [TestFixture]
44 public class SceneObjectStatusTests 45 public class SceneObjectStatusTests
45 { 46 {
47 private TestScene m_scene;
48 private UUID m_ownerId = TestHelpers.ParseTail(0x1);
49 private SceneObjectGroup m_so1;
50 private SceneObjectGroup m_so2;
51
52 [SetUp]
53 public void Init()
54 {
55 m_scene = SceneHelpers.SetupScene();
56 m_so1 = SceneHelpers.CreateSceneObject(1, m_ownerId, "so1", 0x10);
57 m_so2 = SceneHelpers.CreateSceneObject(1, m_ownerId, "so2", 0x20);
58 }
59
46 [Test] 60 [Test]
47 public void TestSetPhantom() 61 public void TestSetPhantomSinglePrim()
48 { 62 {
49 TestHelpers.InMethod(); 63 TestHelpers.InMethod();
50 64
51// Scene scene = SceneSetupHelpers.SetupScene(); 65 SceneObjectPart rootPart = m_so1.RootPart;
52 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, UUID.Zero);
53 SceneObjectPart rootPart = so.RootPart;
54 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); 66 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None));
55 67
56 so.ScriptSetPhantomStatus(true); 68 m_so1.ScriptSetPhantomStatus(true);
57 69
58// Console.WriteLine("so.RootPart.Flags [{0}]", so.RootPart.Flags); 70// Console.WriteLine("so.RootPart.Flags [{0}]", so.RootPart.Flags);
59 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Phantom)); 71 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Phantom));
60 72
61 so.ScriptSetPhantomStatus(false); 73 m_so1.ScriptSetPhantomStatus(false);
62 74
63 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); 75 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None));
64 } 76 }
77
78 [Test]
79 public void TestSetPhysicsSinglePrim()
80 {
81 TestHelpers.InMethod();
82
83 SceneObjectPart rootPart = m_so1.RootPart;
84 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None));
85
86 m_so1.ScriptSetPhysicsStatus(true);
87
88// Console.WriteLine("so.RootPart.Flags [{0}]", so.RootPart.Flags);
89 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Physics));
90
91 m_so1.ScriptSetPhysicsStatus(false);
92
93 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None));
94 }
95
96 [Test]
97 public void TestSetPhysicsLinkset()
98 {
99 TestHelpers.InMethod();
100
101 m_scene.AddSceneObject(m_so1);
102 m_scene.AddSceneObject(m_so2);
103
104 m_scene.LinkObjects(m_ownerId, m_so1.LocalId, new List<uint>() { m_so2.LocalId });
105
106 m_so1.ScriptSetPhysicsStatus(true);
107
108 Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.Physics));
109 Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.Physics));
110
111 m_so1.ScriptSetPhysicsStatus(false);
112
113 Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.None));
114 Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.None));
115
116 m_so1.ScriptSetPhysicsStatus(true);
117
118 Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.Physics));
119 Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.Physics));
120 }
121
122 /// <summary>
123 /// Test that linking results in the correct physical status for all linkees.
124 /// </summary>
125 [Test]
126 public void TestLinkPhysicsBothPhysical()
127 {
128 TestHelpers.InMethod();
129
130 m_scene.AddSceneObject(m_so1);
131 m_scene.AddSceneObject(m_so2);
132
133 m_so1.ScriptSetPhysicsStatus(true);
134 m_so2.ScriptSetPhysicsStatus(true);
135
136 m_scene.LinkObjects(m_ownerId, m_so1.LocalId, new List<uint>() { m_so2.LocalId });
137
138 Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.Physics));
139 Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.Physics));
140 }
141
142 /// <summary>
143 /// Test that linking results in the correct physical status for all linkees.
144 /// </summary>
145 [Test]
146 public void TestLinkPhysicsRootPhysicalOnly()
147 {
148 TestHelpers.InMethod();
149
150 m_scene.AddSceneObject(m_so1);
151 m_scene.AddSceneObject(m_so2);
152
153 m_so1.ScriptSetPhysicsStatus(true);
154
155 m_scene.LinkObjects(m_ownerId, m_so1.LocalId, new List<uint>() { m_so2.LocalId });
156
157 Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.Physics));
158 Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.Physics));
159 }
160
161 /// <summary>
162 /// Test that linking results in the correct physical status for all linkees.
163 /// </summary>
164 [Test]
165 public void TestLinkPhysicsChildPhysicalOnly()
166 {
167 TestHelpers.InMethod();
168
169 m_scene.AddSceneObject(m_so1);
170 m_scene.AddSceneObject(m_so2);
171
172 m_so2.ScriptSetPhysicsStatus(true);
173
174 m_scene.LinkObjects(m_ownerId, m_so1.LocalId, new List<uint>() { m_so2.LocalId });
175
176 Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.None));
177 Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.None));
178 }
65 } 179 }
66} \ No newline at end of file 180} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index 98f5905..5e8f4c6 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -156,7 +156,15 @@ namespace OpenSim.Region.Physics.OdePlugin
156 /// </summary> 156 /// </summary>
157 public IntPtr m_targetSpace = IntPtr.Zero; 157 public IntPtr m_targetSpace = IntPtr.Zero;
158 158
159 /// <summary>
160 /// The prim geometry, used for collision detection.
161 /// </summary>
162 /// <remarks>
163 /// This is never null except for a brief period when the geometry needs to be replaced (due to resizing or
164 /// mesh change) or when the physical prim is being removed from the scene.
165 /// </remarks>
159 public IntPtr prim_geom { get; private set; } 166 public IntPtr prim_geom { get; private set; }
167
160 public IntPtr _triMeshData { get; private set; } 168 public IntPtr _triMeshData { get; private set; }
161 169
162 private IntPtr _linkJointGroup = IntPtr.Zero; 170 private IntPtr _linkJointGroup = IntPtr.Zero;
@@ -325,14 +333,11 @@ namespace OpenSim.Region.Physics.OdePlugin
325 { 333 {
326 prim_geom = geom; 334 prim_geom = geom;
327//Console.WriteLine("SetGeom to " + prim_geom + " for " + Name); 335//Console.WriteLine("SetGeom to " + prim_geom + " for " + Name);
328 if (prim_geom != IntPtr.Zero)
329 {
330 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
331 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
332 336
333 _parent_scene.geom_name_map[prim_geom] = Name; 337 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
334 _parent_scene.actor_name_map[prim_geom] = this; 338 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
335 } 339
340 _parent_scene.geom_name_map[prim_geom] = Name;
336 341
337 if (childPrim) 342 if (childPrim)
338 { 343 {
@@ -765,11 +770,8 @@ namespace OpenSim.Region.Physics.OdePlugin
765 m_collisionCategories &= ~CollisionCategories.Body; 770 m_collisionCategories &= ~CollisionCategories.Body;
766 m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); 771 m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land);
767 772
768 if (prim_geom != IntPtr.Zero) 773 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
769 { 774 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
770 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
771 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
772 }
773 775
774 d.BodyDestroy(Body); 776 d.BodyDestroy(Body);
775 lock (childrenPrim) 777 lock (childrenPrim)
@@ -793,11 +795,8 @@ namespace OpenSim.Region.Physics.OdePlugin
793 m_collisionCategories &= ~CollisionCategories.Body; 795 m_collisionCategories &= ~CollisionCategories.Body;
794 m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); 796 m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land);
795 797
796 if (prim_geom != IntPtr.Zero) 798 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
797 { 799 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
798 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
799 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
800 }
801 800
802 Body = IntPtr.Zero; 801 Body = IntPtr.Zero;
803 } 802 }
@@ -864,10 +863,7 @@ namespace OpenSim.Region.Physics.OdePlugin
864// _parent_scene.waitForSpaceUnlock(m_targetSpace); 863// _parent_scene.waitForSpaceUnlock(m_targetSpace);
865 try 864 try
866 { 865 {
867 if (prim_geom == IntPtr.Zero) 866 SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null));
868 {
869 SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null));
870 }
871 } 867 }
872 catch (AccessViolationException) 868 catch (AccessViolationException)
873 { 869 {
@@ -890,73 +886,67 @@ namespace OpenSim.Region.Physics.OdePlugin
890#if SPAM 886#if SPAM
891Console.WriteLine("ZProcessTaints for " + Name); 887Console.WriteLine("ZProcessTaints for " + Name);
892#endif 888#endif
889
890 // This must be processed as the very first taint so that later operations have a prim_geom to work with
891 // if this is a new prim.
893 if (m_taintadd) 892 if (m_taintadd)
894 {
895 changeadd(); 893 changeadd();
896 }
897
898 if (prim_geom != IntPtr.Zero)
899 {
900 if (!_position.ApproxEquals(m_taintposition, 0f))
901 changemove();
902 894
903 if (m_taintrot != _orientation) 895 if (!_position.ApproxEquals(m_taintposition, 0f))
904 { 896 changemove();
905 if (childPrim && IsPhysical) // For physical child prim... 897
906 { 898 if (m_taintrot != _orientation)
907 rotate(); 899 {
908 // KF: ODE will also rotate the parent prim! 900 if (childPrim && IsPhysical) // For physical child prim...
909 // so rotate the root back to where it was 901 {
910 OdePrim parent = (OdePrim)_parent; 902 rotate();
911 parent.rotate(); 903 // KF: ODE will also rotate the parent prim!
912 } 904 // so rotate the root back to where it was
913 else 905 OdePrim parent = (OdePrim)_parent;
914 { 906 parent.rotate();
915 //Just rotate the prim
916 rotate();
917 }
918 } 907 }
919 908 else
920 if (m_taintPhysics != IsPhysical && !(m_taintparent != _parent)) 909 {
921 changePhysicsStatus(); 910 //Just rotate the prim
911 rotate();
912 }
913 }
914
915 if (m_taintPhysics != IsPhysical && !(m_taintparent != _parent))
916 changePhysicsStatus();
922 917
923 if (!_size.ApproxEquals(m_taintsize, 0f)) 918 if (!_size.ApproxEquals(m_taintsize, 0f))
924 changesize(); 919 changesize();
925 920
926 if (m_taintshape) 921 if (m_taintshape)
927 changeshape(); 922 changeshape();
928 923
929 if (m_taintforce) 924 if (m_taintforce)
930 changeAddForce(); 925 changeAddForce();
931 926
932 if (m_taintaddangularforce) 927 if (m_taintaddangularforce)
933 changeAddAngularForce(); 928 changeAddAngularForce();
934 929
935 if (!m_taintTorque.ApproxEquals(Vector3.Zero, 0.001f)) 930 if (!m_taintTorque.ApproxEquals(Vector3.Zero, 0.001f))
936 changeSetTorque(); 931 changeSetTorque();
937 932
938 if (m_taintdisable) 933 if (m_taintdisable)
939 changedisable(); 934 changedisable();
940 935
941 if (m_taintselected != m_isSelected) 936 if (m_taintselected != m_isSelected)
942 changeSelectedStatus(); 937 changeSelectedStatus();
943 938
944 if (!m_taintVelocity.ApproxEquals(Vector3.Zero, 0.001f)) 939 if (!m_taintVelocity.ApproxEquals(Vector3.Zero, 0.001f))
945 changevelocity(); 940 changevelocity();
946 941
947 if (m_taintparent != _parent) 942 if (m_taintparent != _parent)
948 changelink(); 943 changelink();
949 944
950 if (m_taintCollidesWater != m_collidesWater) 945 if (m_taintCollidesWater != m_collidesWater)
951 changefloatonwater(); 946 changefloatonwater();
952 947
953 if (!m_angularlock.ApproxEquals(m_taintAngularLock,0f)) 948 if (!m_angularlock.ApproxEquals(m_taintAngularLock,0f))
954 changeAngularLock(); 949 changeAngularLock();
955 }
956 else
957 {
958 m_log.ErrorFormat("[PHYSICS]: The scene reused a disposed PhysActor for {0}! *waves finger*, Don't be evil. A couple of things can cause this. An improper prim breakdown(be sure to set prim_geom to zero after d.GeomDestroy! An improper buildup (creating the geom failed). Or, the Scene Reused a physics actor after disposing it.)", Name);
959 }
960 } 950 }
961 951
962 /// <summary> 952 /// <summary>
@@ -1052,150 +1042,146 @@ Console.WriteLine("ZProcessTaints for " + Name);
1052 /// <param name="prim">Child prim</param> 1042 /// <param name="prim">Child prim</param>
1053 private void AddChildPrim(OdePrim prim) 1043 private void AddChildPrim(OdePrim prim)
1054 { 1044 {
1055//Console.WriteLine("AddChildPrim " + Name); 1045 if (LocalID == prim.LocalID)
1056 if (LocalID != prim.LocalID) 1046 return;
1047
1048 if (Body == IntPtr.Zero)
1057 { 1049 {
1058 if (Body == IntPtr.Zero) 1050 Body = d.BodyCreate(_parent_scene.world);
1051 setMass();
1052 }
1053
1054 lock (childrenPrim)
1055 {
1056 if (childrenPrim.Contains(prim))
1057 return;
1058
1059// m_log.DebugFormat(
1060// "[ODE PRIM]: Linking prim {0} {1} to {2} {3}", prim.Name, prim.LocalID, Name, LocalID);
1061
1062 childrenPrim.Add(prim);
1063
1064 foreach (OdePrim prm in childrenPrim)
1059 { 1065 {
1060 Body = d.BodyCreate(_parent_scene.world); 1066 d.Mass m2;
1061 setMass(); 1067 d.MassSetZero(out m2);
1068 d.MassSetBoxTotal(out m2, prim.CalculateMass(), prm._size.X, prm._size.Y, prm._size.Z);
1069
1070 d.Quaternion quat = new d.Quaternion();
1071 quat.W = prm._orientation.W;
1072 quat.X = prm._orientation.X;
1073 quat.Y = prm._orientation.Y;
1074 quat.Z = prm._orientation.Z;
1075
1076 d.Matrix3 mat = new d.Matrix3();
1077 d.RfromQ(out mat, ref quat);
1078 d.MassRotate(ref m2, ref mat);
1079 d.MassTranslate(ref m2, Position.X - prm.Position.X, Position.Y - prm.Position.Y, Position.Z - prm.Position.Z);
1080 d.MassAdd(ref pMass, ref m2);
1062 } 1081 }
1063 if (Body != IntPtr.Zero) 1082
1083 foreach (OdePrim prm in childrenPrim)
1064 { 1084 {
1065 lock (childrenPrim) 1085 prm.m_collisionCategories |= CollisionCategories.Body;
1066 { 1086 prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
1067 if (!childrenPrim.Contains(prim))
1068 {
1069//Console.WriteLine("childrenPrim.Add " + prim);
1070 childrenPrim.Add(prim);
1071
1072 foreach (OdePrim prm in childrenPrim)
1073 {
1074 d.Mass m2;
1075 d.MassSetZero(out m2);
1076 d.MassSetBoxTotal(out m2, prim.CalculateMass(), prm._size.X, prm._size.Y, prm._size.Z);
1077
1078 d.Quaternion quat = new d.Quaternion();
1079 quat.W = prm._orientation.W;
1080 quat.X = prm._orientation.X;
1081 quat.Y = prm._orientation.Y;
1082 quat.Z = prm._orientation.Z;
1083
1084 d.Matrix3 mat = new d.Matrix3();
1085 d.RfromQ(out mat, ref quat);
1086 d.MassRotate(ref m2, ref mat);
1087 d.MassTranslate(ref m2, Position.X - prm.Position.X, Position.Y - prm.Position.Y, Position.Z - prm.Position.Z);
1088 d.MassAdd(ref pMass, ref m2);
1089 }
1090
1091 foreach (OdePrim prm in childrenPrim)
1092 {
1093 prm.m_collisionCategories |= CollisionCategories.Body;
1094 prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
1095 1087
1096 if (prm.prim_geom == IntPtr.Zero)
1097 {
1098 m_log.WarnFormat(
1099 "[PHYSICS]: Unable to link one of the linkset elements {0} for parent {1}. No geom yet",
1100 prm.Name, prim.Name);
1101 continue;
1102 }
1103//Console.WriteLine(" GeomSetCategoryBits 1: " + prm.prim_geom + " - " + (int)prm.m_collisionCategories + " for " + Name); 1088//Console.WriteLine(" GeomSetCategoryBits 1: " + prm.prim_geom + " - " + (int)prm.m_collisionCategories + " for " + Name);
1104 d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories); 1089 d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories);
1105 d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags); 1090 d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags);
1106 1091
1092 d.Quaternion quat = new d.Quaternion();
1093 quat.W = prm._orientation.W;
1094 quat.X = prm._orientation.X;
1095 quat.Y = prm._orientation.Y;
1096 quat.Z = prm._orientation.Z;
1107 1097
1108 d.Quaternion quat = new d.Quaternion(); 1098 d.Matrix3 mat = new d.Matrix3();
1109 quat.W = prm._orientation.W; 1099 d.RfromQ(out mat, ref quat);
1110 quat.X = prm._orientation.X; 1100 if (Body != IntPtr.Zero)
1111 quat.Y = prm._orientation.Y; 1101 {
1112 quat.Z = prm._orientation.Z; 1102 d.GeomSetBody(prm.prim_geom, Body);
1113 1103 prm.childPrim = true;
1114 d.Matrix3 mat = new d.Matrix3(); 1104 d.GeomSetOffsetWorldPosition(prm.prim_geom, prm.Position.X , prm.Position.Y, prm.Position.Z);
1115 d.RfromQ(out mat, ref quat); 1105 //d.GeomSetOffsetPosition(prim.prim_geom,
1116 if (Body != IntPtr.Zero) 1106 // (Position.X - prm.Position.X) - pMass.c.X,
1117 { 1107 // (Position.Y - prm.Position.Y) - pMass.c.Y,
1118 d.GeomSetBody(prm.prim_geom, Body); 1108 // (Position.Z - prm.Position.Z) - pMass.c.Z);
1119 prm.childPrim = true; 1109 d.GeomSetOffsetWorldRotation(prm.prim_geom, ref mat);
1120 d.GeomSetOffsetWorldPosition(prm.prim_geom, prm.Position.X , prm.Position.Y, prm.Position.Z); 1110 //d.GeomSetOffsetRotation(prm.prim_geom, ref mat);
1121 //d.GeomSetOffsetPosition(prim.prim_geom, 1111 d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z);
1122 // (Position.X - prm.Position.X) - pMass.c.X, 1112 d.BodySetMass(Body, ref pMass);
1123 // (Position.Y - prm.Position.Y) - pMass.c.Y, 1113 }
1124 // (Position.Z - prm.Position.Z) - pMass.c.Z); 1114 else
1125 d.GeomSetOffsetWorldRotation(prm.prim_geom, ref mat); 1115 {
1126 //d.GeomSetOffsetRotation(prm.prim_geom, ref mat); 1116 m_log.DebugFormat("[PHYSICS]: {0} ain't got no boooooooooddy, no body", Name);
1127 d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z); 1117 }
1128 d.BodySetMass(Body, ref pMass);
1129 }
1130 else
1131 {
1132 m_log.DebugFormat("[PHYSICS]: {0} ain't got no boooooooooddy, no body", Name);
1133 }
1134 1118
1135 prm.m_interpenetrationcount = 0; 1119 prm.m_interpenetrationcount = 0;
1136 prm.m_collisionscore = 0; 1120 prm.m_collisionscore = 0;
1137 prm.m_disabled = false; 1121 prm.m_disabled = false;
1138 1122
1139 // The body doesn't already have a finite rotation mode set here 1123 // The body doesn't already have a finite rotation mode set here
1140 if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0f)) && _parent == null) 1124 if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0f)) && _parent == null)
1141 { 1125 {
1142 prm.createAMotor(m_angularlock); 1126 prm.createAMotor(m_angularlock);
1143 } 1127 }
1144 prm.Body = Body; 1128 prm.Body = Body;
1145 _parent_scene.ActivatePrim(prm); 1129 _parent_scene.ActivatePrim(prm);
1146 } 1130 }
1147 1131
1148 m_collisionCategories |= CollisionCategories.Body; 1132 m_collisionCategories |= CollisionCategories.Body;
1149 m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); 1133 m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
1150 1134
1151//Console.WriteLine("GeomSetCategoryBits 2: " + prim_geom + " - " + (int)m_collisionCategories + " for " + Name); 1135//Console.WriteLine("GeomSetCategoryBits 2: " + prim_geom + " - " + (int)m_collisionCategories + " for " + Name);
1152 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 1136 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1153//Console.WriteLine(" Post GeomSetCategoryBits 2"); 1137//Console.WriteLine(" Post GeomSetCategoryBits 2");
1154 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 1138 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1155
1156 d.Quaternion quat2 = new d.Quaternion();
1157 quat2.W = _orientation.W;
1158 quat2.X = _orientation.X;
1159 quat2.Y = _orientation.Y;
1160 quat2.Z = _orientation.Z;
1161
1162 d.Matrix3 mat2 = new d.Matrix3();
1163 d.RfromQ(out mat2, ref quat2);
1164 d.GeomSetBody(prim_geom, Body);
1165 d.GeomSetOffsetWorldPosition(prim_geom, Position.X - pMass.c.X, Position.Y - pMass.c.Y, Position.Z - pMass.c.Z);
1166 //d.GeomSetOffsetPosition(prim.prim_geom,
1167 // (Position.X - prm.Position.X) - pMass.c.X,
1168 // (Position.Y - prm.Position.Y) - pMass.c.Y,
1169 // (Position.Z - prm.Position.Z) - pMass.c.Z);
1170 //d.GeomSetOffsetRotation(prim_geom, ref mat2);
1171 d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z);
1172 d.BodySetMass(Body, ref pMass);
1173
1174 d.BodySetAutoDisableFlag(Body, true);
1175 d.BodySetAutoDisableSteps(Body, body_autodisable_frames);
1176 1139
1177 m_interpenetrationcount = 0; 1140 d.Quaternion quat2 = new d.Quaternion();
1178 m_collisionscore = 0; 1141 quat2.W = _orientation.W;
1179 m_disabled = false; 1142 quat2.X = _orientation.X;
1143 quat2.Y = _orientation.Y;
1144 quat2.Z = _orientation.Z;
1180 1145
1181 // The body doesn't already have a finite rotation mode set here 1146 d.Matrix3 mat2 = new d.Matrix3();
1182 if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0f)) && _parent == null) 1147 d.RfromQ(out mat2, ref quat2);
1183 { 1148 d.GeomSetBody(prim_geom, Body);
1184 createAMotor(m_angularlock); 1149 d.GeomSetOffsetWorldPosition(prim_geom, Position.X - pMass.c.X, Position.Y - pMass.c.Y, Position.Z - pMass.c.Z);
1185 } 1150 //d.GeomSetOffsetPosition(prim.prim_geom,
1186 d.BodySetPosition(Body, Position.X, Position.Y, Position.Z); 1151 // (Position.X - prm.Position.X) - pMass.c.X,
1187 if (m_vehicle.Type != Vehicle.TYPE_NONE) 1152 // (Position.Y - prm.Position.Y) - pMass.c.Y,
1188 m_vehicle.Enable(Body, _parent_scene); 1153 // (Position.Z - prm.Position.Z) - pMass.c.Z);
1154 //d.GeomSetOffsetRotation(prim_geom, ref mat2);
1155 d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z);
1156 d.BodySetMass(Body, ref pMass);
1189 1157
1190 _parent_scene.ActivatePrim(this); 1158 d.BodySetAutoDisableFlag(Body, true);
1191 } 1159 d.BodySetAutoDisableSteps(Body, body_autodisable_frames);
1192 } 1160
1161 m_interpenetrationcount = 0;
1162 m_collisionscore = 0;
1163 m_disabled = false;
1164
1165 // The body doesn't already have a finite rotation mode set here
1166 if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0f)) && _parent == null)
1167 {
1168 createAMotor(m_angularlock);
1193 } 1169 }
1170
1171 d.BodySetPosition(Body, Position.X, Position.Y, Position.Z);
1172
1173 if (m_vehicle.Type != Vehicle.TYPE_NONE)
1174 m_vehicle.Enable(Body, _parent_scene);
1175
1176 _parent_scene.ActivatePrim(this);
1194 } 1177 }
1195 } 1178 }
1196 1179
1197 private void ChildSetGeom(OdePrim odePrim) 1180 private void ChildSetGeom(OdePrim odePrim)
1198 { 1181 {
1182// m_log.DebugFormat(
1183// "[ODE PRIM]: ChildSetGeom {0} {1} for {2} {3}", odePrim.Name, odePrim.LocalID, Name, LocalID);
1184
1199 //if (IsPhysical && Body != IntPtr.Zero) 1185 //if (IsPhysical && Body != IntPtr.Zero)
1200 lock (childrenPrim) 1186 lock (childrenPrim)
1201 { 1187 {
@@ -1210,12 +1196,14 @@ Console.WriteLine("ZProcessTaints for " + Name);
1210 //prm.childPrim = false; 1196 //prm.childPrim = false;
1211 } 1197 }
1212 } 1198 }
1199
1213 disableBody(); 1200 disableBody();
1214 1201
1215 if (Body != IntPtr.Zero) 1202 // Spurious - Body == IntPtr.Zero after disableBody()
1216 { 1203// if (Body != IntPtr.Zero)
1217 _parent_scene.DeactivatePrim(this); 1204// {
1218 } 1205// _parent_scene.DeactivatePrim(this);
1206// }
1219 1207
1220 lock (childrenPrim) 1208 lock (childrenPrim)
1221 { 1209 {
@@ -1229,6 +1217,9 @@ Console.WriteLine("ZProcessTaints for " + Name);
1229 1217
1230 private void ChildDelink(OdePrim odePrim) 1218 private void ChildDelink(OdePrim odePrim)
1231 { 1219 {
1220// m_log.DebugFormat(
1221// "[ODE PRIM]: Delinking prim {0} {1} from {2} {3}", odePrim.Name, odePrim.LocalID, Name, LocalID);
1222
1232 // Okay, we have a delinked child.. need to rebuild the body. 1223 // Okay, we have a delinked child.. need to rebuild the body.
1233 lock (childrenPrim) 1224 lock (childrenPrim)
1234 { 1225 {
@@ -1243,6 +1234,7 @@ Console.WriteLine("ZProcessTaints for " + Name);
1243 //prm.childPrim = false; 1234 //prm.childPrim = false;
1244 } 1235 }
1245 } 1236 }
1237
1246 disableBody(); 1238 disableBody();
1247 1239
1248 lock (childrenPrim) 1240 lock (childrenPrim)
@@ -1251,10 +1243,11 @@ Console.WriteLine("ZProcessTaints for " + Name);
1251 childrenPrim.Remove(odePrim); 1243 childrenPrim.Remove(odePrim);
1252 } 1244 }
1253 1245
1254 if (Body != IntPtr.Zero) 1246 // Spurious - Body == IntPtr.Zero after disableBody()
1255 { 1247// if (Body != IntPtr.Zero)
1256 _parent_scene.DeactivatePrim(this); 1248// {
1257 } 1249// _parent_scene.DeactivatePrim(this);
1250// }
1258 1251
1259 lock (childrenPrim) 1252 lock (childrenPrim)
1260 { 1253 {
@@ -1303,11 +1296,8 @@ Console.WriteLine("ZProcessTaints for " + Name);
1303 disableBodySoft(); 1296 disableBodySoft();
1304 } 1297 }
1305 1298
1306 if (prim_geom != IntPtr.Zero) 1299 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1307 { 1300 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1308 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1309 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1310 }
1311 1301
1312 if (IsPhysical) 1302 if (IsPhysical)
1313 { 1303 {
@@ -1328,11 +1318,8 @@ Console.WriteLine("ZProcessTaints for " + Name);
1328 if (m_collidesWater) 1318 if (m_collidesWater)
1329 m_collisionFlags |= CollisionCategories.Water; 1319 m_collisionFlags |= CollisionCategories.Water;
1330 1320
1331 if (prim_geom != IntPtr.Zero) 1321 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1332 { 1322 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1333 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1334 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1335 }
1336 1323
1337 if (IsPhysical) 1324 if (IsPhysical)
1338 { 1325 {
@@ -1472,6 +1459,9 @@ Console.WriteLine("CreateGeom:");
1472 } 1459 }
1473 else 1460 else
1474 { 1461 {
1462 m_log.WarnFormat(
1463 "[ODE PRIM]: Called RemoveGeom() on {0} {1} where geometry was already null.", Name, LocalID);
1464
1475 return false; 1465 return false;
1476 } 1466 }
1477 } 1467 }
@@ -1505,16 +1495,13 @@ Console.WriteLine("changeadd 1");
1505#endif 1495#endif
1506 CreateGeom(m_targetSpace, mesh); 1496 CreateGeom(m_targetSpace, mesh);
1507 1497
1508 if (prim_geom != IntPtr.Zero) 1498 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
1509 { 1499 d.Quaternion myrot = new d.Quaternion();
1510 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); 1500 myrot.X = _orientation.X;
1511 d.Quaternion myrot = new d.Quaternion(); 1501 myrot.Y = _orientation.Y;
1512 myrot.X = _orientation.X; 1502 myrot.Z = _orientation.Z;
1513 myrot.Y = _orientation.Y; 1503 myrot.W = _orientation.W;
1514 myrot.Z = _orientation.Z; 1504 d.GeomSetQuaternion(prim_geom, ref myrot);
1515 myrot.W = _orientation.W;
1516 d.GeomSetQuaternion(prim_geom, ref myrot);
1517 }
1518 1505
1519 if (IsPhysical && Body == IntPtr.Zero) 1506 if (IsPhysical && Body == IntPtr.Zero)
1520 enableBody(); 1507 enableBody();
@@ -1588,13 +1575,11 @@ Console.WriteLine(" JointCreateFixed");
1588 m_targetSpace = tempspace; 1575 m_targetSpace = tempspace;
1589 1576
1590// _parent_scene.waitForSpaceUnlock(m_targetSpace); 1577// _parent_scene.waitForSpaceUnlock(m_targetSpace);
1591 if (prim_geom != IntPtr.Zero) 1578
1592 { 1579 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
1593 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
1594 1580
1595// _parent_scene.waitForSpaceUnlock(m_targetSpace); 1581// _parent_scene.waitForSpaceUnlock(m_targetSpace);
1596 d.SpaceAdd(m_targetSpace, prim_geom); 1582 d.SpaceAdd(m_targetSpace, prim_geom);
1597 }
1598 1583
1599 changeSelectedStatus(); 1584 changeSelectedStatus();
1600 1585
@@ -2045,18 +2030,16 @@ Console.WriteLine(" JointCreateFixed");
2045 { 2030 {
2046 m_collidesWater = m_taintCollidesWater; 2031 m_collidesWater = m_taintCollidesWater;
2047 2032
2048 if (prim_geom != IntPtr.Zero) 2033 if (m_collidesWater)
2049 { 2034 {
2050 if (m_collidesWater) 2035 m_collisionFlags |= CollisionCategories.Water;
2051 {
2052 m_collisionFlags |= CollisionCategories.Water;
2053 }
2054 else
2055 {
2056 m_collisionFlags &= ~CollisionCategories.Water;
2057 }
2058 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
2059 } 2036 }
2037 else
2038 {
2039 m_collisionFlags &= ~CollisionCategories.Water;
2040 }
2041
2042 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
2060 } 2043 }
2061 2044
2062 /// <summary> 2045 /// <summary>
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
index 842ff91..409b27b 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
@@ -2226,7 +2226,8 @@ namespace OpenSim.Region.Physics.OdePlugin
2226 /// <param name="prim"></param> 2226 /// <param name="prim"></param>
2227 internal void RemovePrimThreadLocked(OdePrim prim) 2227 internal void RemovePrimThreadLocked(OdePrim prim)
2228 { 2228 {
2229//Console.WriteLine("RemovePrimThreadLocked " + prim.m_primName); 2229// m_log.DebugFormat("[ODE SCENE]: Removing physical prim {0} {1}", prim.Name, prim.LocalID);
2230
2230 lock (prim) 2231 lock (prim)
2231 { 2232 {
2232 RemoveCollisionEventReporting(prim); 2233 RemoveCollisionEventReporting(prim);