aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs2
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs4
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs4
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs8
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs113
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs5
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs6
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs16
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs2
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs4
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs6
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs23
12 files changed, 155 insertions, 38 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index 21aa9be..88460cc 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -124,7 +124,9 @@ public sealed class BSCharacter : BSPhysObject
124 PhysicsScene.TaintedObject("BSCharacter.destroy", delegate() 124 PhysicsScene.TaintedObject("BSCharacter.destroy", delegate()
125 { 125 {
126 PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null); 126 PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null);
127 PhysBody.Clear();
127 PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null); 128 PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null);
129 PhysShape.Clear();
128 }); 130 });
129 } 131 }
130 132
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
index 65fac00..6b1e304 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
@@ -57,7 +57,7 @@ public abstract class BSConstraint : IDisposable
57 if (m_enabled) 57 if (m_enabled)
58 { 58 {
59 m_enabled = false; 59 m_enabled = false;
60 if (m_constraint.ptr != IntPtr.Zero) 60 if (m_constraint.HasPhysicalConstraint)
61 { 61 {
62 bool success = BulletSimAPI.DestroyConstraint2(m_world.ptr, m_constraint.ptr); 62 bool success = BulletSimAPI.DestroyConstraint2(m_world.ptr, m_constraint.ptr);
63 m_world.physicsScene.DetailLog("{0},BSConstraint.Dispose,taint,id1={1},body1={2},id2={3},body2={4},success={5}", 63 m_world.physicsScene.DetailLog("{0},BSConstraint.Dispose,taint,id1={1},body1={2},id2={3},body2={4},success={5}",
@@ -65,7 +65,7 @@ public abstract class BSConstraint : IDisposable
65 m_body1.ID, m_body1.ptr.ToString("X"), 65 m_body1.ID, m_body1.ptr.ToString("X"),
66 m_body2.ID, m_body2.ptr.ToString("X"), 66 m_body2.ID, m_body2.ptr.ToString("X"),
67 success); 67 success);
68 m_constraint.ptr = System.IntPtr.Zero; 68 m_constraint.Clear();
69 } 69 }
70 } 70 }
71 } 71 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs
index 23ef052..b073555 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs
@@ -65,7 +65,7 @@ public sealed class BSConstraint6Dof : BSConstraint
65 m_world = world; 65 m_world = world;
66 m_body1 = obj1; 66 m_body1 = obj1;
67 m_body2 = obj2; 67 m_body2 = obj2;
68 if (obj1.ptr == IntPtr.Zero || obj2.ptr == IntPtr.Zero) 68 if (!obj1.HasPhysicalBody || !obj2.HasPhysicalBody)
69 { 69 {
70 world.physicsScene.DetailLog("{0},BS6DOFConstraint,badBodyPtr,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}", 70 world.physicsScene.DetailLog("{0},BS6DOFConstraint,badBodyPtr,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}",
71 BSScene.DetailLogZero, world.worldID, 71 BSScene.DetailLogZero, world.worldID,
@@ -83,7 +83,7 @@ public sealed class BSConstraint6Dof : BSConstraint
83 world.physicsScene.DetailLog("{0},BS6DofConstraint,createMidPoint,wID={1}, csrt={2}, rID={3}, rBody={4}, cID={5}, cBody={6}", 83 world.physicsScene.DetailLog("{0},BS6DofConstraint,createMidPoint,wID={1}, csrt={2}, rID={3}, rBody={4}, cID={5}, cBody={6}",
84 BSScene.DetailLogZero, world.worldID, m_constraint.ptr.ToString("X"), 84 BSScene.DetailLogZero, world.worldID, m_constraint.ptr.ToString("X"),
85 obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X")); 85 obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X"));
86 if (m_constraint.ptr == IntPtr.Zero) 86 if (!m_constraint.HasPhysicalConstraint)
87 { 87 {
88 world.physicsScene.Logger.ErrorFormat("{0} Failed creation of 6Dof constraint. rootID={1}, childID={2}", 88 world.physicsScene.Logger.ErrorFormat("{0} Failed creation of 6Dof constraint. rootID={1}, childID={2}",
89 LogHeader, obj1.ID, obj2.ID); 89 LogHeader, obj1.ID, obj2.ID);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index 0df4310..777c5cb 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -32,6 +32,14 @@ using OMV = OpenMetaverse;
32 32
33namespace OpenSim.Region.Physics.BulletSPlugin 33namespace OpenSim.Region.Physics.BulletSPlugin
34{ 34{
35
36// A BSPrim can get individual information about its linkedness attached
37// to it through an instance of a subclass of LinksetInfo.
38// Each type of linkset will define the information needed for its type.
39public abstract class BSLinksetInfo
40{
41}
42
35public abstract class BSLinkset 43public abstract class BSLinkset
36{ 44{
37 // private static string LogHeader = "[BULLETSIM LINKSET]"; 45 // private static string LogHeader = "[BULLETSIM LINKSET]";
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
index bc9f9be..fe5b5e3 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
@@ -32,6 +32,31 @@ using OMV = OpenMetaverse;
32 32
33namespace OpenSim.Region.Physics.BulletSPlugin 33namespace OpenSim.Region.Physics.BulletSPlugin
34{ 34{
35
36// When a child is linked, the relationship position of the child to the parent
37// is remembered so the child's world position can be recomputed when it is
38// removed from the linkset.
39sealed class BSLinksetCompoundInfo : BSLinksetInfo
40{
41 public OMV.Vector3 OffsetPos;
42 public OMV.Quaternion OffsetRot;
43 public BSLinksetCompoundInfo(OMV.Vector3 p, OMV.Quaternion r)
44 {
45 OffsetPos = p;
46 OffsetRot = r;
47 }
48 public override string ToString()
49 {
50 StringBuilder buff = new StringBuilder();
51 buff.Append("<p=");
52 buff.Append(OffsetPos.ToString());
53 buff.Append(",r=");
54 buff.Append(OffsetRot.ToString());
55 buff.Append(">");
56 return buff.ToString();
57 }
58};
59
35public sealed class BSLinksetCompound : BSLinkset 60public sealed class BSLinksetCompound : BSLinkset
36{ 61{
37 private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]"; 62 private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]";
@@ -44,6 +69,7 @@ public sealed class BSLinksetCompound : BSLinkset
44 // For compound implimented linksets, if there are children, use compound shape for the root. 69 // For compound implimented linksets, if there are children, use compound shape for the root.
45 public override BSPhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor) 70 public override BSPhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor)
46 { 71 {
72 // Returning 'unknown' means we don't have a preference.
47 BSPhysicsShapeType ret = BSPhysicsShapeType.SHAPE_UNKNOWN; 73 BSPhysicsShapeType ret = BSPhysicsShapeType.SHAPE_UNKNOWN;
48 if (IsRoot(requestor) && HasAnyChildren) 74 if (IsRoot(requestor) && HasAnyChildren)
49 { 75 {
@@ -63,10 +89,10 @@ public sealed class BSLinksetCompound : BSLinkset
63 // InternalRefresh(requestor); 89 // InternalRefresh(requestor);
64 } 90 }
65 91
92 // Schedule a refresh to happen after all the other taint processing.
66 private void InternalRefresh(BSPhysObject requestor) 93 private void InternalRefresh(BSPhysObject requestor)
67 { 94 {
68 DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,requestor={1}", LinksetRoot.LocalID, requestor.LocalID); 95 DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,requestor={1}", LinksetRoot.LocalID, requestor.LocalID);
69 // Queue to happen after all the other taint processing
70 PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", requestor.LocalID, delegate() 96 PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", requestor.LocalID, delegate()
71 { 97 {
72 if (IsRoot(requestor) && HasAnyChildren) 98 if (IsRoot(requestor) && HasAnyChildren)
@@ -108,7 +134,7 @@ public sealed class BSLinksetCompound : BSLinkset
108 { 134 {
109 // The non-physical children can come back to life. 135 // The non-physical children can come back to life.
110 BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); 136 BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
111 // Don't force activation so setting of DISABLE_SIMULATION can stay. 137 // Don't force activation so setting of DISABLE_SIMULATION can stay if used.
112 BulletSimAPI.Activate2(child.PhysBody.ptr, false); 138 BulletSimAPI.Activate2(child.PhysBody.ptr, false);
113 ret = true; 139 ret = true;
114 } 140 }
@@ -146,6 +172,10 @@ public sealed class BSLinksetCompound : BSLinkset
146 172
147 if (!IsRoot(child)) 173 if (!IsRoot(child))
148 { 174 {
175 // Because it is a convenient time, recompute child world position and rotation based on
176 // its position in the linkset.
177 RecomputeChildWorldPosition(child, true);
178
149 // Cause the current shape to be freed and the new one to be built. 179 // Cause the current shape to be freed and the new one to be built.
150 InternalRefresh(LinksetRoot); 180 InternalRefresh(LinksetRoot);
151 ret = true; 181 ret = true;
@@ -154,6 +184,42 @@ public sealed class BSLinksetCompound : BSLinkset
154 return ret; 184 return ret;
155 } 185 }
156 186
187 // When the linkset is built, the child shape is added
188 // to the compound shape relative to the root shape. The linkset then moves around but
189 // this does not move the actual child prim. The child prim's location must be recomputed
190 // based on the location of the root shape.
191 private void RecomputeChildWorldPosition(BSPhysObject child, bool inTaintTime)
192 {
193 BSLinksetCompoundInfo lci = child.LinksetInfo as BSLinksetCompoundInfo;
194 if (lci != null)
195 {
196 if (inTaintTime)
197 {
198 OMV.Vector3 oldPos = child.RawPosition;
199 child.ForcePosition = LinksetRoot.RawPosition + lci.OffsetPos;
200 child.ForceOrientation = LinksetRoot.RawOrientation * lci.OffsetRot;
201 DetailLog("{0},BSLinksetCompound.RecomputeChildWorldPosition,oldPos={1},lci={2},newPos={3}",
202 child.LocalID, oldPos, lci, child.RawPosition);
203 }
204 else
205 {
206 // TaintedObject is not used here so the raw position is set now and not at taint-time.
207 child.Position = LinksetRoot.RawPosition + lci.OffsetPos;
208 child.Orientation = LinksetRoot.RawOrientation * lci.OffsetRot;
209 }
210 }
211 else
212 {
213 // This happens when children have been added to the linkset but the linkset
214 // has not been constructed yet. So like, at taint time, adding children to a linkset
215 // and then changing properties of the children (makePhysical, for instance)
216 // but the post-print action of actually rebuilding the linkset has not yet happened.
217 // PhysicsScene.Logger.WarnFormat("{0} Restoring linkset child position failed because of no relative position computed. ID={1}",
218 // LogHeader, child.LocalID);
219 DetailLog("{0},BSLinksetCompound.recomputeChildWorldPosition,noRelativePositonInfo", child.LocalID);
220 }
221 }
222
157 // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true', 223 // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true',
158 // this routine will restore the removed constraints. 224 // this routine will restore the removed constraints.
159 // Called at taint-time!! 225 // Called at taint-time!!
@@ -192,8 +258,7 @@ public sealed class BSLinksetCompound : BSLinkset
192 child.LocalID, child.PhysBody.ptr.ToString("X")); 258 child.LocalID, child.PhysBody.ptr.ToString("X"));
193 259
194 // Cause the child's body to be rebuilt and thus restored to normal operation 260 // Cause the child's body to be rebuilt and thus restored to normal operation
195 // TODO: position and rotation must be restored because the child could have moved 261 RecomputeChildWorldPosition(child, false);
196 // based on the linkset.
197 child.ForceBodyShapeRebuild(false); 262 child.ForceBodyShapeRebuild(false);
198 263
199 if (!HasAnyChildren) 264 if (!HasAnyChildren)
@@ -228,43 +293,57 @@ public sealed class BSLinksetCompound : BSLinkset
228 { 293 {
229 if (!IsRoot(cPrim)) 294 if (!IsRoot(cPrim))
230 { 295 {
231 // Each child position and rotation is given relative to the root. 296 // Compute the displacement of the child from the root of the linkset.
232 OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); 297 // This info is saved in the child prim so the relationship does not
233 OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; 298 // change over time and the new child position can be computed
234 OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; 299 // when the linkset is being disassembled (the linkset may have moved).
300 BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo;
301 if (lci == null)
302 {
303 // Each child position and rotation is given relative to the root.
304 OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation);
305 OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation;
306 OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation;
307
308 // Save relative position for recomputing child's world position after moving linkset.
309 lci = new BSLinksetCompoundInfo(displacementPos, displacementRot);
310 cPrim.LinksetInfo = lci;
311 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci);
312 }
235 313
236 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}", 314 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}",
237 LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, displacementPos, displacementRot); 315 LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot);
238 316
239 if (cPrim.PhysShape.isNativeShape) 317 if (cPrim.PhysShape.isNativeShape)
240 { 318 {
241 // A native shape is turning into a null collision shape because native 319 // A native shape is turning into a hull collision shape because native
242 // shapes are not shared so we have to hullify it so it will be tracked 320 // shapes are not shared so we have to hullify it so it will be tracked
243 // and freed at the correct time. This also solves the scaling problem 321 // and freed at the correct time. This also solves the scaling problem
244 // (native shapes scaled but hull/meshes are assumed to not be). 322 // (native shapes scaled but hull/meshes are assumed to not be).
323 // TODO: decide of the native shape can just be used in the compound shape.
324 // Use call to CreateGeomNonSpecial().
245 BulletShape saveShape = cPrim.PhysShape; 325 BulletShape saveShape = cPrim.PhysShape;
246 cPrim.PhysShape.ptr = IntPtr.Zero; // Don't let the create free the child's shape 326 cPrim.PhysShape.Clear(); // Don't let the create free the child's shape
327 // PhysicsScene.Shapes.CreateGeomNonSpecial(true, cPrim, null);
247 PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); 328 PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null);
248 BulletShape newShape = cPrim.PhysShape; 329 BulletShape newShape = cPrim.PhysShape;
249 cPrim.PhysShape = saveShape; 330 cPrim.PhysShape = saveShape;
250 BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, newShape.ptr, displacementPos, displacementRot); 331 BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, newShape.ptr, lci.OffsetPos , lci.OffsetRot);
251 } 332 }
252 else 333 else
253 { 334 {
254 // For the shared shapes (meshes and hulls), just use the shape in the child. 335 // For the shared shapes (meshes and hulls), just use the shape in the child.
336 // The reference count added here will be decremented when the compound shape
337 // is destroyed in BSShapeCollection (the child shapes are looped over and dereferenced).
255 if (PhysicsScene.Shapes.ReferenceShape(cPrim.PhysShape)) 338 if (PhysicsScene.Shapes.ReferenceShape(cPrim.PhysShape))
256 { 339 {
257 PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", 340 PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}",
258 LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); 341 LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape);
259 } 342 }
260 BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, cPrim.PhysShape.ptr, displacementPos, displacementRot); 343 BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, cPrim.PhysShape.ptr, lci.OffsetPos , lci.OffsetRot);
261 } 344 }
262 } 345 }
263 346
264 // TODO: need to phantomize the child prims left behind.
265 // Maybe just destroy the children bodies and shapes and have them rebuild on unlink.
266 // Selection/deselection might cause way too many build/destructions esp. for LARGE linksets.
267
268 return false; // 'false' says to move onto the next child in the list 347 return false; // 'false' says to move onto the next child in the list
269 }); 348 });
270 349
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index b05d4ee..d2fc15c 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -75,6 +75,7 @@ public abstract class BSPhysObject : PhysicsActor
75 public string TypeName { get; protected set; } 75 public string TypeName { get; protected set; }
76 76
77 public BSLinkset Linkset { get; set; } 77 public BSLinkset Linkset { get; set; }
78 public BSLinksetInfo LinksetInfo { get; set; }
78 79
79 // Return the object mass without calculating it or having side effects 80 // Return the object mass without calculating it or having side effects
80 public abstract float RawMass { get; } 81 public abstract float RawMass { get; }
@@ -253,7 +254,9 @@ public abstract class BSPhysObject : PhysicsActor
253 SubscribedEventsMs = 0; 254 SubscribedEventsMs = 0;
254 PhysicsScene.TaintedObject(TypeName+".UnSubscribeEvents", delegate() 255 PhysicsScene.TaintedObject(TypeName+".UnSubscribeEvents", delegate()
255 { 256 {
256 CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 257 // Make sure there is a body there because sometimes destruction happens in an un-ideal order.
258 if (PhysBody.HasPhysicalBody)
259 CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
257 }); 260 });
258 } 261 }
259 // Return 'true' if the simulator wants collision events 262 // Return 'true' if the simulator wants collision events
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 627393a..d1d100d 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -108,8 +108,8 @@ public sealed class BSPrim : BSPhysObject
108 _mass = CalculateMass(); 108 _mass = CalculateMass();
109 109
110 // No body or shape yet 110 // No body or shape yet
111 PhysBody = new BulletBody(LocalID, IntPtr.Zero); 111 PhysBody = new BulletBody(LocalID);
112 PhysShape = new BulletShape(IntPtr.Zero); 112 PhysShape = new BulletShape();
113 113
114 DetailLog("{0},BSPrim.constructor,call", LocalID); 114 DetailLog("{0},BSPrim.constructor,call", LocalID);
115 // do the actual object creation at taint time 115 // do the actual object creation at taint time
@@ -143,7 +143,9 @@ public sealed class BSPrim : BSPhysObject
143 DetailLog("{0},BSPrim.Destroy,taint,", LocalID); 143 DetailLog("{0},BSPrim.Destroy,taint,", LocalID);
144 // If there are physical body and shape, release my use of same. 144 // If there are physical body and shape, release my use of same.
145 PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null); 145 PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null);
146 PhysBody.Clear();
146 PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null); 147 PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null);
148 PhysShape.Clear();
147 }); 149 });
148 } 150 }
149 151
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
index 933f573..74b4371 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
@@ -149,7 +149,7 @@ public sealed class BSShapeCollection : IDisposable
149 // Called when releasing use of a BSBody. BSShape is handled separately. 149 // Called when releasing use of a BSBody. BSShape is handled separately.
150 public void DereferenceBody(BulletBody body, bool inTaintTime, BodyDestructionCallback bodyCallback ) 150 public void DereferenceBody(BulletBody body, bool inTaintTime, BodyDestructionCallback bodyCallback )
151 { 151 {
152 if (body.ptr == IntPtr.Zero) 152 if (!body.HasPhysicalBody)
153 return; 153 return;
154 154
155 lock (m_collectionActivityLock) 155 lock (m_collectionActivityLock)
@@ -243,12 +243,12 @@ public sealed class BSShapeCollection : IDisposable
243 // Release the usage of a shape. 243 // Release the usage of a shape.
244 public void DereferenceShape(BulletShape shape, bool inTaintTime, ShapeDestructionCallback shapeCallback) 244 public void DereferenceShape(BulletShape shape, bool inTaintTime, ShapeDestructionCallback shapeCallback)
245 { 245 {
246 if (shape.ptr == IntPtr.Zero) 246 if (!shape.HasPhysicalShape)
247 return; 247 return;
248 248
249 PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceShape", delegate() 249 PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceShape", delegate()
250 { 250 {
251 if (shape.ptr != IntPtr.Zero) 251 if (shape.HasPhysicalShape)
252 { 252 {
253 if (shape.isNativeShape) 253 if (shape.isNativeShape)
254 { 254 {
@@ -440,7 +440,7 @@ public sealed class BSShapeCollection : IDisposable
440 } 440 }
441 441
442 // Create a mesh/hull shape or a native shape if 'nativeShapePossible' is 'true'. 442 // Create a mesh/hull shape or a native shape if 'nativeShapePossible' is 'true'.
443 private bool CreateGeomNonSpecial(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback) 443 public bool CreateGeomNonSpecial(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback)
444 { 444 {
445 bool ret = false; 445 bool ret = false;
446 bool haveShape = false; 446 bool haveShape = false;
@@ -573,7 +573,7 @@ public sealed class BSShapeCollection : IDisposable
573 // Native shapes are scaled in Bullet so set the scaling to the size 573 // Native shapes are scaled in Bullet so set the scaling to the size
574 newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, nativeShapeData), shapeType); 574 newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, nativeShapeData), shapeType);
575 } 575 }
576 if (newShape.ptr == IntPtr.Zero) 576 if (!newShape.HasPhysicalShape)
577 { 577 {
578 PhysicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}", 578 PhysicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}",
579 LogHeader, prim.LocalID, shapeType); 579 LogHeader, prim.LocalID, shapeType);
@@ -590,7 +590,7 @@ public sealed class BSShapeCollection : IDisposable
590 // Called at taint-time! 590 // Called at taint-time!
591 private bool GetReferenceToMesh(BSPhysObject prim, ShapeDestructionCallback shapeCallback) 591 private bool GetReferenceToMesh(BSPhysObject prim, ShapeDestructionCallback shapeCallback)
592 { 592 {
593 BulletShape newShape = new BulletShape(IntPtr.Zero); 593 BulletShape newShape = new BulletShape();
594 594
595 float lod; 595 float lod;
596 System.UInt64 newMeshKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod); 596 System.UInt64 newMeshKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
@@ -860,7 +860,7 @@ public sealed class BSShapeCollection : IDisposable
860 private BulletShape VerifyMeshCreated(BulletShape newShape, BSPhysObject prim) 860 private BulletShape VerifyMeshCreated(BulletShape newShape, BSPhysObject prim)
861 { 861 {
862 // If the shape was successfully created, nothing more to do 862 // If the shape was successfully created, nothing more to do
863 if (newShape.ptr != IntPtr.Zero) 863 if (newShape.HasPhysicalShape)
864 return newShape; 864 return newShape;
865 865
866 // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset 866 // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset
@@ -919,7 +919,7 @@ public sealed class BSShapeCollection : IDisposable
919 bool ret = false; 919 bool ret = false;
920 920
921 // the mesh, hull or native shape must have already been created in Bullet 921 // the mesh, hull or native shape must have already been created in Bullet
922 bool mustRebuild = (prim.PhysBody.ptr == IntPtr.Zero); 922 bool mustRebuild = !prim.PhysBody.HasPhysicalBody;
923 923
924 // If there is an existing body, verify it's of an acceptable type. 924 // If there is an existing body, verify it's of an acceptable type.
925 // If not a solid object, body is a GhostObject. Otherwise a RigidBody. 925 // If not a solid object, body is a GhostObject. Otherwise a RigidBody.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs
index 83b9c37..2d379bb 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs
@@ -136,7 +136,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
136 { 136 {
137 if (m_mapInfo != null) 137 if (m_mapInfo != null)
138 { 138 {
139 if (m_mapInfo.terrainBody.ptr != IntPtr.Zero) 139 if (m_mapInfo.terrainBody.HasPhysicalBody)
140 { 140 {
141 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); 141 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr);
142 // Frees both the body and the shape. 142 // Frees both the body and the shape.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
index 83df360..c28d69d 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
@@ -151,13 +151,13 @@ public sealed class BSTerrainManager
151 // Release all the terrain structures we might have allocated 151 // Release all the terrain structures we might have allocated
152 public void ReleaseGroundPlaneAndTerrain() 152 public void ReleaseGroundPlaneAndTerrain()
153 { 153 {
154 if (m_groundPlane.ptr != IntPtr.Zero) 154 if (m_groundPlane.HasPhysicalBody)
155 { 155 {
156 if (BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr)) 156 if (BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr))
157 { 157 {
158 BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_groundPlane.ptr); 158 BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_groundPlane.ptr);
159 } 159 }
160 m_groundPlane.ptr = IntPtr.Zero; 160 m_groundPlane.Clear();
161 } 161 }
162 162
163 ReleaseTerrain(); 163 ReleaseTerrain();
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs
index 6ce767d..3473006 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs
@@ -94,7 +94,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys
94 m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr, 94 m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr,
95 indicesCount, indices, verticesCount, vertices), 95 indicesCount, indices, verticesCount, vertices),
96 BSPhysicsShapeType.SHAPE_MESH); 96 BSPhysicsShapeType.SHAPE_MESH);
97 if (m_terrainShape.ptr == IntPtr.Zero) 97 if (!m_terrainShape.HasPhysicalShape)
98 { 98 {
99 // DISASTER!! 99 // DISASTER!!
100 PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape", ID); 100 PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape", ID);
@@ -107,7 +107,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys
107 Quaternion rot = Quaternion.Identity; 107 Quaternion rot = Quaternion.Identity;
108 108
109 m_terrainBody = new BulletBody(id, BulletSimAPI.CreateBodyWithDefaultMotionState2( m_terrainShape.ptr, ID, pos, rot)); 109 m_terrainBody = new BulletBody(id, BulletSimAPI.CreateBodyWithDefaultMotionState2( m_terrainShape.ptr, ID, pos, rot));
110 if (m_terrainBody.ptr == IntPtr.Zero) 110 if (!m_terrainBody.HasPhysicalBody)
111 { 111 {
112 // DISASTER!! 112 // DISASTER!!
113 physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain body! base={1}", LogHeader, TerrainBase); 113 physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain body! base={1}", LogHeader, TerrainBase);
@@ -140,7 +140,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys
140 140
141 public override void Dispose() 141 public override void Dispose()
142 { 142 {
143 if (m_terrainBody.ptr != IntPtr.Zero) 143 if (m_terrainBody.HasPhysicalBody)
144 { 144 {
145 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr); 145 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr);
146 // Frees both the body and the shape. 146 // Frees both the body and the shape.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
index 2671995..1559025 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
@@ -53,6 +53,9 @@ public struct BulletSim
53// An allocated Bullet btRigidBody 53// An allocated Bullet btRigidBody
54public struct BulletBody 54public struct BulletBody
55{ 55{
56 public BulletBody(uint id) : this(id, IntPtr.Zero)
57 {
58 }
56 public BulletBody(uint id, IntPtr xx) 59 public BulletBody(uint id, IntPtr xx)
57 { 60 {
58 ID = id; 61 ID = id;
@@ -64,6 +67,13 @@ public struct BulletBody
64 public uint ID; 67 public uint ID;
65 public CollisionFilterGroups collisionGroup; 68 public CollisionFilterGroups collisionGroup;
66 public CollisionFilterGroups collisionMask; 69 public CollisionFilterGroups collisionMask;
70
71 public void Clear()
72 {
73 ptr = IntPtr.Zero;
74 }
75 public bool HasPhysicalBody { get { return ptr != IntPtr.Zero; } }
76
67 public override string ToString() 77 public override string ToString()
68 { 78 {
69 StringBuilder buff = new StringBuilder(); 79 StringBuilder buff = new StringBuilder();
@@ -103,6 +113,13 @@ public struct BulletShape
103 public BSPhysicsShapeType type; 113 public BSPhysicsShapeType type;
104 public System.UInt64 shapeKey; 114 public System.UInt64 shapeKey;
105 public bool isNativeShape; 115 public bool isNativeShape;
116
117 public void Clear()
118 {
119 ptr = IntPtr.Zero;
120 }
121 public bool HasPhysicalShape { get { return ptr != IntPtr.Zero; } }
122
106 public override string ToString() 123 public override string ToString()
107 { 124 {
108 StringBuilder buff = new StringBuilder(); 125 StringBuilder buff = new StringBuilder();
@@ -140,6 +157,12 @@ public struct BulletConstraint
140 ptr = xx; 157 ptr = xx;
141 } 158 }
142 public IntPtr ptr; 159 public IntPtr ptr;
160
161 public void Clear()
162 {
163 ptr = IntPtr.Zero;
164 }
165 public bool HasPhysicalConstraint { get { return ptr != IntPtr.Zero; } }
143} 166}
144 167
145// An allocated HeightMapThing which holds various heightmap info. 168// An allocated HeightMapThing which holds various heightmap info.