public void Dispose() { int i; for (i = 0; i < mChulls.Count; i++) { CHull cr = mChulls[i]; cr.Dispose(); } }
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); // 20131224 not used 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 bool overlap(CHull h) { return overlapAABB(mMin, mMax, h.mMin, h.mMax); }
public void ConvexDecompResult(ConvexResult result) { CHull ch = new CHull(result); mChulls.Add(ch); }
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); // 20131224 not used 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 bool overlap(CHull h) { return(overlapAABB(mMin, mMax, h.mMin, h.mMax)); }
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. // compute the best fit OBB //computeBestFitOBB(result.mNumOutputVertices, result.mOutputVertices, sizeof(float) * 3, r.mOBBSides, r.mOBBTransform); //r.mOBBVolume = r.mOBBSides[0] * r.mOBBSides[1] * r.mOBBSides[2]; // compute the OBB volume. //fm_getTranslation(r.mOBBTransform, r.mOBBCenter); // get the translation component of the 4x4 matrix. //fm_matrixToQuat(r.mOBBTransform, r.mOBBOrientation); // extract the orientation as a quaternion. //r.mSphereRadius = computeBoundingSphere(result.mNumOutputVertices, result.mOutputVertices, r.mSphereCenter); //r.mSphereVolume = fm_sphereVolume(r.mSphereRadius); mCallback(r); } result = null; cr.Dispose(); } ret = mChulls.Count; mChulls.Clear(); return(ret); }
public bool combineHulls() { bool combine = false; sortChulls(mChulls); // sort the convex hulls, largest volume to least... List <CHull> output = new List <CHull>(); // the output hulls... int i; for (i = 0; i < mChulls.Count && !combine; ++i) { CHull cr = mChulls[i]; int j; for (j = 0; j < mChulls.Count; j++) { CHull match = mChulls[j]; if (cr != match) // don't try to merge a hull with itself, that be stoopid { CHull merge = canMerge(cr, match); // if we can merge these two.... if (merge != null) { output.Add(merge); ++i; while (i != mChulls.Count) { CHull cr2 = mChulls[i]; if (cr2 != match) { output.Add(cr2); } i++; } cr.Dispose(); match.Dispose(); combine = true; break; } } } if (combine) { break; } else { output.Add(cr); } } if (combine) { mChulls.Clear(); mChulls = output; output.Clear(); } return(combine); }