예제 #1
0
 public BSShapeConvexHull(BulletShape pShape) : base(pShape)
 {
 }
예제 #2
0
 public BSShapeCompound(BulletShape pShape) : base(pShape)
 {
 }
예제 #3
0
    private static BulletShape CreatePhysicalCompoundShape(BSScene physicsScene)
    {
        BulletShape cShape = physicsScene.PE.CreateCompoundShape(physicsScene.World, false);

        return(cShape);
    }
예제 #4
0
    private BulletShape CreatePhysicalHull(BSScene physicsScene, BSPhysObject prim, System.UInt64 newHullKey,
                                           PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
    {
        BulletShape newShape = new BulletShape();
        IntPtr      hullPtr  = IntPtr.Zero;

        if (BSParam.ShouldUseBulletHACD)
        {
            // Build the hull shape from an existing mesh shape.
            // The mesh should have already been created in Bullet.
            physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,entry", prim.LocalID);
            BSShape meshShape = BSShapeMesh.GetReference(physicsScene, true, prim);

            if (meshShape.physShapeInfo.HasPhysicalShape)
            {
                HACDParams parms;
                parms.maxVerticesPerHull          = BSParam.BHullMaxVerticesPerHull;
                parms.minClusters                 = BSParam.BHullMinClusters;
                parms.compacityWeight             = BSParam.BHullCompacityWeight;
                parms.volumeWeight                = BSParam.BHullVolumeWeight;
                parms.concavity                   = BSParam.BHullConcavity;
                parms.addExtraDistPoints          = BSParam.NumericBool(BSParam.BHullAddExtraDistPoints);
                parms.addNeighboursDistPoints     = BSParam.NumericBool(BSParam.BHullAddNeighboursDistPoints);
                parms.addFacesPoints              = BSParam.NumericBool(BSParam.BHullAddFacesPoints);
                parms.shouldAdjustCollisionMargin = BSParam.NumericBool(BSParam.BHullShouldAdjustCollisionMargin);

                physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape);
                newShape = physicsScene.PE.BuildHullShapeFromMesh(physicsScene.World, meshShape.physShapeInfo, parms);
                physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);

                // Now done with the mesh shape.
                meshShape.Dereference(physicsScene);
            }
            physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
        }
        if (!newShape.HasPhysicalShape)
        {
            // Build a new hull in the physical world using the C# HACD algorigthm.
            // Pass true for physicalness as this prevents the creation of bounding box which is not needed
            IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */);
            if (meshData != null)
            {
                if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched)
                {
                    // Release the fetched asset data once it has been used.
                    pbs.SculptData      = new byte[0];
                    prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Unknown;
                }

                int[] indices = meshData.getIndexListAsInt();
                List <OMV.Vector3> vertices = meshData.getVertexList();

                //format conversion from IMesh format to DecompDesc format
                List <int>    convIndices  = new List <int>();
                List <float3> convVertices = new List <float3>();
                for (int ii = 0; ii < indices.GetLength(0); ii++)
                {
                    convIndices.Add(indices[ii]);
                }
                foreach (OMV.Vector3 vv in vertices)
                {
                    convVertices.Add(new float3(vv.X, vv.Y, vv.Z));
                }

                uint maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplit;
                if (BSParam.CSHullMaxDepthSplit != BSParam.CSHullMaxDepthSplitForSimpleShapes)
                {
                    // Simple primitive shapes we know are convex so they are better implemented with
                    //    fewer hulls.
                    // Check for simple shape (prim without cuts) and reduce split parameter if so.
                    if (BSShapeCollection.PrimHasNoCuts(pbs))
                    {
                        maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplitForSimpleShapes;
                    }
                }

                // setup and do convex hull conversion
                m_hulls = new List <ConvexResult>();
                DecompDesc dcomp = new DecompDesc();
                dcomp.mIndices     = convIndices;
                dcomp.mVertices    = convVertices;
                dcomp.mDepth       = maxDepthSplit;
                dcomp.mCpercent    = BSParam.CSHullConcavityThresholdPercent;
                dcomp.mPpercent    = BSParam.CSHullVolumeConservationThresholdPercent;
                dcomp.mMaxVertices = (uint)BSParam.CSHullMaxVertices;
                dcomp.mSkinWidth   = BSParam.CSHullMaxSkinWidth;
                ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn);
                // create the hull into the _hulls variable
                convexBuilder.process(dcomp);

                physicsScene.DetailLog("{0},BSShapeCollection.CreatePhysicalHull,key={1},inVert={2},inInd={3},split={4},hulls={5}",
                                       BSScene.DetailLogZero, newHullKey, indices.GetLength(0), vertices.Count, maxDepthSplit, m_hulls.Count);

                // Convert the vertices and indices for passing to unmanaged.
                // The hull information is passed as a large floating point array.
                // The format is:
                //  convHulls[0] = number of hulls
                //  convHulls[1] = number of vertices in first hull
                //  convHulls[2] = hull centroid X coordinate
                //  convHulls[3] = hull centroid Y coordinate
                //  convHulls[4] = hull centroid Z coordinate
                //  convHulls[5] = first hull vertex X
                //  convHulls[6] = first hull vertex Y
                //  convHulls[7] = first hull vertex Z
                //  convHulls[8] = second hull vertex X
                //  ...
                //  convHulls[n] = number of vertices in second hull
                //  convHulls[n+1] = second hull centroid X coordinate
                //  ...
                //
                // TODO: is is very inefficient. Someday change the convex hull generator to return
                //   data structures that do not need to be converted in order to pass to Bullet.
                //   And maybe put the values directly into pinned memory rather than marshaling.
                int hullCount     = m_hulls.Count;
                int totalVertices = 1;          // include one for the count of the hulls
                foreach (ConvexResult cr in m_hulls)
                {
                    totalVertices += 4;                         // add four for the vertex count and centroid
                    totalVertices += cr.HullIndices.Count * 3;  // we pass just triangles
                }
                float[] convHulls = new float[totalVertices];

                convHulls[0] = (float)hullCount;
                int jj = 1;
                foreach (ConvexResult cr in m_hulls)
                {
                    // copy vertices for index access
                    float3[] verts = new float3[cr.HullVertices.Count];
                    int      kk    = 0;
                    foreach (float3 ff in cr.HullVertices)
                    {
                        verts[kk++] = ff;
                    }

                    // add to the array one hull's worth of data
                    convHulls[jj++] = cr.HullIndices.Count;
                    convHulls[jj++] = 0f;   // centroid x,y,z
                    convHulls[jj++] = 0f;
                    convHulls[jj++] = 0f;
                    foreach (int ind in cr.HullIndices)
                    {
                        convHulls[jj++] = verts[ind].x;
                        convHulls[jj++] = verts[ind].y;
                        convHulls[jj++] = verts[ind].z;
                    }
                }
                // create the hull data structure in Bullet
                newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls);
            }
            newShape.shapeKey = newHullKey;
        }
        return(newShape);
    }
예제 #5
0
 public BSShapeHull(BulletShape pShape) : base(pShape)
 {
 }
예제 #6
0
    private BulletShape CreatePhysicalMesh(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey,
                                           PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
    {
        BulletShape newShape = new BulletShape();

        IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod,
                                                        false, // say it is not physical so a bounding box is not built
                                                        false  // do not cache the mesh and do not use previously built versions
                                                        );

        if (meshData != null)
        {
            if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched)
            {
                // Release the fetched asset data once it has been used.
                pbs.SculptData      = new byte[0];
                prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Unknown;
            }

            int[]   indices          = meshData.getIndexListAsInt();
            int     realIndicesIndex = indices.Length;
            float[] verticesAsFloats = meshData.getVertexListAsFloat();

            if (BSParam.ShouldRemoveZeroWidthTriangles)
            {
                // Remove degenerate triangles. These are triangles with two of the vertices
                //    are the same. This is complicated by the problem that vertices are not
                //    made unique in sculpties so we have to compare the values in the vertex.
                realIndicesIndex = 0;
                for (int tri = 0; tri < indices.Length; tri += 3)
                {
                    // Compute displacements into vertex array for each vertex of the triangle
                    int v1 = indices[tri + 0] * 3;
                    int v2 = indices[tri + 1] * 3;
                    int v3 = indices[tri + 2] * 3;
                    // Check to see if any two of the vertices are the same
                    if (!((verticesAsFloats[v1 + 0] == verticesAsFloats[v2 + 0] &&
                           verticesAsFloats[v1 + 1] == verticesAsFloats[v2 + 1] &&
                           verticesAsFloats[v1 + 2] == verticesAsFloats[v2 + 2]) ||
                          (verticesAsFloats[v2 + 0] == verticesAsFloats[v3 + 0] &&
                           verticesAsFloats[v2 + 1] == verticesAsFloats[v3 + 1] &&
                           verticesAsFloats[v2 + 2] == verticesAsFloats[v3 + 2]) ||
                          (verticesAsFloats[v1 + 0] == verticesAsFloats[v3 + 0] &&
                           verticesAsFloats[v1 + 1] == verticesAsFloats[v3 + 1] &&
                           verticesAsFloats[v1 + 2] == verticesAsFloats[v3 + 2]))
                        )
                    {
                        // None of the vertices of the triangles are the same. This is a good triangle;
                        indices[realIndicesIndex + 0] = indices[tri + 0];
                        indices[realIndicesIndex + 1] = indices[tri + 1];
                        indices[realIndicesIndex + 2] = indices[tri + 2];
                        realIndicesIndex += 3;
                    }
                }
            }
            physicsScene.DetailLog("{0},BSShapeMesh.CreatePhysicalMesh,key={1},origTri={2},realTri={3},numVerts={4}",
                                   BSScene.DetailLogZero, newMeshKey.ToString("X"), indices.Length / 3, realIndicesIndex / 3, verticesAsFloats.Length / 3);

            if (realIndicesIndex != 0)
            {
                newShape = physicsScene.PE.CreateMeshShape(physicsScene.World,
                                                           realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats);
            }
            else
            {
                // Force the asset condition to 'failed' so we won't try to keep fetching and processing this mesh.
                prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed;
                physicsScene.Logger.DebugFormat("{0} All mesh triangles degenerate. Prim {1} at {2} in {3}",
                                                LogHeader, prim.PhysObjectName, prim.RawPosition, physicsScene.Name);
                physicsScene.DetailLog("{0},BSShapeMesh.CreatePhysicalMesh,allDegenerate,key={1}", prim.LocalID, newMeshKey);
            }
        }
        newShape.shapeKey = newMeshKey;

        return(newShape);
    }
예제 #7
0
 public BSShapeMesh(BulletShape pShape) : base(pShape)
 {
 }
예제 #8
0
 public BSShapeNative(BulletShape pShape) : base(pShape)
 {
 }