diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | 76 |
1 files changed, 47 insertions, 29 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 399a133..d5e2172 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | |||
@@ -67,8 +67,8 @@ public class BSShapeCollection : IDisposable | |||
67 | public DateTime lastReferenced; | 67 | public DateTime lastReferenced; |
68 | } | 68 | } |
69 | 69 | ||
70 | private Dictionary<ulong, MeshDesc> Meshes = new Dictionary<ulong, MeshDesc>(); | 70 | private Dictionary<System.UInt64, MeshDesc> Meshes = new Dictionary<System.UInt64, MeshDesc>(); |
71 | private Dictionary<ulong, HullDesc> Hulls = new Dictionary<ulong, HullDesc>(); | 71 | private Dictionary<System.UInt64, HullDesc> Hulls = new Dictionary<System.UInt64, HullDesc>(); |
72 | private Dictionary<uint, BodyDesc> Bodies = new Dictionary<uint, BodyDesc>(); | 72 | private Dictionary<uint, BodyDesc> Bodies = new Dictionary<uint, BodyDesc>(); |
73 | 73 | ||
74 | public BSShapeCollection(BSScene physScene) | 74 | public BSShapeCollection(BSScene physScene) |
@@ -121,7 +121,7 @@ public class BSShapeCollection : IDisposable | |||
121 | // Track another user of a body | 121 | // Track another user of a body |
122 | // We presume the caller has allocated the body. | 122 | // We presume the caller has allocated the body. |
123 | // Bodies only have one user so the reference count is either 1 or 0. | 123 | // Bodies only have one user so the reference count is either 1 or 0. |
124 | public void ReferenceBody(BulletBody body, bool atTaintTime) | 124 | public void ReferenceBody(BulletBody body, bool inTaintTime) |
125 | { | 125 | { |
126 | lock (m_collectionActivityLock) | 126 | lock (m_collectionActivityLock) |
127 | { | 127 | { |
@@ -136,7 +136,21 @@ public class BSShapeCollection : IDisposable | |||
136 | // New entry | 136 | // New entry |
137 | bodyDesc.ptr = body.ptr; | 137 | bodyDesc.ptr = body.ptr; |
138 | bodyDesc.referenceCount = 1; | 138 | bodyDesc.referenceCount = 1; |
139 | DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,ref={1}", body.ID, body, bodyDesc.referenceCount); | 139 | DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,ref={2}", |
140 | body.ID, body, bodyDesc.referenceCount); | ||
141 | BSScene.TaintCallback createOperation = delegate() | ||
142 | { | ||
143 | if (!BulletSimAPI.IsInWorld2(body.ptr)) | ||
144 | { | ||
145 | BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, body.ptr); | ||
146 | DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", | ||
147 | body.ID, body); | ||
148 | } | ||
149 | }; | ||
150 | if (inTaintTime) | ||
151 | createOperation(); | ||
152 | else | ||
153 | PhysicsScene.TaintedObject("BSShapeCollection.ReferenceBody", createOperation); | ||
140 | } | 154 | } |
141 | bodyDesc.lastReferenced = System.DateTime.Now; | 155 | bodyDesc.lastReferenced = System.DateTime.Now; |
142 | Bodies[body.ID] = bodyDesc; | 156 | Bodies[body.ID] = bodyDesc; |
@@ -160,21 +174,22 @@ public class BSShapeCollection : IDisposable | |||
160 | Bodies[body.ID] = bodyDesc; | 174 | Bodies[body.ID] = bodyDesc; |
161 | DetailLog("{0},BSShapeCollection.DereferenceBody,ref={1}", body.ID, bodyDesc.referenceCount); | 175 | DetailLog("{0},BSShapeCollection.DereferenceBody,ref={1}", body.ID, bodyDesc.referenceCount); |
162 | 176 | ||
163 | // If body is no longer being used, free it -- bodies are never shared. | 177 | // If body is no longer being used, free it -- bodies can never be shared. |
164 | if (bodyDesc.referenceCount == 0) | 178 | if (bodyDesc.referenceCount == 0) |
165 | { | 179 | { |
166 | Bodies.Remove(body.ID); | 180 | Bodies.Remove(body.ID); |
167 | BSScene.TaintCallback removeOperation = delegate() | 181 | BSScene.TaintCallback removeOperation = delegate() |
168 | { | 182 | { |
169 | DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody. ptr={1}", | 183 | DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody. ptr={1}, inTaintTime={2}", |
170 | body.ID, body.ptr.ToString("X")); | 184 | body.ID, body.ptr.ToString("X"), inTaintTime); |
171 | // If the caller needs to know the old body is going away, pass the event up. | 185 | // If the caller needs to know the old body is going away, pass the event up. |
172 | if (bodyCallback != null) bodyCallback(body); | 186 | if (bodyCallback != null) bodyCallback(body); |
173 | 187 | ||
174 | // Zero any reference to the shape so it is not freed when the body is deleted. | ||
175 | BulletSimAPI.SetCollisionShape2(PhysicsScene.World.ptr, body.ptr, IntPtr.Zero); | ||
176 | // It may have already been removed from the world in which case the next is a NOOP. | 188 | // It may have already been removed from the world in which case the next is a NOOP. |
177 | BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, body.ptr); | 189 | BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, body.ptr); |
190 | |||
191 | // Zero any reference to the shape so it is not freed when the body is deleted. | ||
192 | BulletSimAPI.SetCollisionShape2(PhysicsScene.World.ptr, body.ptr, IntPtr.Zero); | ||
178 | BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, body.ptr); | 193 | BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, body.ptr); |
179 | }; | 194 | }; |
180 | // If already in taint-time, do the operations now. Otherwise queue for later. | 195 | // If already in taint-time, do the operations now. Otherwise queue for later. |
@@ -208,7 +223,7 @@ public class BSShapeCollection : IDisposable | |||
208 | { | 223 | { |
209 | // There is an existing instance of this mesh. | 224 | // There is an existing instance of this mesh. |
210 | meshDesc.referenceCount++; | 225 | meshDesc.referenceCount++; |
211 | DetailLog("{0},BSShapeColliction.ReferenceShape,existingMesh,key={1},cnt={2}", | 226 | DetailLog("{0},BSShapeCollection.ReferenceShape,existingMesh,key={1},cnt={2}", |
212 | BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount); | 227 | BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount); |
213 | } | 228 | } |
214 | else | 229 | else |
@@ -217,7 +232,7 @@ public class BSShapeCollection : IDisposable | |||
217 | meshDesc.ptr = shape.ptr; | 232 | meshDesc.ptr = shape.ptr; |
218 | // We keep a reference to the underlying IMesh data so a hull can be built | 233 | // We keep a reference to the underlying IMesh data so a hull can be built |
219 | meshDesc.referenceCount = 1; | 234 | meshDesc.referenceCount = 1; |
220 | DetailLog("{0},BSShapeColliction.ReferenceShape,newMesh,key={1},cnt={2}", | 235 | DetailLog("{0},BSShapeCollection.ReferenceShape,newMesh,key={1},cnt={2}", |
221 | BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount); | 236 | BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount); |
222 | ret = true; | 237 | ret = true; |
223 | } | 238 | } |
@@ -230,7 +245,7 @@ public class BSShapeCollection : IDisposable | |||
230 | { | 245 | { |
231 | // There is an existing instance of this hull. | 246 | // There is an existing instance of this hull. |
232 | hullDesc.referenceCount++; | 247 | hullDesc.referenceCount++; |
233 | DetailLog("{0},BSShapeColliction.ReferenceShape,existingHull,key={1},cnt={2}", | 248 | DetailLog("{0},BSShapeCollection.ReferenceShape,existingHull,key={1},cnt={2}", |
234 | BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount); | 249 | BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount); |
235 | } | 250 | } |
236 | else | 251 | else |
@@ -238,7 +253,7 @@ public class BSShapeCollection : IDisposable | |||
238 | // This is a new reference to a hull | 253 | // This is a new reference to a hull |
239 | hullDesc.ptr = shape.ptr; | 254 | hullDesc.ptr = shape.ptr; |
240 | hullDesc.referenceCount = 1; | 255 | hullDesc.referenceCount = 1; |
241 | DetailLog("{0},BSShapeColliction.ReferenceShape,newHull,key={1},cnt={2}", | 256 | DetailLog("{0},BSShapeCollection.ReferenceShape,newHull,key={1},cnt={2}", |
242 | BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount); | 257 | BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount); |
243 | ret = true; | 258 | ret = true; |
244 | 259 | ||
@@ -257,7 +272,7 @@ public class BSShapeCollection : IDisposable | |||
257 | 272 | ||
258 | // Release the usage of a shape. | 273 | // Release the usage of a shape. |
259 | // The collisionObject is released since it is a copy of the real collision shape. | 274 | // The collisionObject is released since it is a copy of the real collision shape. |
260 | public void DereferenceShape(BulletShape shape, bool atTaintTime, ShapeDestructionCallback shapeCallback) | 275 | public void DereferenceShape(BulletShape shape, bool inTaintTime, ShapeDestructionCallback shapeCallback) |
261 | { | 276 | { |
262 | if (shape.ptr == IntPtr.Zero) | 277 | if (shape.ptr == IntPtr.Zero) |
263 | return; | 278 | return; |
@@ -279,14 +294,14 @@ public class BSShapeCollection : IDisposable | |||
279 | if (shape.ptr != IntPtr.Zero & shape.isNativeShape) | 294 | if (shape.ptr != IntPtr.Zero & shape.isNativeShape) |
280 | { | 295 | { |
281 | DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}", | 296 | DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}", |
282 | BSScene.DetailLogZero, shape.ptr.ToString("X"), atTaintTime); | 297 | BSScene.DetailLogZero, shape.ptr.ToString("X"), inTaintTime); |
283 | if (shapeCallback != null) shapeCallback(shape); | 298 | if (shapeCallback != null) shapeCallback(shape); |
284 | BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr); | 299 | BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr); |
285 | } | 300 | } |
286 | break; | 301 | break; |
287 | } | 302 | } |
288 | }; | 303 | }; |
289 | if (atTaintTime) | 304 | if (inTaintTime) |
290 | { | 305 | { |
291 | lock (m_collectionActivityLock) | 306 | lock (m_collectionActivityLock) |
292 | { | 307 | { |
@@ -392,7 +407,7 @@ public class BSShapeCollection : IDisposable | |||
392 | // made. Native shapes are best used in either case. | 407 | // made. Native shapes are best used in either case. |
393 | if (!haveShape) | 408 | if (!haveShape) |
394 | { | 409 | { |
395 | if (prim.IsPhysical) | 410 | if (prim.IsPhysical && PhysicsScene.ShouldUseHullsForPhysicalObjects) |
396 | { | 411 | { |
397 | // Update prim.BSShape to reference a hull of this shape. | 412 | // Update prim.BSShape to reference a hull of this shape. |
398 | ret = GetReferenceToHull(prim, shapeData, pbs, shapeCallback); | 413 | ret = GetReferenceToHull(prim, shapeData, pbs, shapeCallback); |
@@ -426,7 +441,7 @@ public class BSShapeCollection : IDisposable | |||
426 | 441 | ||
427 | // Native shapes are always built independently. | 442 | // Native shapes are always built independently. |
428 | newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, shapeData), shapeType); | 443 | newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, shapeData), shapeType); |
429 | newShape.shapeKey = (ulong)shapeKey; | 444 | newShape.shapeKey = (System.UInt64)shapeKey; |
430 | newShape.isNativeShape = true; | 445 | newShape.isNativeShape = true; |
431 | 446 | ||
432 | // Don't need to do a 'ReferenceShape()' here because native shapes are not tracked. | 447 | // Don't need to do a 'ReferenceShape()' here because native shapes are not tracked. |
@@ -446,7 +461,7 @@ public class BSShapeCollection : IDisposable | |||
446 | BulletShape newShape = new BulletShape(IntPtr.Zero); | 461 | BulletShape newShape = new BulletShape(IntPtr.Zero); |
447 | 462 | ||
448 | float lod; | 463 | float lod; |
449 | ulong newMeshKey = ComputeShapeKey(shapeData, pbs, out lod); | 464 | System.UInt64 newMeshKey = ComputeShapeKey(shapeData, pbs, out lod); |
450 | 465 | ||
451 | // if this new shape is the same as last time, don't recreate the mesh | 466 | // if this new shape is the same as last time, don't recreate the mesh |
452 | if (newMeshKey == prim.BSShape.shapeKey && prim.BSShape.type == ShapeData.PhysicsShapeType.SHAPE_MESH) | 467 | if (newMeshKey == prim.BSShape.shapeKey && prim.BSShape.type == ShapeData.PhysicsShapeType.SHAPE_MESH) |
@@ -469,7 +484,7 @@ public class BSShapeCollection : IDisposable | |||
469 | return true; // 'true' means a new shape has been added to this prim | 484 | return true; // 'true' means a new shape has been added to this prim |
470 | } | 485 | } |
471 | 486 | ||
472 | private BulletShape CreatePhysicalMesh(string objName, ulong newMeshKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | 487 | private BulletShape CreatePhysicalMesh(string objName, System.UInt64 newMeshKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) |
473 | { | 488 | { |
474 | IMesh meshData = null; | 489 | IMesh meshData = null; |
475 | IntPtr meshPtr; | 490 | IntPtr meshPtr; |
@@ -516,7 +531,7 @@ public class BSShapeCollection : IDisposable | |||
516 | BulletShape newShape; | 531 | BulletShape newShape; |
517 | 532 | ||
518 | float lod; | 533 | float lod; |
519 | ulong newHullKey = ComputeShapeKey(shapeData, pbs, out lod); | 534 | System.UInt64 newHullKey = ComputeShapeKey(shapeData, pbs, out lod); |
520 | 535 | ||
521 | // if the hull hasn't changed, don't rebuild it | 536 | // if the hull hasn't changed, don't rebuild it |
522 | if (newHullKey == prim.BSShape.shapeKey && prim.BSShape.type == ShapeData.PhysicsShapeType.SHAPE_HULL) | 537 | if (newHullKey == prim.BSShape.shapeKey && prim.BSShape.type == ShapeData.PhysicsShapeType.SHAPE_HULL) |
@@ -525,7 +540,7 @@ public class BSShapeCollection : IDisposable | |||
525 | DetailLog("{0},BSShapeCollection.CreateGeomHull,create,oldKey={1},newKey={2}", | 540 | DetailLog("{0},BSShapeCollection.CreateGeomHull,create,oldKey={1},newKey={2}", |
526 | prim.LocalID, prim.BSShape.shapeKey.ToString("X"), newHullKey.ToString("X")); | 541 | prim.LocalID, prim.BSShape.shapeKey.ToString("X"), newHullKey.ToString("X")); |
527 | 542 | ||
528 | // Remove usage of the previous shape. Also removes reference to underlying mesh if it is a hull. | 543 | // Remove usage of the previous shape. |
529 | DereferenceShape(prim.BSShape, true, shapeCallback); | 544 | DereferenceShape(prim.BSShape, true, shapeCallback); |
530 | 545 | ||
531 | newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, pbs, shapeData.Size, lod); | 546 | newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, pbs, shapeData.Size, lod); |
@@ -539,7 +554,7 @@ public class BSShapeCollection : IDisposable | |||
539 | } | 554 | } |
540 | 555 | ||
541 | List<ConvexResult> m_hulls; | 556 | List<ConvexResult> m_hulls; |
542 | private BulletShape CreatePhysicalHull(string objName, ulong newHullKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | 557 | private BulletShape CreatePhysicalHull(string objName, System.UInt64 newHullKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) |
543 | { | 558 | { |
544 | 559 | ||
545 | IntPtr hullPtr; | 560 | IntPtr hullPtr; |
@@ -652,22 +667,23 @@ public class BSShapeCollection : IDisposable | |||
652 | 667 | ||
653 | // Create a hash of all the shape parameters to be used as a key | 668 | // Create a hash of all the shape parameters to be used as a key |
654 | // for this particular shape. | 669 | // for this particular shape. |
655 | private ulong ComputeShapeKey(ShapeData shapeData, PrimitiveBaseShape pbs, out float retLod) | 670 | private System.UInt64 ComputeShapeKey(ShapeData shapeData, PrimitiveBaseShape pbs, out float retLod) |
656 | { | 671 | { |
657 | // level of detail based on size and type of the object | 672 | // level of detail based on size and type of the object |
658 | float lod = PhysicsScene.MeshLOD; | 673 | float lod = PhysicsScene.MeshLOD; |
659 | if (pbs.SculptEntry) | 674 | if (pbs.SculptEntry) |
660 | lod = PhysicsScene.SculptLOD; | 675 | lod = PhysicsScene.SculptLOD; |
661 | 676 | ||
677 | // Mega prims usually get more detail because one can interact with shape approximations at this size. | ||
662 | float maxAxis = Math.Max(shapeData.Size.X, Math.Max(shapeData.Size.Y, shapeData.Size.Z)); | 678 | float maxAxis = Math.Max(shapeData.Size.X, Math.Max(shapeData.Size.Y, shapeData.Size.Z)); |
663 | if (maxAxis > PhysicsScene.MeshMegaPrimThreshold) | 679 | if (maxAxis > PhysicsScene.MeshMegaPrimThreshold) |
664 | lod = PhysicsScene.MeshMegaPrimLOD; | 680 | lod = PhysicsScene.MeshMegaPrimLOD; |
665 | 681 | ||
666 | retLod = lod; | 682 | retLod = lod; |
667 | return (ulong)pbs.GetMeshKey(shapeData.Size, lod); | 683 | return pbs.GetMeshKey(shapeData.Size, lod); |
668 | } | 684 | } |
669 | // For those who don't want the LOD | 685 | // For those who don't want the LOD |
670 | private ulong ComputeShapeKey(ShapeData shapeData, PrimitiveBaseShape pbs) | 686 | private System.UInt64 ComputeShapeKey(ShapeData shapeData, PrimitiveBaseShape pbs) |
671 | { | 687 | { |
672 | float lod; | 688 | float lod; |
673 | return ComputeShapeKey(shapeData, pbs, out lod); | 689 | return ComputeShapeKey(shapeData, pbs, out lod); |
@@ -701,6 +717,7 @@ public class BSShapeCollection : IDisposable | |||
701 | 717 | ||
702 | if (mustRebuild || forceRebuild) | 718 | if (mustRebuild || forceRebuild) |
703 | { | 719 | { |
720 | // Free any old body | ||
704 | DereferenceBody(prim.BSBody, true, bodyCallback); | 721 | DereferenceBody(prim.BSBody, true, bodyCallback); |
705 | 722 | ||
706 | BulletBody aBody; | 723 | BulletBody aBody; |
@@ -709,13 +726,13 @@ public class BSShapeCollection : IDisposable | |||
709 | { | 726 | { |
710 | bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr, | 727 | bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr, |
711 | shapeData.ID, shapeData.Position, shapeData.Rotation); | 728 | shapeData.ID, shapeData.Position, shapeData.Rotation); |
712 | // DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); | 729 | DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); |
713 | } | 730 | } |
714 | else | 731 | else |
715 | { | 732 | { |
716 | bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr, | 733 | bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr, |
717 | shapeData.ID, shapeData.Position, shapeData.Rotation); | 734 | shapeData.ID, shapeData.Position, shapeData.Rotation); |
718 | // DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); | 735 | DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); |
719 | } | 736 | } |
720 | aBody = new BulletBody(shapeData.ID, bodyPtr); | 737 | aBody = new BulletBody(shapeData.ID, bodyPtr); |
721 | 738 | ||
@@ -731,7 +748,8 @@ public class BSShapeCollection : IDisposable | |||
731 | 748 | ||
732 | private void DetailLog(string msg, params Object[] args) | 749 | private void DetailLog(string msg, params Object[] args) |
733 | { | 750 | { |
734 | PhysicsScene.PhysicsLogging.Write(msg, args); | 751 | if (PhysicsScene.PhysicsLogging.Enabled) |
752 | PhysicsScene.DetailLog(msg, args); | ||
735 | } | 753 | } |
736 | } | 754 | } |
737 | } | 755 | } |