bool computeSplitPlane(unsigned int vcount, const double *vertices, unsigned int tcount, const unsigned int *indices, ConvexDecompInterface *callback, double *plane) { bool cret = false; double sides[3]; double matrix[16]; computeBestFitOBB( vcount, vertices, sizeof(double)*3, sides, matrix ); double bmax[3]; double bmin[3]; bmax[0] = sides[0]*0.5f; bmax[1] = sides[1]*0.5f; bmax[2] = sides[2]*0.5f; bmin[0] = -bmax[0]; bmin[1] = -bmax[1]; bmin[2] = -bmax[2]; double dx = sides[0]; double dy = sides[1]; double dz = sides[2]; double laxis = dx; unsigned int axis = 0; if ( dy > dx ) { axis = 1; laxis = dy; } if ( dz > dx && dz > dy ) { axis = 2; laxis = dz; } double p1[3]; double p2[3]; double p3[3]; p3[0] = p2[0] = p1[0] = bmin[0] + dx*0.5f; p3[1] = p2[1] = p1[1] = bmin[1] + dy*0.5f; p3[2] = p2[2] = p1[2] = bmin[2] + dz*0.5f; Rect3d b(bmin,bmax); Rect3d b1,b2; splitRect(axis,b,b1,b2,p1); // callback->ConvexDebugBound(b1.mMin,b1.mMax,0x00FF00); // callback->ConvexDebugBound(b2.mMin,b2.mMax,0xFFFF00); switch ( axis ) { case 0: p2[1] = bmin[1]; p2[2] = bmin[2]; if ( dz > dy ) { p3[1] = bmax[1]; p3[2] = bmin[2]; } else { p3[1] = bmin[1]; p3[2] = bmax[2]; } break; case 1: p2[0] = bmin[0]; p2[2] = bmin[2]; if ( dx > dz ) { p3[0] = bmax[0]; p3[2] = bmin[2]; } else { p3[0] = bmin[0]; p3[2] = bmax[2]; } break; case 2: p2[0] = bmin[0]; p2[1] = bmin[1]; if ( dx > dy ) { p3[0] = bmax[0]; p3[1] = bmin[1]; } else { p3[0] = bmin[0]; p3[1] = bmax[1]; } break; } double tp1[3]; double tp2[3]; double tp3[3]; fm_transform(matrix,p1,tp1); fm_transform(matrix,p2,tp2); fm_transform(matrix,p3,tp3); // callback->ConvexDebugTri(p1,p2,p3,0xFF0000); computePlane(tp1,tp2,tp3,plane); return true; }
unsigned int ConvexBuilder::process(const DecompDesc &desc) { unsigned int ret = 0; MAXDEPTH = desc.mDepth; CONCAVE_PERCENT = desc.mCpercent; MERGE_PERCENT = desc.mPpercent; calcConvexDecomposition(desc.mVcount, desc.mVertices, desc.mTcount, desc.mIndices,this,0,0); while ( combineHulls() ); // keep combinging hulls until I can't combine any more... int i; for (i=0;i<mChulls.size();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. const ConvexResult &c = *cr->mResult; // the high resolution hull... HullResult result; HullLibrary hl; HullDesc hdesc; hdesc.SetHullFlag(QF_TRIANGLES); hdesc.mVcount = c.mHullVcount; hdesc.mVertices = c.mHullVertices; hdesc.mVertexStride = sizeof(float)*3; hdesc.mMaxVertices = desc.mMaxVertices; // maximum number of vertices allowed in the output if ( desc.mSkinWidth ) { hdesc.mSkinWidth = desc.mSkinWidth; hdesc.SetHullFlag(QF_SKIN_WIDTH); // do skin width computation. } HullError ret = hl.CreateConvexHull(hdesc,result); if ( ret == QE_OK ) { ConvexResult r(result.mNumOutputVertices, result.mOutputVertices, result.mNumFaces, result.mIndices); r.mHullVolume = computeMeshVolume( result.mOutputVertices, result.mNumFaces, result.mIndices ); // 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->ConvexDecompResult(r); } hl.ReleaseResult (result); delete cr; } ret = mChulls.size(); mChulls.clear(); return ret; }