public CHull canMerge(CHull a, CHull b)
        {
            if (!a.overlap(b)) // if their AABB's (with a little slop) don't overlap, then return.
            {
                return(null);
            }

            CHull ret = null;

            // ok..we are going to combine both meshes into a single mesh
            // and then we are going to compute the concavity...

            VertexPool vc = new VertexPool();

            List <int> indices = new List <int>();

            getMesh(a.mResult, vc, indices);
            getMesh(b.mResult, vc, indices);

            int           vcount   = vc.GetSize();
            List <float3> vertices = vc.GetVertices();
            int           tcount   = indices.Count / 3;

            //don't do anything if hull is empty
            if (tcount == 0)
            {
                vc.Clear();
                return(null);
            }

            HullResult hresult = new HullResult();
            HullDesc   desc    = new HullDesc();

            desc.SetHullFlag(HullFlag.QF_TRIANGLES);
            desc.Vertices = vertices;

            HullError hret = HullUtils.CreateConvexHull(desc, ref hresult);

            if (hret == HullError.QE_OK)
            {
                float combineVolume = Concavity.computeMeshVolume(hresult.OutputVertices, hresult.Indices);
                float sumVolume     = a.mVolume + b.mVolume;

                float percent = (sumVolume * 100) / combineVolume;
                if (percent >= (100.0f - MERGE_PERCENT))
                {
                    ConvexResult cr = new ConvexResult(hresult.OutputVertices, hresult.Indices);
                    ret = new CHull(cr);
                }
            }

            vc.Clear();
            return(ret);
        }
        public CHull(ConvexResult result)
        {
            mResult = new ConvexResult(result);
            mVolume = Concavity.computeMeshVolume(result.HullVertices, result.HullIndices);

            mDiagonal = getBoundingRegion(result.HullVertices, mMin, mMax);

            float dx = mMax[0] - mMin[0];
            float dy = mMax[1] - mMin[1];
            float dz = mMax[2] - mMin[2];

            dx *= 0.1f; // inflate 1/10th on each edge
            dy *= 0.1f; // inflate 1/10th on each edge
            dz *= 0.1f; // inflate 1/10th on each edge

            mMin[0] -= dx;
            mMin[1] -= dy;
            mMin[2] -= dz;

            mMax[0] += dx;
            mMax[1] += dy;
            mMax[2] += dz;
        }
        public int process(DecompDesc desc)
        {
            int ret = 0;

            MAXDEPTH        = (int)desc.mDepth;
            CONCAVE_PERCENT = desc.mCpercent;
            MERGE_PERCENT   = desc.mPpercent;

            ConvexDecomposition.calcConvexDecomposition(desc.mVertices, desc.mIndices, ConvexDecompResult, 0f, 0, MAXDEPTH, CONCAVE_PERCENT, MERGE_PERCENT);

            while (combineHulls()) // keep combinging hulls until I can't combine any more...
            {
                ;
            }

            int i;

            for (i = 0; i < mChulls.Count; i++)
            {
                CHull cr = mChulls[i];

                // before we hand it back to the application, we need to regenerate the hull based on the
                // limits given by the user.

                ConvexResult c = cr.mResult; // the high resolution hull...

                HullResult result = new HullResult();
                HullDesc   hdesc  = new HullDesc();

                hdesc.SetHullFlag(HullFlag.QF_TRIANGLES);

                hdesc.Vertices    = c.HullVertices;
                hdesc.MaxVertices = desc.mMaxVertices; // maximum number of vertices allowed in the output

                if (desc.mSkinWidth != 0f)
                {
                    hdesc.SkinWidth = desc.mSkinWidth;
                    hdesc.SetHullFlag(HullFlag.QF_SKIN_WIDTH); // do skin width computation.
                }

                HullError ret2 = HullUtils.CreateConvexHull(hdesc, ref result);

                if (ret2 == HullError.QE_OK)
                {
                    ConvexResult r = new ConvexResult(result.OutputVertices, result.Indices);

                    r.mHullVolume = Concavity.computeMeshVolume(result.OutputVertices, result.Indices); // the volume of the hull.

                    mCallback(r);
                }

                result = null;
                cr.Dispose();
            }

            ret = mChulls.Count;

            mChulls.Clear();

            return(ret);
        }