diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | 81 |
1 files changed, 50 insertions, 31 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 399a133..d189f1d 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 | { |
@@ -358,7 +373,8 @@ public class BSShapeCollection : IDisposable | |||
358 | && pbs.PathScaleX == 100 && pbs.PathScaleY == 100 | 373 | && pbs.PathScaleX == 100 && pbs.PathScaleY == 100 |
359 | && pbs.PathShearX == 0 && pbs.PathShearY == 0) ) ) | 374 | && pbs.PathShearX == 0 && pbs.PathShearY == 0) ) ) |
360 | { | 375 | { |
361 | if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1) | 376 | if ((pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1) |
377 | && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z) | ||
362 | { | 378 | { |
363 | haveShape = true; | 379 | haveShape = true; |
364 | if (forceRebuild | 380 | if (forceRebuild |
@@ -372,7 +388,7 @@ public class BSShapeCollection : IDisposable | |||
372 | prim.LocalID, forceRebuild, prim.BSShape); | 388 | prim.LocalID, forceRebuild, prim.BSShape); |
373 | } | 389 | } |
374 | } | 390 | } |
375 | else | 391 | if (pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight) |
376 | { | 392 | { |
377 | haveShape = true; | 393 | haveShape = true; |
378 | if (forceRebuild | 394 | if (forceRebuild |
@@ -392,7 +408,7 @@ public class BSShapeCollection : IDisposable | |||
392 | // made. Native shapes are best used in either case. | 408 | // made. Native shapes are best used in either case. |
393 | if (!haveShape) | 409 | if (!haveShape) |
394 | { | 410 | { |
395 | if (prim.IsPhysical) | 411 | if (prim.IsPhysical && PhysicsScene.ShouldUseHullsForPhysicalObjects) |
396 | { | 412 | { |
397 | // Update prim.BSShape to reference a hull of this shape. | 413 | // Update prim.BSShape to reference a hull of this shape. |
398 | ret = GetReferenceToHull(prim, shapeData, pbs, shapeCallback); | 414 | ret = GetReferenceToHull(prim, shapeData, pbs, shapeCallback); |
@@ -426,7 +442,7 @@ public class BSShapeCollection : IDisposable | |||
426 | 442 | ||
427 | // Native shapes are always built independently. | 443 | // Native shapes are always built independently. |
428 | newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, shapeData), shapeType); | 444 | newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, shapeData), shapeType); |
429 | newShape.shapeKey = (ulong)shapeKey; | 445 | newShape.shapeKey = (System.UInt64)shapeKey; |
430 | newShape.isNativeShape = true; | 446 | newShape.isNativeShape = true; |
431 | 447 | ||
432 | // Don't need to do a 'ReferenceShape()' here because native shapes are not tracked. | 448 | // Don't need to do a 'ReferenceShape()' here because native shapes are not tracked. |
@@ -446,7 +462,7 @@ public class BSShapeCollection : IDisposable | |||
446 | BulletShape newShape = new BulletShape(IntPtr.Zero); | 462 | BulletShape newShape = new BulletShape(IntPtr.Zero); |
447 | 463 | ||
448 | float lod; | 464 | float lod; |
449 | ulong newMeshKey = ComputeShapeKey(shapeData, pbs, out lod); | 465 | System.UInt64 newMeshKey = ComputeShapeKey(shapeData, pbs, out lod); |
450 | 466 | ||
451 | // if this new shape is the same as last time, don't recreate the mesh | 467 | // 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) | 468 | if (newMeshKey == prim.BSShape.shapeKey && prim.BSShape.type == ShapeData.PhysicsShapeType.SHAPE_MESH) |
@@ -469,7 +485,7 @@ public class BSShapeCollection : IDisposable | |||
469 | return true; // 'true' means a new shape has been added to this prim | 485 | return true; // 'true' means a new shape has been added to this prim |
470 | } | 486 | } |
471 | 487 | ||
472 | private BulletShape CreatePhysicalMesh(string objName, ulong newMeshKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | 488 | private BulletShape CreatePhysicalMesh(string objName, System.UInt64 newMeshKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) |
473 | { | 489 | { |
474 | IMesh meshData = null; | 490 | IMesh meshData = null; |
475 | IntPtr meshPtr; | 491 | IntPtr meshPtr; |
@@ -516,7 +532,7 @@ public class BSShapeCollection : IDisposable | |||
516 | BulletShape newShape; | 532 | BulletShape newShape; |
517 | 533 | ||
518 | float lod; | 534 | float lod; |
519 | ulong newHullKey = ComputeShapeKey(shapeData, pbs, out lod); | 535 | System.UInt64 newHullKey = ComputeShapeKey(shapeData, pbs, out lod); |
520 | 536 | ||
521 | // if the hull hasn't changed, don't rebuild it | 537 | // if the hull hasn't changed, don't rebuild it |
522 | if (newHullKey == prim.BSShape.shapeKey && prim.BSShape.type == ShapeData.PhysicsShapeType.SHAPE_HULL) | 538 | if (newHullKey == prim.BSShape.shapeKey && prim.BSShape.type == ShapeData.PhysicsShapeType.SHAPE_HULL) |
@@ -525,7 +541,7 @@ public class BSShapeCollection : IDisposable | |||
525 | DetailLog("{0},BSShapeCollection.CreateGeomHull,create,oldKey={1},newKey={2}", | 541 | DetailLog("{0},BSShapeCollection.CreateGeomHull,create,oldKey={1},newKey={2}", |
526 | prim.LocalID, prim.BSShape.shapeKey.ToString("X"), newHullKey.ToString("X")); | 542 | prim.LocalID, prim.BSShape.shapeKey.ToString("X"), newHullKey.ToString("X")); |
527 | 543 | ||
528 | // Remove usage of the previous shape. Also removes reference to underlying mesh if it is a hull. | 544 | // Remove usage of the previous shape. |
529 | DereferenceShape(prim.BSShape, true, shapeCallback); | 545 | DereferenceShape(prim.BSShape, true, shapeCallback); |
530 | 546 | ||
531 | newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, pbs, shapeData.Size, lod); | 547 | newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, pbs, shapeData.Size, lod); |
@@ -539,7 +555,7 @@ public class BSShapeCollection : IDisposable | |||
539 | } | 555 | } |
540 | 556 | ||
541 | List<ConvexResult> m_hulls; | 557 | List<ConvexResult> m_hulls; |
542 | private BulletShape CreatePhysicalHull(string objName, ulong newHullKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | 558 | private BulletShape CreatePhysicalHull(string objName, System.UInt64 newHullKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) |
543 | { | 559 | { |
544 | 560 | ||
545 | IntPtr hullPtr; | 561 | IntPtr hullPtr; |
@@ -652,22 +668,23 @@ public class BSShapeCollection : IDisposable | |||
652 | 668 | ||
653 | // Create a hash of all the shape parameters to be used as a key | 669 | // Create a hash of all the shape parameters to be used as a key |
654 | // for this particular shape. | 670 | // for this particular shape. |
655 | private ulong ComputeShapeKey(ShapeData shapeData, PrimitiveBaseShape pbs, out float retLod) | 671 | private System.UInt64 ComputeShapeKey(ShapeData shapeData, PrimitiveBaseShape pbs, out float retLod) |
656 | { | 672 | { |
657 | // level of detail based on size and type of the object | 673 | // level of detail based on size and type of the object |
658 | float lod = PhysicsScene.MeshLOD; | 674 | float lod = PhysicsScene.MeshLOD; |
659 | if (pbs.SculptEntry) | 675 | if (pbs.SculptEntry) |
660 | lod = PhysicsScene.SculptLOD; | 676 | lod = PhysicsScene.SculptLOD; |
661 | 677 | ||
678 | // 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)); | 679 | float maxAxis = Math.Max(shapeData.Size.X, Math.Max(shapeData.Size.Y, shapeData.Size.Z)); |
663 | if (maxAxis > PhysicsScene.MeshMegaPrimThreshold) | 680 | if (maxAxis > PhysicsScene.MeshMegaPrimThreshold) |
664 | lod = PhysicsScene.MeshMegaPrimLOD; | 681 | lod = PhysicsScene.MeshMegaPrimLOD; |
665 | 682 | ||
666 | retLod = lod; | 683 | retLod = lod; |
667 | return (ulong)pbs.GetMeshKey(shapeData.Size, lod); | 684 | return pbs.GetMeshKey(shapeData.Size, lod); |
668 | } | 685 | } |
669 | // For those who don't want the LOD | 686 | // For those who don't want the LOD |
670 | private ulong ComputeShapeKey(ShapeData shapeData, PrimitiveBaseShape pbs) | 687 | private System.UInt64 ComputeShapeKey(ShapeData shapeData, PrimitiveBaseShape pbs) |
671 | { | 688 | { |
672 | float lod; | 689 | float lod; |
673 | return ComputeShapeKey(shapeData, pbs, out lod); | 690 | return ComputeShapeKey(shapeData, pbs, out lod); |
@@ -701,6 +718,7 @@ public class BSShapeCollection : IDisposable | |||
701 | 718 | ||
702 | if (mustRebuild || forceRebuild) | 719 | if (mustRebuild || forceRebuild) |
703 | { | 720 | { |
721 | // Free any old body | ||
704 | DereferenceBody(prim.BSBody, true, bodyCallback); | 722 | DereferenceBody(prim.BSBody, true, bodyCallback); |
705 | 723 | ||
706 | BulletBody aBody; | 724 | BulletBody aBody; |
@@ -709,13 +727,13 @@ public class BSShapeCollection : IDisposable | |||
709 | { | 727 | { |
710 | bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr, | 728 | bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr, |
711 | shapeData.ID, shapeData.Position, shapeData.Rotation); | 729 | shapeData.ID, shapeData.Position, shapeData.Rotation); |
712 | // DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); | 730 | DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); |
713 | } | 731 | } |
714 | else | 732 | else |
715 | { | 733 | { |
716 | bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr, | 734 | bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr, |
717 | shapeData.ID, shapeData.Position, shapeData.Rotation); | 735 | shapeData.ID, shapeData.Position, shapeData.Rotation); |
718 | // DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); | 736 | DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); |
719 | } | 737 | } |
720 | aBody = new BulletBody(shapeData.ID, bodyPtr); | 738 | aBody = new BulletBody(shapeData.ID, bodyPtr); |
721 | 739 | ||
@@ -731,7 +749,8 @@ public class BSShapeCollection : IDisposable | |||
731 | 749 | ||
732 | private void DetailLog(string msg, params Object[] args) | 750 | private void DetailLog(string msg, params Object[] args) |
733 | { | 751 | { |
734 | PhysicsScene.PhysicsLogging.Write(msg, args); | 752 | if (PhysicsScene.PhysicsLogging.Enabled) |
753 | PhysicsScene.DetailLog(msg, args); | ||
735 | } | 754 | } |
736 | } | 755 | } |
737 | } | 756 | } |