diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | 65 |
1 files changed, 41 insertions, 24 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index b428ba3..2618971 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | |||
@@ -81,12 +81,21 @@ public class BSShapeCollection : IDisposable | |||
81 | // TODO!!!!!!!!! | 81 | // TODO!!!!!!!!! |
82 | } | 82 | } |
83 | 83 | ||
84 | // Callbacks called just before either the body or shape is destroyed. | ||
85 | // Mostly used for changing bodies out from under Linksets. | ||
86 | // Useful for other cases where parameters need saving. | ||
87 | // Passing 'null' says no callback. | ||
88 | public delegate void ShapeDestructionCallback(BulletShape shape); | ||
89 | public delegate void BodyDestructionCallback(BulletBody body); | ||
90 | |||
84 | // Called to update/change the body and shape for an object. | 91 | // Called to update/change the body and shape for an object. |
85 | // First checks the shape and updates that if necessary then makes | 92 | // First checks the shape and updates that if necessary then makes |
86 | // sure the body is of the right type. | 93 | // sure the body is of the right type. |
87 | // Return 'true' if either the body or the shape changed. | 94 | // Return 'true' if either the body or the shape changed. |
88 | // Called at taint-time!! | 95 | // Called at taint-time!! |
89 | public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPrim prim, ShapeData shapeData, PrimitiveBaseShape pbs) | 96 | public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPrim prim, |
97 | ShapeData shapeData, PrimitiveBaseShape pbs, | ||
98 | ShapeDestructionCallback shapeCallback, BodyDestructionCallback bodyCallback) | ||
90 | { | 99 | { |
91 | bool ret = false; | 100 | bool ret = false; |
92 | 101 | ||
@@ -95,11 +104,11 @@ public class BSShapeCollection : IDisposable | |||
95 | { | 104 | { |
96 | // Do we have the correct geometry for this type of object? | 105 | // Do we have the correct geometry for this type of object? |
97 | // Updates prim.BSShape with information/pointers to requested shape | 106 | // Updates prim.BSShape with information/pointers to requested shape |
98 | bool newGeom = CreateGeom(forceRebuild, prim, shapeData, pbs); | 107 | bool newGeom = CreateGeom(forceRebuild, prim, shapeData, pbs, shapeCallback); |
99 | // If we had to select a new shape geometry for the object, | 108 | // If we had to select a new shape geometry for the object, |
100 | // rebuild the body around it. | 109 | // rebuild the body around it. |
101 | // Updates prim.BSBody with information/pointers to requested body | 110 | // Updates prim.BSBody with information/pointers to requested body |
102 | bool newBody = CreateBody((newGeom || forceRebuild), prim, PhysicsScene.World, prim.BSShape, shapeData); | 111 | bool newBody = CreateBody((newGeom || forceRebuild), prim, PhysicsScene.World, prim.BSShape, shapeData, bodyCallback); |
103 | ret = newGeom || newBody; | 112 | ret = newGeom || newBody; |
104 | } | 113 | } |
105 | DetailLog("{0},BSShapeCollection.GetBodyAndShape,force={1},ret={2},body={3},shape={4}", | 114 | DetailLog("{0},BSShapeCollection.GetBodyAndShape,force={1},ret={2},body={3},shape={4}", |
@@ -135,7 +144,7 @@ public class BSShapeCollection : IDisposable | |||
135 | 144 | ||
136 | // Release the usage of a body. | 145 | // Release the usage of a body. |
137 | // Called when releasing use of a BSBody. BSShape is handled separately. | 146 | // Called when releasing use of a BSBody. BSShape is handled separately. |
138 | public void DereferenceBody(BulletBody shape, bool inTaintTime) | 147 | public void DereferenceBody(BulletBody shape, bool inTaintTime, BodyDestructionCallback bodyCallback ) |
139 | { | 148 | { |
140 | if (shape.ptr == IntPtr.Zero) | 149 | if (shape.ptr == IntPtr.Zero) |
141 | return; | 150 | return; |
@@ -244,7 +253,7 @@ public class BSShapeCollection : IDisposable | |||
244 | 253 | ||
245 | // Release the usage of a shape. | 254 | // Release the usage of a shape. |
246 | // The collisionObject is released since it is a copy of the real collision shape. | 255 | // The collisionObject is released since it is a copy of the real collision shape. |
247 | private void DereferenceShape(BulletShape shape, bool atTaintTime) | 256 | private void DereferenceShape(BulletShape shape, bool atTaintTime, ShapeDestructionCallback shapeCallback) |
248 | { | 257 | { |
249 | if (shape.ptr == IntPtr.Zero) | 258 | if (shape.ptr == IntPtr.Zero) |
250 | return; | 259 | return; |
@@ -254,10 +263,10 @@ public class BSShapeCollection : IDisposable | |||
254 | switch (shape.type) | 263 | switch (shape.type) |
255 | { | 264 | { |
256 | case ShapeData.PhysicsShapeType.SHAPE_HULL: | 265 | case ShapeData.PhysicsShapeType.SHAPE_HULL: |
257 | DereferenceHull(shape); | 266 | DereferenceHull(shape, shapeCallback); |
258 | break; | 267 | break; |
259 | case ShapeData.PhysicsShapeType.SHAPE_MESH: | 268 | case ShapeData.PhysicsShapeType.SHAPE_MESH: |
260 | DereferenceMesh(shape); | 269 | DereferenceMesh(shape, shapeCallback); |
261 | break; | 270 | break; |
262 | case ShapeData.PhysicsShapeType.SHAPE_UNKNOWN: | 271 | case ShapeData.PhysicsShapeType.SHAPE_UNKNOWN: |
263 | break; | 272 | break; |
@@ -267,6 +276,7 @@ public class BSShapeCollection : IDisposable | |||
267 | { | 276 | { |
268 | DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}", | 277 | DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}", |
269 | BSScene.DetailLogZero, shape.ptr.ToString("X"), atTaintTime); | 278 | BSScene.DetailLogZero, shape.ptr.ToString("X"), atTaintTime); |
279 | if (shapeCallback != null) shapeCallback(shape); | ||
270 | BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr); | 280 | BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr); |
271 | } | 281 | } |
272 | break; | 282 | break; |
@@ -287,13 +297,14 @@ public class BSShapeCollection : IDisposable | |||
287 | 297 | ||
288 | // Count down the reference count for a mesh shape | 298 | // Count down the reference count for a mesh shape |
289 | // Called at taint-time. | 299 | // Called at taint-time. |
290 | private void DereferenceMesh(BulletShape shape) | 300 | private void DereferenceMesh(BulletShape shape, ShapeDestructionCallback shapeCallback) |
291 | { | 301 | { |
292 | MeshDesc meshDesc; | 302 | MeshDesc meshDesc; |
293 | if (Meshes.TryGetValue(shape.shapeKey, out meshDesc)) | 303 | if (Meshes.TryGetValue(shape.shapeKey, out meshDesc)) |
294 | { | 304 | { |
295 | meshDesc.referenceCount--; | 305 | meshDesc.referenceCount--; |
296 | // TODO: release the Bullet storage | 306 | // TODO: release the Bullet storage |
307 | if (shapeCallback != null) shapeCallback(shape); | ||
297 | meshDesc.lastReferenced = System.DateTime.Now; | 308 | meshDesc.lastReferenced = System.DateTime.Now; |
298 | Meshes[shape.shapeKey] = meshDesc; | 309 | Meshes[shape.shapeKey] = meshDesc; |
299 | DetailLog("{0},BSShapeCollection.DereferenceMesh,key={1},refCnt={2}", | 310 | DetailLog("{0},BSShapeCollection.DereferenceMesh,key={1},refCnt={2}", |
@@ -304,13 +315,14 @@ public class BSShapeCollection : IDisposable | |||
304 | 315 | ||
305 | // Count down the reference count for a hull shape | 316 | // Count down the reference count for a hull shape |
306 | // Called at taint-time. | 317 | // Called at taint-time. |
307 | private void DereferenceHull(BulletShape shape) | 318 | private void DereferenceHull(BulletShape shape, ShapeDestructionCallback shapeCallback) |
308 | { | 319 | { |
309 | HullDesc hullDesc; | 320 | HullDesc hullDesc; |
310 | if (Hulls.TryGetValue(shape.shapeKey, out hullDesc)) | 321 | if (Hulls.TryGetValue(shape.shapeKey, out hullDesc)) |
311 | { | 322 | { |
312 | hullDesc.referenceCount--; | 323 | hullDesc.referenceCount--; |
313 | // TODO: release the Bullet storage (aging old entries?) | 324 | // TODO: release the Bullet storage (aging old entries?) |
325 | if (shapeCallback != null) shapeCallback(shape); | ||
314 | hullDesc.lastReferenced = System.DateTime.Now; | 326 | hullDesc.lastReferenced = System.DateTime.Now; |
315 | Hulls[shape.shapeKey] = hullDesc; | 327 | Hulls[shape.shapeKey] = hullDesc; |
316 | DetailLog("{0},BSShapeCollection.DereferenceHull,key={1},refCnt={2}", | 328 | DetailLog("{0},BSShapeCollection.DereferenceHull,key={1},refCnt={2}", |
@@ -324,7 +336,8 @@ public class BSShapeCollection : IDisposable | |||
324 | // if 'forceRebuild' is true, the geometry is rebuilt. Otherwise a previously built version is used. | 336 | // if 'forceRebuild' is true, the geometry is rebuilt. Otherwise a previously built version is used. |
325 | // Returns 'true' if the geometry was rebuilt. | 337 | // Returns 'true' if the geometry was rebuilt. |
326 | // Called at taint-time! | 338 | // Called at taint-time! |
327 | private bool CreateGeom(bool forceRebuild, BSPrim prim, ShapeData shapeData, PrimitiveBaseShape pbs) | 339 | private bool CreateGeom(bool forceRebuild, BSPrim prim, ShapeData shapeData, |
340 | PrimitiveBaseShape pbs, ShapeDestructionCallback shapeCallback) | ||
328 | { | 341 | { |
329 | bool ret = false; | 342 | bool ret = false; |
330 | bool haveShape = false; | 343 | bool haveShape = false; |
@@ -349,8 +362,8 @@ public class BSShapeCollection : IDisposable | |||
349 | || prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_SPHERE | 362 | || prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_SPHERE |
350 | ) | 363 | ) |
351 | { | 364 | { |
352 | ret = GetReferenceToNativeShape(prim, shapeData, | 365 | ret = GetReferenceToNativeShape(prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_SPHERE, |
353 | ShapeData.PhysicsShapeType.SHAPE_SPHERE, ShapeData.FixedShapeKey.KEY_SPHERE); | 366 | ShapeData.FixedShapeKey.KEY_SPHERE, shapeCallback); |
354 | DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}", | 367 | DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}", |
355 | prim.LocalID, forceRebuild, prim.BSShape); | 368 | prim.LocalID, forceRebuild, prim.BSShape); |
356 | } | 369 | } |
@@ -363,8 +376,8 @@ public class BSShapeCollection : IDisposable | |||
363 | || prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_BOX | 376 | || prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_BOX |
364 | ) | 377 | ) |
365 | { | 378 | { |
366 | ret = GetReferenceToNativeShape( | 379 | ret = GetReferenceToNativeShape( prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_BOX, |
367 | prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_BOX, ShapeData.FixedShapeKey.KEY_BOX); | 380 | ShapeData.FixedShapeKey.KEY_BOX, shapeCallback); |
368 | DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}", | 381 | DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}", |
369 | prim.LocalID, forceRebuild, prim.BSShape); | 382 | prim.LocalID, forceRebuild, prim.BSShape); |
370 | } | 383 | } |
@@ -378,13 +391,13 @@ public class BSShapeCollection : IDisposable | |||
378 | if (prim.IsPhysical) | 391 | if (prim.IsPhysical) |
379 | { | 392 | { |
380 | // Update prim.BSShape to reference a hull of this shape. | 393 | // Update prim.BSShape to reference a hull of this shape. |
381 | ret = GetReferenceToHull(prim, shapeData, pbs); | 394 | ret = GetReferenceToHull(prim, shapeData, pbs, shapeCallback); |
382 | DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", | 395 | DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", |
383 | shapeData.ID, prim.BSShape, prim.BSShape.shapeKey.ToString("X")); | 396 | shapeData.ID, prim.BSShape, prim.BSShape.shapeKey.ToString("X")); |
384 | } | 397 | } |
385 | else | 398 | else |
386 | { | 399 | { |
387 | ret = GetReferenceToMesh(prim, shapeData, pbs); | 400 | ret = GetReferenceToMesh(prim, shapeData, pbs, shapeCallback); |
388 | DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}", | 401 | DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}", |
389 | shapeData.ID, prim.BSShape, prim.BSShape.shapeKey.ToString("X")); | 402 | shapeData.ID, prim.BSShape, prim.BSShape.shapeKey.ToString("X")); |
390 | } | 403 | } |
@@ -394,7 +407,8 @@ public class BSShapeCollection : IDisposable | |||
394 | 407 | ||
395 | // Creates a native shape and assignes it to prim.BSShape | 408 | // Creates a native shape and assignes it to prim.BSShape |
396 | private bool GetReferenceToNativeShape( BSPrim prim, ShapeData shapeData, | 409 | private bool GetReferenceToNativeShape( BSPrim prim, ShapeData shapeData, |
397 | ShapeData.PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey) | 410 | ShapeData.PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey, |
411 | ShapeDestructionCallback shapeCallback) | ||
398 | { | 412 | { |
399 | BulletShape newShape; | 413 | BulletShape newShape; |
400 | 414 | ||
@@ -404,7 +418,7 @@ public class BSShapeCollection : IDisposable | |||
404 | shapeData.Scale = shapeData.Size; | 418 | shapeData.Scale = shapeData.Size; |
405 | 419 | ||
406 | // release any previous shape | 420 | // release any previous shape |
407 | DereferenceShape(prim.BSShape, true); | 421 | DereferenceShape(prim.BSShape, true, shapeCallback); |
408 | 422 | ||
409 | // Native shapes are always built independently. | 423 | // Native shapes are always built independently. |
410 | newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, shapeData), shapeType); | 424 | newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, shapeData), shapeType); |
@@ -422,7 +436,8 @@ public class BSShapeCollection : IDisposable | |||
422 | // Dereferences previous shape in BSShape and adds a reference for this new shape. | 436 | // Dereferences previous shape in BSShape and adds a reference for this new shape. |
423 | // Returns 'true' of a mesh was actually built. Otherwise . | 437 | // Returns 'true' of a mesh was actually built. Otherwise . |
424 | // Called at taint-time! | 438 | // Called at taint-time! |
425 | private bool GetReferenceToMesh(BSPrim prim, ShapeData shapeData, PrimitiveBaseShape pbs) | 439 | private bool GetReferenceToMesh(BSPrim prim, ShapeData shapeData, PrimitiveBaseShape pbs, |
440 | ShapeDestructionCallback shapeCallback) | ||
426 | { | 441 | { |
427 | BulletShape newShape = new BulletShape(IntPtr.Zero); | 442 | BulletShape newShape = new BulletShape(IntPtr.Zero); |
428 | 443 | ||
@@ -436,7 +451,7 @@ public class BSShapeCollection : IDisposable | |||
436 | prim.LocalID, prim.BSShape.shapeKey.ToString("X"), newMeshKey.ToString("X")); | 451 | prim.LocalID, prim.BSShape.shapeKey.ToString("X"), newMeshKey.ToString("X")); |
437 | 452 | ||
438 | // Since we're recreating new, get rid of the reference to the previous shape | 453 | // Since we're recreating new, get rid of the reference to the previous shape |
439 | DereferenceShape(prim.BSShape, true); | 454 | DereferenceShape(prim.BSShape, true, shapeCallback); |
440 | 455 | ||
441 | newShape = CreatePhysicalMesh(prim.PhysObjectName, newMeshKey, pbs, shapeData.Size, lod); | 456 | newShape = CreatePhysicalMesh(prim.PhysObjectName, newMeshKey, pbs, shapeData.Size, lod); |
442 | 457 | ||
@@ -490,7 +505,8 @@ public class BSShapeCollection : IDisposable | |||
490 | 505 | ||
491 | // See that hull shape exists in the physical world and update prim.BSShape. | 506 | // See that hull shape exists in the physical world and update prim.BSShape. |
492 | // We could be creating the hull because scale changed or whatever. | 507 | // We could be creating the hull because scale changed or whatever. |
493 | private bool GetReferenceToHull(BSPrim prim, ShapeData shapeData, PrimitiveBaseShape pbs) | 508 | private bool GetReferenceToHull(BSPrim prim, ShapeData shapeData, PrimitiveBaseShape pbs, |
509 | ShapeDestructionCallback shapeCallback) | ||
494 | { | 510 | { |
495 | BulletShape newShape; | 511 | BulletShape newShape; |
496 | 512 | ||
@@ -505,7 +521,7 @@ public class BSShapeCollection : IDisposable | |||
505 | prim.LocalID, prim.BSShape.shapeKey.ToString("X"), newHullKey.ToString("X")); | 521 | prim.LocalID, prim.BSShape.shapeKey.ToString("X"), newHullKey.ToString("X")); |
506 | 522 | ||
507 | // Remove usage of the previous shape. Also removes reference to underlying mesh if it is a hull. | 523 | // Remove usage of the previous shape. Also removes reference to underlying mesh if it is a hull. |
508 | DereferenceShape(prim.BSShape, true); | 524 | DereferenceShape(prim.BSShape, true, shapeCallback); |
509 | 525 | ||
510 | newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, pbs, shapeData.Size, lod); | 526 | newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, pbs, shapeData.Size, lod); |
511 | 527 | ||
@@ -656,7 +672,8 @@ public class BSShapeCollection : IDisposable | |||
656 | // Updates prim.BSBody with the information about the new body if one is created. | 672 | // Updates prim.BSBody with the information about the new body if one is created. |
657 | // Returns 'true' if an object was actually created. | 673 | // Returns 'true' if an object was actually created. |
658 | // Called at taint-time. | 674 | // Called at taint-time. |
659 | private bool CreateBody(bool forceRebuild, BSPrim prim, BulletSim sim, BulletShape shape, ShapeData shapeData) | 675 | private bool CreateBody(bool forceRebuild, BSPrim prim, BulletSim sim, BulletShape shape, |
676 | ShapeData shapeData, BodyDestructionCallback bodyCallback) | ||
660 | { | 677 | { |
661 | bool ret = false; | 678 | bool ret = false; |
662 | 679 | ||
@@ -679,7 +696,7 @@ public class BSShapeCollection : IDisposable | |||
679 | 696 | ||
680 | if (mustRebuild || forceRebuild) | 697 | if (mustRebuild || forceRebuild) |
681 | { | 698 | { |
682 | DereferenceBody(prim.BSBody, true); | 699 | DereferenceBody(prim.BSBody, true, bodyCallback); |
683 | 700 | ||
684 | BulletBody aBody; | 701 | BulletBody aBody; |
685 | IntPtr bodyPtr = IntPtr.Zero; | 702 | IntPtr bodyPtr = IntPtr.Zero; |