diff options
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 | ||
33 | namespace OpenSim.Region.Physics.BulletSPlugin | 33 | namespace 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. | ||
39 | public abstract class BSLinksetInfo | ||
40 | { | ||
41 | } | ||
42 | |||
35 | public abstract class BSLinkset | 43 | public 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 | ||
33 | namespace OpenSim.Region.Physics.BulletSPlugin | 33 | namespace 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. | ||
39 | sealed 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 | |||
35 | public sealed class BSLinksetCompound : BSLinkset | 60 | public 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 |
54 | public struct BulletBody | 54 | public 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. |