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