void releaseHull(Hull &h) { HACD_FREE((void *)h.mIndices); HACD_FREE((void *)h.mVertices); h.mIndices = NULL; h.mVertices = NULL; }
void release(void) { HACD_FREE(mIndices); HACD_FREE(mVertices); mIndices = 0; mVertices = 0; mTriCount = 0; mVertexCount = 0; }
HullError HullLibrary::ReleaseResult(HullResult &result) // release memory allocated for this result, we are done with it. { if ( result.mOutputVertices ) { HACD_FREE(result.mOutputVertices); result.mOutputVertices = 0; } if ( result.mIndices ) { HACD_FREE(result.mIndices); result.mIndices = 0; } return QE_OK; }
ChUll * doMerge(ChUll *a,ChUll *b) { ChUll *ret = 0; HaU32 combinedVertexCount = a->mVertexCount + b->mVertexCount; HaF32 *combinedVertices = (HaF32 *)HACD_ALLOC(combinedVertexCount*sizeof(HaF32)*3); HaF32 *dest = combinedVertices; memcpy(dest,a->mVertices, sizeof(HaF32)*3*a->mVertexCount); dest+=a->mVertexCount*3; memcpy(dest,b->mVertices,sizeof(HaF32)*3*b->mVertexCount); HullResult hresult; HullLibrary hl; HullDesc desc; desc.mVcount = combinedVertexCount; desc.mVertices = combinedVertices; desc.mVertexStride = sizeof(hacd::HaF32)*3; desc.mMaxVertices = mMaxHullVertices; desc.mUseWuQuantizer = true; HullError hret = hl.CreateConvexHull(desc,hresult); HACD_ASSERT( hret == QE_OK ); if ( hret == QE_OK ) { ret = HACD_NEW(ChUll)(hresult.mNumOutputVertices, hresult.mOutputVertices, hresult.mNumTriangles, hresult.mIndices,mGuid++); } HACD_FREE(combinedVertices); hl.ReleaseResult(hresult); return ret; }
HaF32 canMerge(ChUll *a,ChUll *b) { if ( !a->overlap(*b) ) return 0; // if their AABB's (with a little slop) don't overlap, then return. // ok..we are going to combine both meshes into a single mesh // and then we are going to compute the concavity... HaF32 ret = 0; HaU32 combinedVertexCount = a->mVertexCount + b->mVertexCount; HaF32 *combinedVertices = (HaF32 *)HACD_ALLOC(combinedVertexCount*sizeof(HaF32)*3); HaF32 *dest = combinedVertices; memcpy(dest,a->mVertices, sizeof(HaF32)*3*a->mVertexCount); dest+=a->mVertexCount*3; memcpy(dest,b->mVertices,sizeof(HaF32)*3*b->mVertexCount); HullResult hresult; HullLibrary hl; HullDesc desc; desc.mVcount = combinedVertexCount; desc.mVertices = combinedVertices; desc.mVertexStride = sizeof(hacd::HaF32)*3; desc.mUseWuQuantizer = true; HullError hret = hl.CreateConvexHull(desc,hresult); HACD_ASSERT( hret == QE_OK ); if ( hret == QE_OK ) { ret = fm_computeMeshVolume( hresult.mOutputVertices, hresult.mNumTriangles, hresult.mIndices ); } HACD_FREE(combinedVertices); hl.ReleaseResult(hresult); return ret; }
void release(void) { delete []mHulls; mHulls = 0; HACD_FREE(mSimpleHulls); mSimpleHulls = 0; }
void HullLibrary::BringOutYourDead(const float *verts,uint32_t vcount, float *overts,uint32_t &ocount,uint32_t *indices,uint32_t indexcount) { uint32_t *used = (uint32_t *)HACD_ALLOC(sizeof(uint32_t)*vcount); memset(used,0,sizeof(uint32_t)*vcount); ocount = 0; for (uint32_t i=0; i<indexcount; i++) { uint32_t v = indices[i]; // original array index HACD_ASSERT( v < vcount ); if ( used[v] ) // if already remapped { indices[i] = used[v]-1; // index to new array } else { indices[i] = ocount; // new index mapping overts[ocount*3+0] = verts[v*3+0]; // copy old vert to new vert array overts[ocount*3+1] = verts[v*3+1]; overts[ocount*3+2] = verts[v*3+2]; ocount++; // increment output vert count HACD_ASSERT( ocount <= vcount ); used[v] = ocount; // assign new index remapping } } HACD_FREE(used); }
~ChUll(void) { HACD_FREE(mVertices); HACD_FREE(mIndices); }
HullError HullLibrary::CreateConvexHull(const HullDesc &desc, // describes the input request HullResult &result) // contains the resulst { HullError ret = QE_FAIL; uint32_t vcount = desc.mVcount; if ( vcount < 8 ) vcount = 8; float *vsource = (float *) HACD_ALLOC( sizeof(float)*vcount*3 ); float scale[3]; float center[3]; uint32_t ovcount; bool ok = NormalizeAndCleanupVertices(desc.mVcount,desc.mVertices, desc.mVertexStride, ovcount, vsource, desc.mNormalEpsilon, scale, center, desc.mMaxVertices*2, desc.mUseWuQuantizer ); // normalize point cloud, remove duplicates! if ( ok ) { double *bigVertices = (double *)HACD_ALLOC(sizeof(double)*3*ovcount); for (uint32_t i=0; i<3*ovcount; i++) { bigVertices[i] = vsource[i]; } dgConvexHull3d convexHull(bigVertices,sizeof(double)*3,(int32_t)ovcount,0.0001f,(int32_t)desc.mMaxVertices); if ( convexHull.GetCount() ) { float *hullVertices = (float *)HACD_ALLOC( sizeof(float)*3*convexHull.GetVertexCount() ); float *dest = hullVertices; for (int32_t i=0; i<convexHull.GetVertexCount(); i++) { const dgBigVector &v = convexHull.GetVertex(i); dest[0] = (float)v.m_x*scale[0]+center[0]; dest[1] = (float)v.m_y*scale[1]+center[1]; dest[2] = (float)v.m_z*scale[2]+center[2]; dest+=3; } uint32_t triangleCount = (uint32_t)convexHull.GetCount(); uint32_t *indices = (uint32_t*)HACD_ALLOC(triangleCount*sizeof(uint32_t)*3); uint32_t *destIndices = indices; dgList<dgConvexHull3DFace>::Iterator iter(convexHull); uint32_t outCount = 0; for (iter.Begin(); iter; iter++) { dgConvexHull3DFace &face = (*iter); destIndices[0] = (uint32_t)face.m_index[0]; destIndices[1] = (uint32_t)face.m_index[1]; destIndices[2] = (uint32_t)face.m_index[2]; destIndices+=3; outCount++; } HACD_ASSERT( outCount == triangleCount ); // re-index triangle mesh so it refers to only used vertices, rebuild a new vertex table. float *vscratch = (float *) HACD_ALLOC( sizeof(float)*convexHull.GetVertexCount()*3 ); BringOutYourDead(hullVertices,(uint32_t)convexHull.GetVertexCount(),vscratch, ovcount, indices, triangleCount*3 ); ret = QE_OK; result.mNumOutputVertices = ovcount; result.mOutputVertices = (float *)HACD_ALLOC( sizeof(float)*ovcount*3); result.mNumTriangles = triangleCount; result.mIndices = (uint32_t *) HACD_ALLOC( sizeof(uint32_t)*triangleCount*3); memcpy(result.mOutputVertices, vscratch, sizeof(float)*3*ovcount ); memcpy(result.mIndices, indices, sizeof(uint32_t)*triangleCount*3); HACD_FREE(indices); HACD_FREE(vscratch); HACD_FREE(hullVertices); } HACD_FREE(bigVertices); } HACD_FREE(vsource); return ret; }
void TMMesh::Copy(TMMesh & mesh) { Clear(); // updating the id's hacd::HaU32 nV = mesh.m_vertices.GetSize(); hacd::HaU32 nE = mesh. m_edges.GetSize(); hacd::HaU32 nT = mesh.m_triangles.GetSize(); for(hacd::HaU32 v = 0; v < nV; v++) { mesh.m_vertices.GetData().m_id = v; mesh.m_vertices.Next(); } for(hacd::HaU32 e = 0; e < nE; e++) { mesh.m_edges.GetData().m_id = e; mesh.m_edges.Next(); } for(hacd::HaU32 f = 0; f < nT; f++) { mesh.m_triangles.GetData().m_id = f; mesh.m_triangles.Next(); } // copying data m_vertices = mesh.m_vertices; m_edges = mesh.m_edges; m_triangles = mesh.m_triangles; // generating mapping CircularListElement<TMMVertex> ** vertexMap = (CircularListElement<TMMVertex> **) HACD_ALLOC(sizeof(CircularListElement<TMMVertex> *)*nV); CircularListElement<TMMEdge> ** edgeMap = (CircularListElement<TMMEdge> **)HACD_ALLOC(sizeof(CircularListElement<TMMEdge> *)*nE); CircularListElement<TMMTriangle> ** triangleMap = (CircularListElement<TMMTriangle> **) HACD_ALLOC(sizeof(CircularListElement<TMMTriangle> *)*nT); for(hacd::HaU32 v = 0; v < nV; v++) { vertexMap[v] = m_vertices.GetHead(); m_vertices.Next(); } for(hacd::HaU32 e = 0; e < nE; e++) { edgeMap[e] = m_edges.GetHead(); m_edges.Next(); } for(hacd::HaU32 f = 0; f < nT; f++) { triangleMap[f] = m_triangles.GetHead(); m_triangles.Next(); } // updating pointers for(hacd::HaU32 v = 0; v < nV; v++) { if (vertexMap[v]->GetData().m_duplicate) { vertexMap[v]->GetData().m_duplicate = edgeMap[vertexMap[v]->GetData().m_duplicate->GetData().m_id]; } } for(hacd::HaU32 e = 0; e < nE; e++) { if (edgeMap[e]->GetData().m_newFace) { edgeMap[e]->GetData().m_newFace = triangleMap[edgeMap[e]->GetData().m_newFace->GetData().m_id]; } if (nT > 0) { for(int f = 0; f < 2; f++) { if (edgeMap[e]->GetData().m_triangles[f]) { edgeMap[e]->GetData().m_triangles[f] = triangleMap[edgeMap[e]->GetData().m_triangles[f]->GetData().m_id]; } } } for(int v = 0; v < 2; v++) { if (edgeMap[e]->GetData().m_vertices[v]) { edgeMap[e]->GetData().m_vertices[v] = vertexMap[edgeMap[e]->GetData().m_vertices[v]->GetData().m_id]; } } } for(hacd::HaU32 f = 0; f < nT; f++) { if (nE > 0) { for(int e = 0; e < 3; e++) { if (triangleMap[f]->GetData().m_edges[e]) { triangleMap[f]->GetData().m_edges[e] = edgeMap[triangleMap[f]->GetData().m_edges[e]->GetData().m_id]; } } } for(int v = 0; v < 3; v++) { if (triangleMap[f]->GetData().m_vertices[v]) { triangleMap[f]->GetData().m_vertices[v] = vertexMap[triangleMap[f]->GetData().m_vertices[v]->GetData().m_id]; } } } HACD_FREE(vertexMap); HACD_FREE(edgeMap); HACD_FREE(triangleMap); }