diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | 327 |
1 files changed, 311 insertions, 16 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs index dd5ae1a..e427dbc 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | |||
@@ -31,6 +31,7 @@ using System.Text; | |||
31 | 31 | ||
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
33 | using OpenSim.Region.Physics.Manager; | 33 | using OpenSim.Region.Physics.Manager; |
34 | using OpenSim.Region.Physics.ConvexDecompositionDotNet; | ||
34 | 35 | ||
35 | using OMV = OpenMetaverse; | 36 | using OMV = OpenMetaverse; |
36 | 37 | ||
@@ -73,7 +74,7 @@ public abstract class BSShape | |||
73 | if (ret == null && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND) | 74 | if (ret == null && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND) |
74 | { | 75 | { |
75 | // Getting a reference to a compound shape gets you the compound shape with the root prim shape added | 76 | // Getting a reference to a compound shape gets you the compound shape with the root prim shape added |
76 | ret = BSShapeCompound.GetReference(prim); | 77 | ret = BSShapeCompound.GetReference(physicsScene, prim); |
77 | physicsScene.DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, ret); | 78 | physicsScene.DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, ret); |
78 | } | 79 | } |
79 | 80 | ||
@@ -92,6 +93,7 @@ public abstract class BSShape | |||
92 | } | 93 | } |
93 | private static BSShape GetShapeReferenceNonSpecial(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) | 94 | private static BSShape GetShapeReferenceNonSpecial(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) |
94 | { | 95 | { |
96 | // TODO: work needed here!! | ||
95 | BSShapeMesh.GetReference(physicsScene, forceRebuild, prim); | 97 | BSShapeMesh.GetReference(physicsScene, forceRebuild, prim); |
96 | BSShapeHull.GetReference(physicsScene, forceRebuild, prim); | 98 | BSShapeHull.GetReference(physicsScene, forceRebuild, prim); |
97 | return null; | 99 | return null; |
@@ -209,7 +211,7 @@ public class BSShapeNative : BSShape | |||
209 | public class BSShapeMesh : BSShape | 211 | public class BSShapeMesh : BSShape |
210 | { | 212 | { |
211 | private static string LogHeader = "[BULLETSIM SHAPE MESH]"; | 213 | private static string LogHeader = "[BULLETSIM SHAPE MESH]"; |
212 | private static Dictionary<System.UInt64, BSShapeMesh> Meshes = new Dictionary<System.UInt64, BSShapeMesh>(); | 214 | public static Dictionary<System.UInt64, BSShapeMesh> Meshes = new Dictionary<System.UInt64, BSShapeMesh>(); |
213 | 215 | ||
214 | public BSShapeMesh(BulletShape pShape) : base(pShape) | 216 | public BSShapeMesh(BulletShape pShape) : base(pShape) |
215 | { | 217 | { |
@@ -219,10 +221,10 @@ public class BSShapeMesh : BSShape | |||
219 | float lod; | 221 | float lod; |
220 | System.UInt64 newMeshKey = BSShapeCollection.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); | 222 | System.UInt64 newMeshKey = BSShapeCollection.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); |
221 | 223 | ||
222 | physicsScene.DetailLog("{0},BSShapeMesh,create,oldKey={1},newKey={2},size={3},lod={4}", | 224 | physicsScene.DetailLog("{0},BSShapeMesh,getReference,oldKey={1},newKey={2},size={3},lod={4}", |
223 | prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X"), prim.Size, lod); | 225 | prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X"), prim.Size, lod); |
224 | 226 | ||
225 | BSShapeMesh retMesh; | 227 | BSShapeMesh retMesh = new BSShapeMesh(new BulletShape()); |
226 | lock (Meshes) | 228 | lock (Meshes) |
227 | { | 229 | { |
228 | if (Meshes.TryGetValue(newMeshKey, out retMesh)) | 230 | if (Meshes.TryGetValue(newMeshKey, out retMesh)) |
@@ -233,13 +235,17 @@ public class BSShapeMesh : BSShape | |||
233 | else | 235 | else |
234 | { | 236 | { |
235 | // An instance of this mesh has not been created. Build and remember same. | 237 | // An instance of this mesh has not been created. Build and remember same. |
236 | BulletShape newShape = CreatePhysicalMesh(physicsScene, prim, newMeshKey, prim.BaseShape, prim.Size, lod); | 238 | BulletShape newShape = retMesh.CreatePhysicalMesh(physicsScene, prim, newMeshKey, prim.BaseShape, prim.Size, lod); |
237 | // Take evasive action if the mesh was not constructed. | ||
238 | newShape = BSShapeCollection.VerifyMeshCreated(physicsScene, newShape, prim); | ||
239 | 239 | ||
240 | retMesh = new BSShapeMesh(newShape); | 240 | // Check to see if mesh was created (might require an asset). |
241 | newShape = BSShapeCollection.VerifyMeshCreated(physicsScene, newShape, prim); | ||
242 | if (newShape.type == BSPhysicsShapeType.SHAPE_MESH) | ||
243 | { | ||
244 | // If a mesh was what was created, remember the built shape for later sharing. | ||
245 | Meshes.Add(newMeshKey, retMesh); | ||
246 | } | ||
241 | 247 | ||
242 | Meshes.Add(newMeshKey, retMesh); | 248 | retMesh.physShapeInfo = newShape; |
243 | } | 249 | } |
244 | } | 250 | } |
245 | return retMesh; | 251 | return retMesh; |
@@ -252,8 +258,28 @@ public class BSShapeMesh : BSShape | |||
252 | // TODO: schedule aging and destruction of unused meshes. | 258 | // TODO: schedule aging and destruction of unused meshes. |
253 | } | 259 | } |
254 | } | 260 | } |
261 | // Loop through all the known meshes and return the description based on the physical address. | ||
262 | public static bool TryGetMeshByPtr(BulletShape pShape, out BSShapeMesh outMesh) | ||
263 | { | ||
264 | bool ret = false; | ||
265 | BSShapeMesh foundDesc = null; | ||
266 | lock (Meshes) | ||
267 | { | ||
268 | foreach (BSShapeMesh sm in Meshes.Values) | ||
269 | { | ||
270 | if (sm.physShapeInfo.ReferenceSame(pShape)) | ||
271 | { | ||
272 | foundDesc = sm; | ||
273 | ret = true; | ||
274 | break; | ||
275 | } | ||
255 | 276 | ||
256 | private static BulletShape CreatePhysicalMesh(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, | 277 | } |
278 | } | ||
279 | outMesh = foundDesc; | ||
280 | return ret; | ||
281 | } | ||
282 | private BulletShape CreatePhysicalMesh(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, | ||
257 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | 283 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) |
258 | { | 284 | { |
259 | BulletShape newShape = null; | 285 | BulletShape newShape = null; |
@@ -326,32 +352,301 @@ public class BSShapeMesh : BSShape | |||
326 | public class BSShapeHull : BSShape | 352 | public class BSShapeHull : BSShape |
327 | { | 353 | { |
328 | private static string LogHeader = "[BULLETSIM SHAPE HULL]"; | 354 | private static string LogHeader = "[BULLETSIM SHAPE HULL]"; |
329 | private static Dictionary<System.UInt64, BSShapeHull> Hulls = new Dictionary<System.UInt64, BSShapeHull>(); | 355 | public static Dictionary<System.UInt64, BSShapeHull> Hulls = new Dictionary<System.UInt64, BSShapeHull>(); |
330 | 356 | ||
331 | public BSShapeHull(BulletShape pShape) : base(pShape) | 357 | public BSShapeHull(BulletShape pShape) : base(pShape) |
332 | { | 358 | { |
333 | } | 359 | } |
334 | public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) | 360 | public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) |
335 | { | 361 | { |
336 | return new BSShapeNull(); | 362 | float lod; |
363 | System.UInt64 newHullKey = BSShapeCollection.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); | ||
364 | |||
365 | physicsScene.DetailLog("{0},BSShapeHull,getReference,oldKey={1},newKey={2},size={3},lod={4}", | ||
366 | prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newHullKey.ToString("X"), prim.Size, lod); | ||
367 | |||
368 | BSShapeHull retHull = new BSShapeHull(new BulletShape()); | ||
369 | lock (Hulls) | ||
370 | { | ||
371 | if (Hulls.TryGetValue(newHullKey, out retHull)) | ||
372 | { | ||
373 | // The mesh has already been created. Return a new reference to same. | ||
374 | retHull.IncrementReference(); | ||
375 | } | ||
376 | else | ||
377 | { | ||
378 | // An instance of this mesh has not been created. Build and remember same. | ||
379 | BulletShape newShape = retHull.CreatePhysicalHull(physicsScene, prim, newHullKey, prim.BaseShape, prim.Size, lod); | ||
380 | |||
381 | // Check to see if mesh was created (might require an asset). | ||
382 | newShape = BSShapeCollection.VerifyMeshCreated(physicsScene, newShape, prim); | ||
383 | if (newShape.type == BSPhysicsShapeType.SHAPE_MESH) | ||
384 | { | ||
385 | // If a mesh was what was created, remember the built shape for later sharing. | ||
386 | Hulls.Add(newHullKey, retHull); | ||
387 | } | ||
388 | |||
389 | retHull = new BSShapeHull(newShape); | ||
390 | retHull.physShapeInfo = newShape; | ||
391 | } | ||
392 | } | ||
393 | return retHull; | ||
337 | } | 394 | } |
338 | public override void Dereference(BSScene physicsScene) | 395 | public override void Dereference(BSScene physicsScene) |
339 | { | 396 | { |
340 | } | 397 | } |
398 | List<ConvexResult> m_hulls; | ||
399 | private BulletShape CreatePhysicalHull(BSScene physicsScene, BSPhysObject prim, System.UInt64 newHullKey, | ||
400 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | ||
401 | { | ||
402 | BulletShape newShape = new BulletShape(); | ||
403 | IntPtr hullPtr = IntPtr.Zero; | ||
404 | |||
405 | if (BSParam.ShouldUseBulletHACD) | ||
406 | { | ||
407 | physicsScene.DetailLog("{0},BSShapeCollection.CreatePhysicalHull,shouldUseBulletHACD,entry", prim.LocalID); | ||
408 | BSShape meshShape = BSShapeMesh.GetReference(physicsScene, true, prim); | ||
409 | |||
410 | if (meshShape.physShapeInfo.HasPhysicalShape) | ||
411 | { | ||
412 | HACDParams parms; | ||
413 | parms.maxVerticesPerHull = BSParam.BHullMaxVerticesPerHull; | ||
414 | parms.minClusters = BSParam.BHullMinClusters; | ||
415 | parms.compacityWeight = BSParam.BHullCompacityWeight; | ||
416 | parms.volumeWeight = BSParam.BHullVolumeWeight; | ||
417 | parms.concavity = BSParam.BHullConcavity; | ||
418 | parms.addExtraDistPoints = BSParam.NumericBool(BSParam.BHullAddExtraDistPoints); | ||
419 | parms.addNeighboursDistPoints = BSParam.NumericBool(BSParam.BHullAddNeighboursDistPoints); | ||
420 | parms.addFacesPoints = BSParam.NumericBool(BSParam.BHullAddFacesPoints); | ||
421 | parms.shouldAdjustCollisionMargin = BSParam.NumericBool(BSParam.BHullShouldAdjustCollisionMargin); | ||
422 | |||
423 | physicsScene.DetailLog("{0},BSShapeCollection.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape); | ||
424 | newShape = physicsScene.PE.BuildHullShapeFromMesh(physicsScene.World, meshShape.physShapeInfo, parms); | ||
425 | physicsScene.DetailLog("{0},BSShapeCollection.CreatePhysicalHull,hullFromMesh,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); | ||
426 | } | ||
427 | // Now done with the mesh shape. | ||
428 | meshShape.DecrementReference(); | ||
429 | physicsScene.DetailLog("{0},BSShapeCollection.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); | ||
430 | } | ||
431 | if (!newShape.HasPhysicalShape) | ||
432 | { | ||
433 | // Build a new hull in the physical world. | ||
434 | // Pass true for physicalness as this prevents the creation of bounding box which is not needed | ||
435 | IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */); | ||
436 | if (meshData != null) | ||
437 | { | ||
438 | int[] indices = meshData.getIndexListAsInt(); | ||
439 | List<OMV.Vector3> vertices = meshData.getVertexList(); | ||
440 | |||
441 | //format conversion from IMesh format to DecompDesc format | ||
442 | List<int> convIndices = new List<int>(); | ||
443 | List<float3> convVertices = new List<float3>(); | ||
444 | for (int ii = 0; ii < indices.GetLength(0); ii++) | ||
445 | { | ||
446 | convIndices.Add(indices[ii]); | ||
447 | } | ||
448 | foreach (OMV.Vector3 vv in vertices) | ||
449 | { | ||
450 | convVertices.Add(new float3(vv.X, vv.Y, vv.Z)); | ||
451 | } | ||
452 | |||
453 | uint maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplit; | ||
454 | if (BSParam.CSHullMaxDepthSplit != BSParam.CSHullMaxDepthSplitForSimpleShapes) | ||
455 | { | ||
456 | // Simple primitive shapes we know are convex so they are better implemented with | ||
457 | // fewer hulls. | ||
458 | // Check for simple shape (prim without cuts) and reduce split parameter if so. | ||
459 | if (BSShapeCollection.PrimHasNoCuts(pbs)) | ||
460 | { | ||
461 | maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplitForSimpleShapes; | ||
462 | } | ||
463 | } | ||
464 | |||
465 | // setup and do convex hull conversion | ||
466 | m_hulls = new List<ConvexResult>(); | ||
467 | DecompDesc dcomp = new DecompDesc(); | ||
468 | dcomp.mIndices = convIndices; | ||
469 | dcomp.mVertices = convVertices; | ||
470 | dcomp.mDepth = maxDepthSplit; | ||
471 | dcomp.mCpercent = BSParam.CSHullConcavityThresholdPercent; | ||
472 | dcomp.mPpercent = BSParam.CSHullVolumeConservationThresholdPercent; | ||
473 | dcomp.mMaxVertices = (uint)BSParam.CSHullMaxVertices; | ||
474 | dcomp.mSkinWidth = BSParam.CSHullMaxSkinWidth; | ||
475 | ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn); | ||
476 | // create the hull into the _hulls variable | ||
477 | convexBuilder.process(dcomp); | ||
478 | |||
479 | physicsScene.DetailLog("{0},BSShapeCollection.CreatePhysicalHull,key={1},inVert={2},inInd={3},split={4},hulls={5}", | ||
480 | BSScene.DetailLogZero, newHullKey, indices.GetLength(0), vertices.Count, maxDepthSplit, m_hulls.Count); | ||
481 | |||
482 | // Convert the vertices and indices for passing to unmanaged. | ||
483 | // The hull information is passed as a large floating point array. | ||
484 | // The format is: | ||
485 | // convHulls[0] = number of hulls | ||
486 | // convHulls[1] = number of vertices in first hull | ||
487 | // convHulls[2] = hull centroid X coordinate | ||
488 | // convHulls[3] = hull centroid Y coordinate | ||
489 | // convHulls[4] = hull centroid Z coordinate | ||
490 | // convHulls[5] = first hull vertex X | ||
491 | // convHulls[6] = first hull vertex Y | ||
492 | // convHulls[7] = first hull vertex Z | ||
493 | // convHulls[8] = second hull vertex X | ||
494 | // ... | ||
495 | // convHulls[n] = number of vertices in second hull | ||
496 | // convHulls[n+1] = second hull centroid X coordinate | ||
497 | // ... | ||
498 | // | ||
499 | // TODO: is is very inefficient. Someday change the convex hull generator to return | ||
500 | // data structures that do not need to be converted in order to pass to Bullet. | ||
501 | // And maybe put the values directly into pinned memory rather than marshaling. | ||
502 | int hullCount = m_hulls.Count; | ||
503 | int totalVertices = 1; // include one for the count of the hulls | ||
504 | foreach (ConvexResult cr in m_hulls) | ||
505 | { | ||
506 | totalVertices += 4; // add four for the vertex count and centroid | ||
507 | totalVertices += cr.HullIndices.Count * 3; // we pass just triangles | ||
508 | } | ||
509 | float[] convHulls = new float[totalVertices]; | ||
510 | |||
511 | convHulls[0] = (float)hullCount; | ||
512 | int jj = 1; | ||
513 | foreach (ConvexResult cr in m_hulls) | ||
514 | { | ||
515 | // copy vertices for index access | ||
516 | float3[] verts = new float3[cr.HullVertices.Count]; | ||
517 | int kk = 0; | ||
518 | foreach (float3 ff in cr.HullVertices) | ||
519 | { | ||
520 | verts[kk++] = ff; | ||
521 | } | ||
522 | |||
523 | // add to the array one hull's worth of data | ||
524 | convHulls[jj++] = cr.HullIndices.Count; | ||
525 | convHulls[jj++] = 0f; // centroid x,y,z | ||
526 | convHulls[jj++] = 0f; | ||
527 | convHulls[jj++] = 0f; | ||
528 | foreach (int ind in cr.HullIndices) | ||
529 | { | ||
530 | convHulls[jj++] = verts[ind].x; | ||
531 | convHulls[jj++] = verts[ind].y; | ||
532 | convHulls[jj++] = verts[ind].z; | ||
533 | } | ||
534 | } | ||
535 | // create the hull data structure in Bullet | ||
536 | newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls); | ||
537 | } | ||
538 | newShape.shapeKey = newHullKey; | ||
539 | } | ||
540 | return newShape; | ||
541 | } | ||
542 | // Callback from convex hull creater with a newly created hull. | ||
543 | // Just add it to our collection of hulls for this shape. | ||
544 | private void HullReturn(ConvexResult result) | ||
545 | { | ||
546 | m_hulls.Add(result); | ||
547 | return; | ||
548 | } | ||
549 | // Loop through all the known hulls and return the description based on the physical address. | ||
550 | public static bool TryGetHullByPtr(BulletShape pShape, out BSShapeHull outHull) | ||
551 | { | ||
552 | bool ret = false; | ||
553 | BSShapeHull foundDesc = null; | ||
554 | lock (Hulls) | ||
555 | { | ||
556 | foreach (BSShapeHull sh in Hulls.Values) | ||
557 | { | ||
558 | if (sh.physShapeInfo.ReferenceSame(pShape)) | ||
559 | { | ||
560 | foundDesc = sh; | ||
561 | ret = true; | ||
562 | break; | ||
563 | } | ||
564 | |||
565 | } | ||
566 | } | ||
567 | outHull = foundDesc; | ||
568 | return ret; | ||
569 | } | ||
341 | } | 570 | } |
342 | 571 | ||
572 | |||
343 | // ============================================================================================================ | 573 | // ============================================================================================================ |
344 | public class BSShapeCompound : BSShape | 574 | public class BSShapeCompound : BSShape |
345 | { | 575 | { |
346 | private static string LogHeader = "[BULLETSIM SHAPE COMPOUND]"; | 576 | private static string LogHeader = "[BULLETSIM SHAPE COMPOUND]"; |
347 | public BSShapeCompound() : base() | 577 | public BSShapeCompound(BulletShape pShape) : base(pShape) |
348 | { | 578 | { |
349 | } | 579 | } |
350 | public static BSShape GetReference(BSPhysObject prim) | 580 | public static BSShape GetReference(BSScene physicsScene, BSPhysObject prim) |
351 | { | 581 | { |
352 | return new BSShapeNull(); | 582 | // Compound shapes are not shared so a new one is created every time. |
583 | return new BSShapeCompound(CreatePhysicalCompoundShape(physicsScene, prim)); | ||
584 | } | ||
585 | // Dereferencing a compound shape releases the hold on all the child shapes. | ||
586 | public override void Dereference(BSScene physicsScene) | ||
587 | { | ||
588 | if (!physicsScene.PE.IsCompound(physShapeInfo)) | ||
589 | { | ||
590 | // Failed the sanity check!! | ||
591 | physicsScene.Logger.ErrorFormat("{0} Attempt to free a compound shape that is not compound!! type={1}, ptr={2}", | ||
592 | LogHeader, physShapeInfo.type, physShapeInfo.AddrString); | ||
593 | physicsScene.DetailLog("{0},BSShapeCollection.DereferenceCompound,notACompoundShape,type={1},ptr={2}", | ||
594 | BSScene.DetailLogZero, physShapeInfo.type, physShapeInfo.AddrString); | ||
595 | return; | ||
596 | } | ||
597 | |||
598 | int numChildren = physicsScene.PE.GetNumberOfCompoundChildren(physShapeInfo); | ||
599 | physicsScene.DetailLog("{0},BSShapeCollection.DereferenceCompound,shape={1},children={2}", | ||
600 | BSScene.DetailLogZero, physShapeInfo, numChildren); | ||
601 | |||
602 | // Loop through all the children dereferencing each. | ||
603 | for (int ii = numChildren - 1; ii >= 0; ii--) | ||
604 | { | ||
605 | BulletShape childShape = physicsScene.PE.RemoveChildShapeFromCompoundShapeIndex(physShapeInfo, ii); | ||
606 | DereferenceAnonCollisionShape(physicsScene, childShape); | ||
607 | } | ||
608 | physicsScene.PE.DeleteCollisionShape(physicsScene.World, physShapeInfo); | ||
609 | } | ||
610 | private static BulletShape CreatePhysicalCompoundShape(BSScene physicsScene, BSPhysObject prim) | ||
611 | { | ||
612 | BulletShape cShape = physicsScene.PE.CreateCompoundShape(physicsScene.World, false); | ||
613 | return cShape; | ||
614 | } | ||
615 | // Sometimes we have a pointer to a collision shape but don't know what type it is. | ||
616 | // Figure out type and call the correct dereference routine. | ||
617 | // Called at taint-time. | ||
618 | private void DereferenceAnonCollisionShape(BSScene physicsScene, BulletShape pShape) | ||
619 | { | ||
620 | BSShapeMesh meshDesc; | ||
621 | if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc)) | ||
622 | { | ||
623 | meshDesc.Dereference(physicsScene); | ||
624 | } | ||
625 | else | ||
626 | { | ||
627 | BSShapeHull hullDesc; | ||
628 | if (BSShapeHull.TryGetHullByPtr(pShape, out hullDesc)) | ||
629 | { | ||
630 | hullDesc.Dereference(physicsScene); | ||
631 | } | ||
632 | else | ||
633 | { | ||
634 | if (physicsScene.PE.IsCompound(pShape)) | ||
635 | { | ||
636 | BSShapeCompound recursiveCompound = new BSShapeCompound(pShape); | ||
637 | recursiveCompound.Dereference(physicsScene); | ||
638 | } | ||
639 | else | ||
640 | { | ||
641 | if (physicsScene.PE.IsNativeShape(pShape)) | ||
642 | { | ||
643 | BSShapeNative nativeShape = new BSShapeNative(pShape); | ||
644 | nativeShape.Dereference(physicsScene); | ||
645 | } | ||
646 | } | ||
647 | } | ||
648 | } | ||
353 | } | 649 | } |
354 | public override void Dereference(BSScene physicsScene) { } | ||
355 | } | 650 | } |
356 | 651 | ||
357 | // ============================================================================================================ | 652 | // ============================================================================================================ |