Exemple #1
0
	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;
	}
		float generateHull(void)
		{
			release();
			if ( mPoints.size() >= 3 ) // must have at least 3 vertices to create a hull.
			{
				// now generate the convex hull.
				HullDesc desc((uint32_t)mPoints.size(),&mPoints[0].x, sizeof(float)*3);
				desc.mMaxVertices = 32;
				desc.mSkinWidth = 0.001f;

				HullLibrary h;
				HullResult result;
				HullError e = h.CreateConvexHull(desc,result);
				if ( e == QE_OK )
				{
					mTriCount = result.mNumTriangles;
					mIndices  = (uint32_t *)HACD_ALLOC(sizeof(uint32_t)*mTriCount*3);
					memcpy(mIndices,result.mIndices,sizeof(uint32_t)*mTriCount*3);
					mVertexCount = result.mNumOutputVertices;
					mVertices = (float *)HACD_ALLOC(sizeof(float)*mVertexCount*3);
					memcpy(mVertices,result.mOutputVertices,sizeof(float)*mVertexCount*3);
					mValidHull = true;
					mMeshVolume = fm_computeMeshVolume( mVertices, mTriCount, mIndices ); // compute the volume of this mesh.
					h.ReleaseResult(result);
				}
			}
			return mMeshVolume;
		}
Exemple #3
0
		ChUll(HaU32 vcount,const HaF32 *vertices,HaU32 tcount,const HaU32 *indices,HaU32 guid)
		{
			mGuid = guid;
			mVertexCount = vcount;
			mTriangleCount = tcount;
			mVertices = (HaF32 *)HACD_ALLOC(sizeof(HaF32)*3*vcount);
			memcpy(mVertices,vertices,sizeof(HaF32)*3*vcount);
			mIndices = (HaU32 *)HACD_ALLOC(sizeof(HaU32)*3*tcount);
			memcpy(mIndices,indices,sizeof(HaU32)*3*tcount);
			mVolume = fm_computeMeshVolume( mVertices, mTriangleCount, mIndices);
			mDiagonal = fm_computeBestFitAABB( mVertexCount, mVertices, sizeof(hacd::HaF32)*3, mMin, mMax );
			hacd::HaF32 dx = mMax[0] - mMin[0];
			hacd::HaF32 dy = mMax[1] - mMin[1];
			hacd::HaF32 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;
		}
NxF32 computeConcavityVolume(NxU32 vcount_hull,
						     const NxF32 *vertices_hull,
						     NxU32 tcount_hull,
						     const NxU32 *indices_hull,
						     NxU32 vcount_mesh,
						     const NxF32 *vertices_mesh,
						     NxU32 tcount_mesh,
						     const NxU32 *indices_mesh)
{
	NxF32 total_volume = 0;

#if SHOW_DEBUG
	NVSHARE::gRenderDebug->pushRenderState();
	NVSHARE::gRenderDebug->setCurrentDisplayTime(150.0f);
#endif

	iRayCast *cast_hull = createRayCast(vertices_hull,tcount_hull,indices_hull);
	iRayCast *cast_mesh = createRayCast(vertices_mesh,tcount_mesh,indices_mesh);


	const NxU32 *indices = indices_mesh;
#if 0
	static NxU32 index = 0;
	NxU32 i = index++;
	indices = &indices[i*3];
#else
	for (NxU32 i=0; i<tcount_mesh; i++)
#endif
	{
		NxU32 i1 = indices[0];
		NxU32 i2 = indices[1];
		NxU32 i3 = indices[2];

		const NxF32 *p1 = &vertices_mesh[i1*3];
		const NxF32 *p2 = &vertices_mesh[i2*3];
		const NxF32 *p3 = &vertices_mesh[i3*3];

		NxF32 normal[3];
		NxF32 d = fm_computePlane(p3,p2,p1,normal);

		NxF32  vertices[6*3];

		vertices[0] = p1[0];
		vertices[1] = p1[1];
		vertices[2] = p1[2];

		vertices[3] = p2[0];
		vertices[4] = p2[1];
		vertices[5] = p2[2];

		vertices[6] = p3[0];
		vertices[7] = p3[1];
		vertices[8] = p3[2];

		NxF32 midPoint[3];
		midPoint[0] = (p1[0]+p2[0]+p3[0])/3;
		midPoint[1] = (p1[1]+p2[1]+p3[1])/3;
		midPoint[2] = (p1[2]+p2[2]+p3[2])/3;

		fm_lerp(midPoint,p1,&vertices[0],0.9999f);
		fm_lerp(midPoint,p2,&vertices[3],0.9999f);
		fm_lerp(midPoint,p3,&vertices[6],0.9999f);

		NxF32 *_p1 = &vertices[3*3];
		NxF32 *_p2 = &vertices[4*3];
		NxF32 *_p3 = &vertices[5*3];

		NxU32 hitCount = 0;

		if ( raycast(&vertices[0],normal, _p1,cast_hull,cast_mesh) ) hitCount++;
		if ( raycast(&vertices[3],normal, _p2,cast_hull,cast_mesh) ) hitCount++;
		if ( raycast(&vertices[6],normal, _p3,cast_hull,cast_mesh) ) hitCount++;

		// form triangle mesh!
		if ( hitCount == 3 )
		{
			NxU32 tcount = 0;
			NxU32 tindices[8*3];

			addTri(tindices,2,1,0,tcount);
			addTri(tindices,3,4,5,tcount);

			addTri(tindices,0,3,2,tcount);
			addTri(tindices,2,3,5,tcount);

			addTri(tindices,1,3,0,tcount);
			addTri(tindices,4,3,1,tcount);

			addTri(tindices,5,4,1,tcount);
			addTri(tindices,2,5,1,tcount);

			NxF32 volume = fm_computeMeshVolume(vertices,tcount,tindices);
			total_volume+=volume;
#if SHOW_DEBUG
			NVSHARE::gRenderDebug->setCurrentColor(0x0000FF,0xFFFFFF);
			NVSHARE::gRenderDebug->addToCurrentState(NVSHARE::DebugRenderState::SolidWireShaded);

			for (NxU32 i=0; i<tcount; i++)
			{
				NxU32 i1 = tindices[i*3+0];
				NxU32 i2 = tindices[i*3+1];
				NxU32 i3 = tindices[i*3+2];

				const NxF32 *p1 = &vertices[i1*3];
				const NxF32 *p2 = &vertices[i2*3];
				const NxF32 *p3 = &vertices[i3*3];

				NVSHARE::gRenderDebug->DebugTri(p1,p2,p3);
			}
#endif
		}
		indices+=3;
	}
#if SHOW_DEBUG
	NVSHARE::gRenderDebug->popRenderState();
#endif

	releaseRayCast(cast_hull);
	releaseRayCast(cast_mesh);

	return total_volume;
}