Exemplo n.º 1
0
CHull * ConvexBuilder::canMerge(CHull *a,CHull *b)
{

	if ( !a->overlap(*b) ) return 0; // if their AABB's (with a little slop) don't overlap, then return.

	CHull *ret = 0;

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

	VertexLookup vc = Vl_createVertexLookup();

	UintVector indices;

	getMesh( *a->mResult, vc, indices );
	getMesh( *b->mResult, vc, indices );

	unsigned int vcount = Vl_getVcount(vc);
	const float *vertices = Vl_getVertices(vc);
	unsigned int tcount = indices.size()/3;
	
	//don't do anything if hull is empty
	if (!tcount)
	{
		Vl_releaseVertexLookup (vc);
		return 0;
	}

	HullResult hresult;
	HullLibrary hl;
	HullDesc   desc;

	desc.SetHullFlag(QF_TRIANGLES);

	desc.mVcount       = vcount;
	desc.mVertices     = vertices;
	desc.mVertexStride = sizeof(float)*3;

	HullError hret = hl.CreateConvexHull(desc,hresult);

	if ( hret == QE_OK )
	{

		float combineVolume  = computeMeshVolume( hresult.mOutputVertices, hresult.mNumFaces, hresult.mIndices );
		float sumVolume      = a->mVolume + b->mVolume;

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


	Vl_releaseVertexLookup(vc);

	return ret;
}
Exemplo n.º 2
0
void ConvexBuilder::getMesh(const ConvexResult &cr,VertexLookup vc,UintVector &indices)
{
	unsigned int *src = cr.mHullIndices;

	for (unsigned int i=0; i<cr.mHullTcount; i++)
	{
		unsigned int i1 = *src++;
		unsigned int i2 = *src++;
		unsigned int i3 = *src++;

		const float *p1 = &cr.mHullVertices[i1*3];
		const float *p2 = &cr.mHullVertices[i2*3];
		const float *p3 = &cr.mHullVertices[i3*3];

		i1 = Vl_getIndex(vc,p1);
		i2 = Vl_getIndex(vc,p2);
		i3 = Vl_getIndex(vc,p3);

#if 0
		bool duplicate = false;

		unsigned int tcount = indices.size()/3;
		for (unsigned int j=0; j<tcount; j++)
		{
			unsigned int ci1 = indices[j*3+0];
			unsigned int ci2 = indices[j*3+1];
			unsigned int ci3 = indices[j*3+2];
			if ( isDuplicate(i1,i2,i3, ci1, ci2, ci3 ) )
			{
				duplicate = true;
				break;
			}
		}

		if ( !duplicate )
		{
			indices.push_back(i1);
			indices.push_back(i2);
			indices.push_back(i3);
		}
#endif

	}
}
Exemplo n.º 3
0
void calcConvexDecomposition(unsigned int           vcount,
                                const float           *vertices,
                                unsigned int           tcount,
                                const unsigned int    *indices,
                                ConvexDecompInterface *callback,
                                float                  masterVolume,
                                unsigned int           depth)

{

  float plane[4];

  bool split = false;


  if ( depth < MAXDEPTH )
  {

		float volume;
		float c = computeConcavity( vcount, vertices, tcount, indices, callback, plane, volume );

    if ( depth == 0 )
    {
      masterVolume = volume;
    }

		float percent = (c*100.0f)/masterVolume;

		if ( percent > CONCAVE_PERCENT ) // if great than 5% of the total volume is concave, go ahead and keep splitting.
		{
      split = true;
    }

  }

  if ( depth >= MAXDEPTH || !split )
  {

#if 1

    HullResult result;
    HullLibrary hl;
    HullDesc   desc;

  	desc.SetHullFlag(QF_TRIANGLES);

    desc.mVcount       = vcount;
    desc.mVertices     = vertices;
    desc.mVertexStride = sizeof(float)*3;

    HullError ret = hl.CreateConvexHull(desc,result);

    if ( ret == QE_OK )
    {

			ConvexResult r(result.mNumOutputVertices, result.mOutputVertices, result.mNumFaces, result.mIndices);


			callback->ConvexDecompResult(r);
    }


#else

		static unsigned int colors[8] =
		{
			0xFF0000,
		  0x00FF00,
			0x0000FF,
			0xFFFF00,
			0x00FFFF,
			0xFF00FF,
			0xFFFFFF,
			0xFF8040
		};

		static int count = 0;

		count++;

		if ( count == 8 ) count = 0;

		assert( count >= 0 && count < 8 );

		unsigned int color = colors[count];

    const unsigned int *source = indices;

    for (unsigned int i=0; i<tcount; i++)
    {

      unsigned int i1 = *source++;
      unsigned int i2 = *source++;
      unsigned int i3 = *source++;

			FaceTri t(vertices, i1, i2, i3 );

      callback->ConvexDebugTri( t.mP1.Ptr(), t.mP2.Ptr(), t.mP3.Ptr(), color );

    }
#endif

    return;

  }

  UintVector ifront;
  UintVector iback;

  VertexLookup vfront = Vl_createVertexLookup();
  VertexLookup vback  = Vl_createVertexLookup();


	bool showmesh = false;
  #if SHOW_MESH
  showmesh = true;
  #endif

	if ( 0 )
	{
		showmesh = true;
	  for (float x=-1; x<1; x+=0.10f)
		{
		  for (float y=0; y<1; y+=0.10f)
			{
			  for (float z=-1; z<1; z+=0.04f)
				{
				  float d = x*plane[0] + y*plane[1] + z*plane[2] + plane[3];
					Vector3d p(x,y,z);
				  if ( d >= 0 )
					  callback->ConvexDebugPoint(p.Ptr(), 0.02f, 0x00FF00);
				  else
					  callback->ConvexDebugPoint(p.Ptr(), 0.02f, 0xFF0000);
				}
			}
		}
	}

	if ( 1 )
	{
		// ok..now we are going to 'split' all of the input triangles against this plane!
		const unsigned int *source = indices;
		for (unsigned int i=0; i<tcount; i++)
		{
			unsigned int i1 = *source++;
			unsigned int i2 = *source++;
			unsigned int i3 = *source++;

			FaceTri t(vertices, i1, i2, i3 );

			Vector3d front[4];
			Vector3d back[4];

			unsigned int fcount=0;
			unsigned int bcount=0;

			PlaneTriResult result;

		  result = planeTriIntersection(plane,t.mP1.Ptr(),sizeof(Vector3d),0.00001f,front[0].Ptr(),fcount,back[0].Ptr(),bcount );

			if( fcount > 4 || bcount > 4 )
			{
		    result = planeTriIntersection(plane,t.mP1.Ptr(),sizeof(Vector3d),0.00001f,front[0].Ptr(),fcount,back[0].Ptr(),bcount );
			}

			switch ( result )
			{
				case PTR_FRONT:

					assert( fcount == 3 );

          if ( showmesh )
            callback->ConvexDebugTri( front[0].Ptr(), front[1].Ptr(), front[2].Ptr(), 0x00FF00 );

          #if MAKE_MESH

          addTri( vfront, ifront, front[0], front[1], front[2] );


          #endif

					break;
				case PTR_BACK:
					assert( bcount == 3 );

          if ( showmesh )
  					callback->ConvexDebugTri( back[0].Ptr(), back[1].Ptr(), back[2].Ptr(), 0xFFFF00 );

          #if MAKE_MESH

          addTri( vback, iback, back[0], back[1], back[2] );

          #endif

					break;
				case PTR_SPLIT:

					assert( fcount >= 3 && fcount <= 4);
					assert( bcount >= 3 && bcount <= 4);

          #if MAKE_MESH

          addTri( vfront, ifront, front[0], front[1], front[2] );
          addTri( vback, iback, back[0], back[1], back[2] );


          if ( fcount == 4 )
          {
            addTri( vfront, ifront, front[0], front[2], front[3] );
          }

          if ( bcount == 4  )
          {
            addTri( vback, iback, back[0], back[2], back[3] );
          }

          #endif

          if ( showmesh )
          {
  					callback->ConvexDebugTri( front[0].Ptr(), front[1].Ptr(), front[2].Ptr(), 0x00D000 );
  					callback->ConvexDebugTri( back[0].Ptr(), back[1].Ptr(), back[2].Ptr(), 0xD0D000 );

  					if ( fcount == 4 )
  					{
  						callback->ConvexDebugTri( front[0].Ptr(), front[2].Ptr(), front[3].Ptr(), 0x00D000 );
  					}
  					if ( bcount == 4 )
  					{
  						callback->ConvexDebugTri( back[0].Ptr(), back[2].Ptr(), back[3].Ptr(), 0xD0D000 );
  					}
  				}

					break;
			}
		}

		unsigned int fsize = ifront.size()/3;
		unsigned int bsize = iback.size()/3;

    // ok... here we recursively call
    if ( ifront.size() )
    {
      unsigned int vcount   = Vl_getVcount(vfront);
      const float *vertices = Vl_getVertices(vfront);
      unsigned int tcount   = ifront.size()/3;

      calcConvexDecomposition(vcount, vertices, tcount, &ifront[0], callback, masterVolume, depth+1);

    }

    ifront.clear();

    Vl_releaseVertexLookup(vfront);

    if ( iback.size() )
    {
      unsigned int vcount   = Vl_getVcount(vback);
      const float *vertices = Vl_getVertices(vback);
      unsigned int tcount   = iback.size()/3;

      calcConvexDecomposition(vcount, vertices, tcount, &iback[0], callback, masterVolume, depth+1);

    }

    iback.clear();
    Vl_releaseVertexLookup(vback);

	}
}