aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs76
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}