diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | 415 |
1 files changed, 296 insertions, 119 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs index 72d039b..81edc12 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.Meshing; | ||
34 | using OpenSim.Region.Physics.ConvexDecompositionDotNet; | 35 | using OpenSim.Region.Physics.ConvexDecompositionDotNet; |
35 | 36 | ||
36 | using OMV = OpenMetaverse; | 37 | using OMV = OpenMetaverse; |
@@ -422,15 +423,32 @@ public class BSShapeMesh : BSShape | |||
422 | outMesh = foundDesc; | 423 | outMesh = foundDesc; |
423 | return ret; | 424 | return ret; |
424 | } | 425 | } |
426 | |||
427 | public delegate BulletShape CreateShapeCall(BulletWorld world, int indicesCount, int[] indices, int verticesCount, float[] vertices ); | ||
425 | private BulletShape CreatePhysicalMesh(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, | 428 | private BulletShape CreatePhysicalMesh(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, |
426 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | 429 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) |
427 | { | 430 | { |
431 | return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod, | ||
432 | (w, iC, i, vC, v) => physicsScene.PE.CreateMeshShape(w, iC, i, vC, v) ); | ||
433 | } | ||
434 | |||
435 | // Code that uses the mesher to create the index/vertices info for a trimesh shape. | ||
436 | // This is used by the passed 'makeShape' call to create the Bullet mesh shape. | ||
437 | // The actual build call is passed so this logic can be used by several of the shapes that use a | ||
438 | // simple mesh as their base shape. | ||
439 | public static BulletShape CreatePhysicalMeshShape(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, | ||
440 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod, CreateShapeCall makeShape) | ||
441 | { | ||
428 | BulletShape newShape = new BulletShape(); | 442 | BulletShape newShape = new BulletShape(); |
429 | 443 | ||
430 | IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, | 444 | IMesh meshData = null; |
431 | false, // say it is not physical so a bounding box is not built | 445 | lock (physicsScene.mesher) |
432 | false // do not cache the mesh and do not use previously built versions | 446 | { |
433 | ); | 447 | meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, |
448 | false, // say it is not physical so a bounding box is not built | ||
449 | false // do not cache the mesh and do not use previously built versions | ||
450 | ); | ||
451 | } | ||
434 | 452 | ||
435 | if (meshData != null) | 453 | if (meshData != null) |
436 | { | 454 | { |
@@ -482,8 +500,7 @@ public class BSShapeMesh : BSShape | |||
482 | 500 | ||
483 | if (realIndicesIndex != 0) | 501 | if (realIndicesIndex != 0) |
484 | { | 502 | { |
485 | newShape = physicsScene.PE.CreateMeshShape(physicsScene.World, | 503 | newShape = makeShape(physicsScene.World, realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats); |
486 | realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats); | ||
487 | } | 504 | } |
488 | else | 505 | else |
489 | { | 506 | { |
@@ -561,13 +578,74 @@ public class BSShapeHull : BSShape | |||
561 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | 578 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) |
562 | { | 579 | { |
563 | BulletShape newShape = new BulletShape(); | 580 | BulletShape newShape = new BulletShape(); |
564 | IntPtr hullPtr = IntPtr.Zero; | ||
565 | 581 | ||
566 | if (BSParam.ShouldUseBulletHACD) | 582 | IMesh meshData = null; |
583 | List<List<OMV.Vector3>> allHulls = null; | ||
584 | lock (physicsScene.mesher) | ||
585 | { | ||
586 | // Pass true for physicalness as this prevents the creation of bounding box which is not needed | ||
587 | meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */); | ||
588 | |||
589 | // If we should use the asset's hull info, fetch it out of the locked mesher | ||
590 | if (meshData != null && BSParam.ShouldUseAssetHulls) | ||
591 | { | ||
592 | Meshmerizer realMesher = physicsScene.mesher as Meshmerizer; | ||
593 | if (realMesher != null) | ||
594 | { | ||
595 | allHulls = realMesher.GetConvexHulls(size); | ||
596 | } | ||
597 | if (allHulls == null) | ||
598 | { | ||
599 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,assetHulls,noAssetHull", prim.LocalID); | ||
600 | } | ||
601 | } | ||
602 | } | ||
603 | |||
604 | // If there is hull data in the mesh asset, build the hull from that | ||
605 | if (allHulls != null && BSParam.ShouldUseAssetHulls) | ||
606 | { | ||
607 | int hullCount = allHulls.Count; | ||
608 | int totalVertices = 1; // include one for the count of the hulls | ||
609 | // Using the structure described for HACD hulls, create the memory sturcture | ||
610 | // to pass the hull data to the creater. | ||
611 | foreach (List<OMV.Vector3> hullVerts in allHulls) | ||
612 | { | ||
613 | totalVertices += 4; // add four for the vertex count and centroid | ||
614 | totalVertices += hullVerts.Count * 3; // one vertex is three dimensions | ||
615 | } | ||
616 | float[] convHulls = new float[totalVertices]; | ||
617 | |||
618 | convHulls[0] = (float)hullCount; | ||
619 | int jj = 1; | ||
620 | foreach (List<OMV.Vector3> hullVerts in allHulls) | ||
621 | { | ||
622 | convHulls[jj + 0] = hullVerts.Count; | ||
623 | convHulls[jj + 1] = 0f; // centroid x,y,z | ||
624 | convHulls[jj + 2] = 0f; | ||
625 | convHulls[jj + 3] = 0f; | ||
626 | jj += 4; | ||
627 | foreach (OMV.Vector3 oneVert in hullVerts) | ||
628 | { | ||
629 | convHulls[jj + 0] = oneVert.X; | ||
630 | convHulls[jj + 1] = oneVert.Y; | ||
631 | convHulls[jj + 2] = oneVert.Z; | ||
632 | jj += 3; | ||
633 | } | ||
634 | } | ||
635 | |||
636 | // create the hull data structure in Bullet | ||
637 | newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls); | ||
638 | |||
639 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,assetHulls,hulls={1},totVert={2},shape={3}", | ||
640 | prim.LocalID, hullCount, totalVertices, newShape); | ||
641 | } | ||
642 | |||
643 | // If no hull specified in the asset and we should use Bullet's HACD approximation... | ||
644 | if (!newShape.HasPhysicalShape && BSParam.ShouldUseBulletHACD) | ||
567 | { | 645 | { |
568 | // Build the hull shape from an existing mesh shape. | 646 | // Build the hull shape from an existing mesh shape. |
569 | // The mesh should have already been created in Bullet. | 647 | // The mesh should have already been created in Bullet. |
570 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,entry", prim.LocalID); | 648 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,bulletHACD,entry", prim.LocalID); |
571 | BSShape meshShape = BSShapeMesh.GetReference(physicsScene, true, prim); | 649 | BSShape meshShape = BSShapeMesh.GetReference(physicsScene, true, prim); |
572 | 650 | ||
573 | if (meshShape.physShapeInfo.HasPhysicalShape) | 651 | if (meshShape.physShapeInfo.HasPhysicalShape) |
@@ -585,129 +663,125 @@ public class BSShapeHull : BSShape | |||
585 | 663 | ||
586 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape); | 664 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape); |
587 | newShape = physicsScene.PE.BuildHullShapeFromMesh(physicsScene.World, meshShape.physShapeInfo, parms); | 665 | newShape = physicsScene.PE.BuildHullShapeFromMesh(physicsScene.World, meshShape.physShapeInfo, parms); |
588 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); | 666 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,shape={1}", prim.LocalID, newShape); |
589 | 667 | ||
590 | // Now done with the mesh shape. | 668 | // Now done with the mesh shape. |
591 | meshShape.Dereference(physicsScene); | 669 | meshShape.Dereference(physicsScene); |
592 | } | 670 | } |
593 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); | 671 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,bulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); |
594 | } | 672 | } |
595 | if (!newShape.HasPhysicalShape) | 673 | |
674 | // If no other hull specifications, use our HACD hull approximation. | ||
675 | if (!newShape.HasPhysicalShape && meshData != null) | ||
596 | { | 676 | { |
597 | // Build a new hull in the physical world using the C# HACD algorigthm. | 677 | if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched) |
598 | // Pass true for physicalness as this prevents the creation of bounding box which is not needed | ||
599 | IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */); | ||
600 | if (meshData != null) | ||
601 | { | 678 | { |
602 | if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched) | 679 | // Release the fetched asset data once it has been used. |
603 | { | 680 | pbs.SculptData = new byte[0]; |
604 | // Release the fetched asset data once it has been used. | 681 | prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Unknown; |
605 | pbs.SculptData = new byte[0]; | 682 | } |
606 | prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Unknown; | ||
607 | } | ||
608 | 683 | ||
609 | int[] indices = meshData.getIndexListAsInt(); | 684 | int[] indices = meshData.getIndexListAsInt(); |
610 | List<OMV.Vector3> vertices = meshData.getVertexList(); | 685 | List<OMV.Vector3> vertices = meshData.getVertexList(); |
611 | 686 | ||
612 | //format conversion from IMesh format to DecompDesc format | 687 | //format conversion from IMesh format to DecompDesc format |
613 | List<int> convIndices = new List<int>(); | 688 | List<int> convIndices = new List<int>(); |
614 | List<float3> convVertices = new List<float3>(); | 689 | List<float3> convVertices = new List<float3>(); |
615 | for (int ii = 0; ii < indices.GetLength(0); ii++) | 690 | for (int ii = 0; ii < indices.GetLength(0); ii++) |
616 | { | 691 | { |
617 | convIndices.Add(indices[ii]); | 692 | convIndices.Add(indices[ii]); |
618 | } | 693 | } |
619 | foreach (OMV.Vector3 vv in vertices) | 694 | foreach (OMV.Vector3 vv in vertices) |
620 | { | 695 | { |
621 | convVertices.Add(new float3(vv.X, vv.Y, vv.Z)); | 696 | convVertices.Add(new float3(vv.X, vv.Y, vv.Z)); |
622 | } | 697 | } |
623 | 698 | ||
624 | uint maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplit; | 699 | uint maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplit; |
625 | if (BSParam.CSHullMaxDepthSplit != BSParam.CSHullMaxDepthSplitForSimpleShapes) | 700 | if (BSParam.CSHullMaxDepthSplit != BSParam.CSHullMaxDepthSplitForSimpleShapes) |
701 | { | ||
702 | // Simple primitive shapes we know are convex so they are better implemented with | ||
703 | // fewer hulls. | ||
704 | // Check for simple shape (prim without cuts) and reduce split parameter if so. | ||
705 | if (BSShapeCollection.PrimHasNoCuts(pbs)) | ||
626 | { | 706 | { |
627 | // Simple primitive shapes we know are convex so they are better implemented with | 707 | maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplitForSimpleShapes; |
628 | // fewer hulls. | ||
629 | // Check for simple shape (prim without cuts) and reduce split parameter if so. | ||
630 | if (BSShapeCollection.PrimHasNoCuts(pbs)) | ||
631 | { | ||
632 | maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplitForSimpleShapes; | ||
633 | } | ||
634 | } | 708 | } |
709 | } | ||
710 | |||
711 | // setup and do convex hull conversion | ||
712 | m_hulls = new List<ConvexResult>(); | ||
713 | DecompDesc dcomp = new DecompDesc(); | ||
714 | dcomp.mIndices = convIndices; | ||
715 | dcomp.mVertices = convVertices; | ||
716 | dcomp.mDepth = maxDepthSplit; | ||
717 | dcomp.mCpercent = BSParam.CSHullConcavityThresholdPercent; | ||
718 | dcomp.mPpercent = BSParam.CSHullVolumeConservationThresholdPercent; | ||
719 | dcomp.mMaxVertices = (uint)BSParam.CSHullMaxVertices; | ||
720 | dcomp.mSkinWidth = BSParam.CSHullMaxSkinWidth; | ||
721 | ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn); | ||
722 | // create the hull into the _hulls variable | ||
723 | convexBuilder.process(dcomp); | ||
724 | |||
725 | physicsScene.DetailLog("{0},BSShapeCollection.CreatePhysicalHull,key={1},inVert={2},inInd={3},split={4},hulls={5}", | ||
726 | BSScene.DetailLogZero, newHullKey, indices.GetLength(0), vertices.Count, maxDepthSplit, m_hulls.Count); | ||
727 | |||
728 | // Convert the vertices and indices for passing to unmanaged. | ||
729 | // The hull information is passed as a large floating point array. | ||
730 | // The format is: | ||
731 | // convHulls[0] = number of hulls | ||
732 | // convHulls[1] = number of vertices in first hull | ||
733 | // convHulls[2] = hull centroid X coordinate | ||
734 | // convHulls[3] = hull centroid Y coordinate | ||
735 | // convHulls[4] = hull centroid Z coordinate | ||
736 | // convHulls[5] = first hull vertex X | ||
737 | // convHulls[6] = first hull vertex Y | ||
738 | // convHulls[7] = first hull vertex Z | ||
739 | // convHulls[8] = second hull vertex X | ||
740 | // ... | ||
741 | // convHulls[n] = number of vertices in second hull | ||
742 | // convHulls[n+1] = second hull centroid X coordinate | ||
743 | // ... | ||
744 | // | ||
745 | // TODO: is is very inefficient. Someday change the convex hull generator to return | ||
746 | // data structures that do not need to be converted in order to pass to Bullet. | ||
747 | // And maybe put the values directly into pinned memory rather than marshaling. | ||
748 | int hullCount = m_hulls.Count; | ||
749 | int totalVertices = 1; // include one for the count of the hulls | ||
750 | foreach (ConvexResult cr in m_hulls) | ||
751 | { | ||
752 | totalVertices += 4; // add four for the vertex count and centroid | ||
753 | totalVertices += cr.HullIndices.Count * 3; // we pass just triangles | ||
754 | } | ||
755 | float[] convHulls = new float[totalVertices]; | ||
635 | 756 | ||
636 | // setup and do convex hull conversion | 757 | convHulls[0] = (float)hullCount; |
637 | m_hulls = new List<ConvexResult>(); | 758 | int jj = 1; |
638 | DecompDesc dcomp = new DecompDesc(); | 759 | foreach (ConvexResult cr in m_hulls) |
639 | dcomp.mIndices = convIndices; | 760 | { |
640 | dcomp.mVertices = convVertices; | 761 | // copy vertices for index access |
641 | dcomp.mDepth = maxDepthSplit; | 762 | float3[] verts = new float3[cr.HullVertices.Count]; |
642 | dcomp.mCpercent = BSParam.CSHullConcavityThresholdPercent; | 763 | int kk = 0; |
643 | dcomp.mPpercent = BSParam.CSHullVolumeConservationThresholdPercent; | 764 | foreach (float3 ff in cr.HullVertices) |
644 | dcomp.mMaxVertices = (uint)BSParam.CSHullMaxVertices; | ||
645 | dcomp.mSkinWidth = BSParam.CSHullMaxSkinWidth; | ||
646 | ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn); | ||
647 | // create the hull into the _hulls variable | ||
648 | convexBuilder.process(dcomp); | ||
649 | |||
650 | physicsScene.DetailLog("{0},BSShapeCollection.CreatePhysicalHull,key={1},inVert={2},inInd={3},split={4},hulls={5}", | ||
651 | BSScene.DetailLogZero, newHullKey, indices.GetLength(0), vertices.Count, maxDepthSplit, m_hulls.Count); | ||
652 | |||
653 | // Convert the vertices and indices for passing to unmanaged. | ||
654 | // The hull information is passed as a large floating point array. | ||
655 | // The format is: | ||
656 | // convHulls[0] = number of hulls | ||
657 | // convHulls[1] = number of vertices in first hull | ||
658 | // convHulls[2] = hull centroid X coordinate | ||
659 | // convHulls[3] = hull centroid Y coordinate | ||
660 | // convHulls[4] = hull centroid Z coordinate | ||
661 | // convHulls[5] = first hull vertex X | ||
662 | // convHulls[6] = first hull vertex Y | ||
663 | // convHulls[7] = first hull vertex Z | ||
664 | // convHulls[8] = second hull vertex X | ||
665 | // ... | ||
666 | // convHulls[n] = number of vertices in second hull | ||
667 | // convHulls[n+1] = second hull centroid X coordinate | ||
668 | // ... | ||
669 | // | ||
670 | // TODO: is is very inefficient. Someday change the convex hull generator to return | ||
671 | // data structures that do not need to be converted in order to pass to Bullet. | ||
672 | // And maybe put the values directly into pinned memory rather than marshaling. | ||
673 | int hullCount = m_hulls.Count; | ||
674 | int totalVertices = 1; // include one for the count of the hulls | ||
675 | foreach (ConvexResult cr in m_hulls) | ||
676 | { | 765 | { |
677 | totalVertices += 4; // add four for the vertex count and centroid | 766 | verts[kk++] = ff; |
678 | totalVertices += cr.HullIndices.Count * 3; // we pass just triangles | ||
679 | } | 767 | } |
680 | float[] convHulls = new float[totalVertices]; | ||
681 | 768 | ||
682 | convHulls[0] = (float)hullCount; | 769 | // add to the array one hull's worth of data |
683 | int jj = 1; | 770 | convHulls[jj++] = cr.HullIndices.Count; |
684 | foreach (ConvexResult cr in m_hulls) | 771 | convHulls[jj++] = 0f; // centroid x,y,z |
772 | convHulls[jj++] = 0f; | ||
773 | convHulls[jj++] = 0f; | ||
774 | foreach (int ind in cr.HullIndices) | ||
685 | { | 775 | { |
686 | // copy vertices for index access | 776 | convHulls[jj++] = verts[ind].x; |
687 | float3[] verts = new float3[cr.HullVertices.Count]; | 777 | convHulls[jj++] = verts[ind].y; |
688 | int kk = 0; | 778 | convHulls[jj++] = verts[ind].z; |
689 | foreach (float3 ff in cr.HullVertices) | ||
690 | { | ||
691 | verts[kk++] = ff; | ||
692 | } | ||
693 | |||
694 | // add to the array one hull's worth of data | ||
695 | convHulls[jj++] = cr.HullIndices.Count; | ||
696 | convHulls[jj++] = 0f; // centroid x,y,z | ||
697 | convHulls[jj++] = 0f; | ||
698 | convHulls[jj++] = 0f; | ||
699 | foreach (int ind in cr.HullIndices) | ||
700 | { | ||
701 | convHulls[jj++] = verts[ind].x; | ||
702 | convHulls[jj++] = verts[ind].y; | ||
703 | convHulls[jj++] = verts[ind].z; | ||
704 | } | ||
705 | } | 779 | } |
706 | // create the hull data structure in Bullet | ||
707 | newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls); | ||
708 | } | 780 | } |
709 | newShape.shapeKey = newHullKey; | 781 | // create the hull data structure in Bullet |
782 | newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls); | ||
710 | } | 783 | } |
784 | newShape.shapeKey = newHullKey; | ||
711 | return newShape; | 785 | return newShape; |
712 | } | 786 | } |
713 | // Callback from convex hull creater with a newly created hull. | 787 | // Callback from convex hull creater with a newly created hull. |
@@ -803,6 +877,7 @@ public class BSShapeCompound : BSShape | |||
803 | // Called at taint-time. | 877 | // Called at taint-time. |
804 | private void DereferenceAnonCollisionShape(BSScene physicsScene, BulletShape pShape) | 878 | private void DereferenceAnonCollisionShape(BSScene physicsScene, BulletShape pShape) |
805 | { | 879 | { |
880 | // TODO: figure a better way to go through all the shape types and find a possible instance. | ||
806 | BSShapeMesh meshDesc; | 881 | BSShapeMesh meshDesc; |
807 | if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc)) | 882 | if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc)) |
808 | { | 883 | { |
@@ -824,17 +899,27 @@ public class BSShapeCompound : BSShape | |||
824 | } | 899 | } |
825 | else | 900 | else |
826 | { | 901 | { |
827 | if (physicsScene.PE.IsCompound(pShape)) | 902 | BSShapeGImpact gImpactDesc; |
903 | if (BSShapeGImpact.TryGetGImpactByPtr(pShape, out gImpactDesc)) | ||
828 | { | 904 | { |
829 | BSShapeCompound recursiveCompound = new BSShapeCompound(pShape); | 905 | gImpactDesc.Dereference(physicsScene); |
830 | recursiveCompound.Dereference(physicsScene); | ||
831 | } | 906 | } |
832 | else | 907 | else |
833 | { | 908 | { |
834 | if (physicsScene.PE.IsNativeShape(pShape)) | 909 | // Didn't find it in the lists of specific types. It could be compound. |
910 | if (physicsScene.PE.IsCompound(pShape)) | ||
911 | { | ||
912 | BSShapeCompound recursiveCompound = new BSShapeCompound(pShape); | ||
913 | recursiveCompound.Dereference(physicsScene); | ||
914 | } | ||
915 | else | ||
835 | { | 916 | { |
836 | BSShapeNative nativeShape = new BSShapeNative(pShape); | 917 | // If none of the above, maybe it is a simple native shape. |
837 | nativeShape.Dereference(physicsScene); | 918 | if (physicsScene.PE.IsNativeShape(pShape)) |
919 | { | ||
920 | BSShapeNative nativeShape = new BSShapeNative(pShape); | ||
921 | nativeShape.Dereference(physicsScene); | ||
922 | } | ||
838 | } | 923 | } |
839 | } | 924 | } |
840 | } | 925 | } |
@@ -857,7 +942,7 @@ public class BSShapeConvexHull : BSShape | |||
857 | float lod; | 942 | float lod; |
858 | System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); | 943 | System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); |
859 | 944 | ||
860 | physicsScene.DetailLog("{0},BSShapeMesh,getReference,newKey={1},size={2},lod={3}", | 945 | physicsScene.DetailLog("{0},BSShapeConvexHull,getReference,newKey={1},size={2},lod={3}", |
861 | prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod); | 946 | prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod); |
862 | 947 | ||
863 | BSShapeConvexHull retConvexHull = null; | 948 | BSShapeConvexHull retConvexHull = null; |
@@ -937,6 +1022,98 @@ public class BSShapeConvexHull : BSShape | |||
937 | return ret; | 1022 | return ret; |
938 | } | 1023 | } |
939 | } | 1024 | } |
1025 | // ============================================================================================================ | ||
1026 | public class BSShapeGImpact : BSShape | ||
1027 | { | ||
1028 | private static string LogHeader = "[BULLETSIM SHAPE GIMPACT]"; | ||
1029 | public static Dictionary<System.UInt64, BSShapeGImpact> GImpacts = new Dictionary<System.UInt64, BSShapeGImpact>(); | ||
1030 | |||
1031 | public BSShapeGImpact(BulletShape pShape) : base(pShape) | ||
1032 | { | ||
1033 | } | ||
1034 | public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) | ||
1035 | { | ||
1036 | float lod; | ||
1037 | System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); | ||
1038 | |||
1039 | physicsScene.DetailLog("{0},BSShapeGImpact,getReference,newKey={1},size={2},lod={3}", | ||
1040 | prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod); | ||
1041 | |||
1042 | BSShapeGImpact retGImpact = null; | ||
1043 | lock (GImpacts) | ||
1044 | { | ||
1045 | if (GImpacts.TryGetValue(newMeshKey, out retGImpact)) | ||
1046 | { | ||
1047 | // The mesh has already been created. Return a new reference to same. | ||
1048 | retGImpact.IncrementReference(); | ||
1049 | } | ||
1050 | else | ||
1051 | { | ||
1052 | retGImpact = new BSShapeGImpact(new BulletShape()); | ||
1053 | BulletShape newShape = retGImpact.CreatePhysicalGImpact(physicsScene, prim, newMeshKey, prim.BaseShape, prim.Size, lod); | ||
1054 | |||
1055 | // Check to see if mesh was created (might require an asset). | ||
1056 | newShape = VerifyMeshCreated(physicsScene, newShape, prim); | ||
1057 | newShape.shapeKey = newMeshKey; | ||
1058 | if (!newShape.isNativeShape || prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Failed) | ||
1059 | { | ||
1060 | // If a mesh was what was created, remember the built shape for later sharing. | ||
1061 | // Also note that if meshing failed we put it in the mesh list as there is nothing else to do about the mesh. | ||
1062 | GImpacts.Add(newMeshKey, retGImpact); | ||
1063 | } | ||
1064 | |||
1065 | retGImpact.physShapeInfo = newShape; | ||
1066 | } | ||
1067 | } | ||
1068 | return retGImpact; | ||
1069 | } | ||
1070 | |||
1071 | private BulletShape CreatePhysicalGImpact(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, | ||
1072 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | ||
1073 | { | ||
1074 | return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod, | ||
1075 | (w, iC, i, vC, v) => physicsScene.PE.CreateGImpactShape(w, iC, i, vC, v) ); | ||
1076 | } | ||
1077 | |||
1078 | public override BSShape GetReference(BSScene physicsScene, BSPhysObject prim) | ||
1079 | { | ||
1080 | // Calling this reference means we want another handle to an existing shape | ||
1081 | // (usually linksets) so return this copy. | ||
1082 | IncrementReference(); | ||
1083 | return this; | ||
1084 | } | ||
1085 | // Dereferencing a compound shape releases the hold on all the child shapes. | ||
1086 | public override void Dereference(BSScene physicsScene) | ||
1087 | { | ||
1088 | lock (GImpacts) | ||
1089 | { | ||
1090 | this.DecrementReference(); | ||
1091 | physicsScene.DetailLog("{0},BSShapeGImpact.Dereference,shape={1}", BSScene.DetailLogZero, this); | ||
1092 | // TODO: schedule aging and destruction of unused meshes. | ||
1093 | } | ||
1094 | } | ||
1095 | // Loop through all the known hulls and return the description based on the physical address. | ||
1096 | public static bool TryGetGImpactByPtr(BulletShape pShape, out BSShapeGImpact outHull) | ||
1097 | { | ||
1098 | bool ret = false; | ||
1099 | BSShapeGImpact foundDesc = null; | ||
1100 | lock (GImpacts) | ||
1101 | { | ||
1102 | foreach (BSShapeGImpact sh in GImpacts.Values) | ||
1103 | { | ||
1104 | if (sh.physShapeInfo.ReferenceSame(pShape)) | ||
1105 | { | ||
1106 | foundDesc = sh; | ||
1107 | ret = true; | ||
1108 | break; | ||
1109 | } | ||
1110 | |||
1111 | } | ||
1112 | } | ||
1113 | outHull = foundDesc; | ||
1114 | return ret; | ||
1115 | } | ||
1116 | } | ||
940 | 1117 | ||
941 | // ============================================================================================================ | 1118 | // ============================================================================================================ |
942 | public class BSShapeAvatar : BSShape | 1119 | public class BSShapeAvatar : BSShape |