Logo Search packages:      
Sourcecode: blender version File versions  Download package

bool HullLibrary::CleanupVertices ( unsigned int  svcount,
const btVector3 *  svertices,
unsigned int  stride,
unsigned int &  vcount,
btVector3 *  vertices,
btScalar  normalepsilon,
btVector3 &  scale 
) [private]

XXX might be broken

Definition at line 862 of file btConvexHull.cpp.

References btAlignedObjectArray< T >::push_back(), and btAlignedObjectArray< T >::resize().

{
      if ( svcount == 0 ) return false;

      m_vertexIndexMapping.resize(0);


#define EPSILON btScalar(0.000001) /* close enough to consider two btScalaring point numbers to be 'the same'. */

      vcount = 0;

      btScalar recip[3];

      if ( scale )
      {
            scale[0] = 1;
            scale[1] = 1;
            scale[2] = 1;
      }

      btScalar bmin[3] = {  FLT_MAX,  FLT_MAX,  FLT_MAX };
      btScalar bmax[3] = { -FLT_MAX, -FLT_MAX, -FLT_MAX };

      const char *vtx = (const char *) svertices;

//    if ( 1 )
      {
            for (unsigned int i=0; i<svcount; i++)
            {
                  const btScalar *p = (const btScalar *) vtx;

                  vtx+=stride;

                  for (int j=0; j<3; j++)
                  {
                        if ( p[j] < bmin[j] ) bmin[j] = p[j];
                        if ( p[j] > bmax[j] ) bmax[j] = p[j];
                  }
            }
      }

      btScalar dx = bmax[0] - bmin[0];
      btScalar dy = bmax[1] - bmin[1];
      btScalar dz = bmax[2] - bmin[2];

      btVector3 center;

      center[0] = dx*btScalar(0.5) + bmin[0];
      center[1] = dy*btScalar(0.5) + bmin[1];
      center[2] = dz*btScalar(0.5) + bmin[2];

      if ( dx < EPSILON || dy < EPSILON || dz < EPSILON || svcount < 3 )
      {

            btScalar len = FLT_MAX;

            if ( dx > EPSILON && dx < len ) len = dx;
            if ( dy > EPSILON && dy < len ) len = dy;
            if ( dz > EPSILON && dz < len ) len = dz;

            if ( len == FLT_MAX )
            {
                  dx = dy = dz = btScalar(0.01); // one centimeter
            }
            else
            {
                  if ( dx < EPSILON ) dx = len * btScalar(0.05); // 1/5th the shortest non-zero edge.
                  if ( dy < EPSILON ) dy = len * btScalar(0.05);
                  if ( dz < EPSILON ) dz = len * btScalar(0.05);
            }

            btScalar x1 = center[0] - dx;
            btScalar x2 = center[0] + dx;

            btScalar y1 = center[1] - dy;
            btScalar y2 = center[1] + dy;

            btScalar z1 = center[2] - dz;
            btScalar z2 = center[2] + dz;

            addPoint(vcount,vertices,x1,y1,z1);
            addPoint(vcount,vertices,x2,y1,z1);
            addPoint(vcount,vertices,x2,y2,z1);
            addPoint(vcount,vertices,x1,y2,z1);
            addPoint(vcount,vertices,x1,y1,z2);
            addPoint(vcount,vertices,x2,y1,z2);
            addPoint(vcount,vertices,x2,y2,z2);
            addPoint(vcount,vertices,x1,y2,z2);

            return true; // return cube


      }
      else
      {
            if ( scale )
            {
                  scale[0] = dx;
                  scale[1] = dy;
                  scale[2] = dz;

                  recip[0] = 1 / dx;
                  recip[1] = 1 / dy;
                  recip[2] = 1 / dz;

                  center[0]*=recip[0];
                  center[1]*=recip[1];
                  center[2]*=recip[2];

            }

      }



      vtx = (const char *) svertices;

      for (unsigned int i=0; i<svcount; i++)
      {
            const btVector3 *p = (const btVector3 *)vtx;
            vtx+=stride;

            btScalar px = p->getX();
            btScalar py = p->getY();
            btScalar pz = p->getZ();

            if ( scale )
            {
                  px = px*recip[0]; // normalize
                  py = py*recip[1]; // normalize
                  pz = pz*recip[2]; // normalize
            }

//          if ( 1 )
            {
                  unsigned int j;

                  for (j=0; j<vcount; j++)
                  {
                        /// XXX might be broken
                        btVector3& v = vertices[j];

                        btScalar x = v[0];
                        btScalar y = v[1];
                        btScalar z = v[2];

                        btScalar dx = fabsf(x - px );
                        btScalar dy = fabsf(y - py );
                        btScalar dz = fabsf(z - pz );

                        if ( dx < normalepsilon && dy < normalepsilon && dz < normalepsilon )
                        {
                              // ok, it is close enough to the old one
                              // now let us see if it is further from the center of the point cloud than the one we already recorded.
                              // in which case we keep this one instead.

                              btScalar dist1 = GetDist(px,py,pz,center);
                              btScalar dist2 = GetDist(v[0],v[1],v[2],center);

                              if ( dist1 > dist2 )
                              {
                                    v[0] = px;
                                    v[1] = py;
                                    v[2] = pz;
                                    
                              }

                              break;
                        }
                  }

                  if ( j == vcount )
                  {
                        btVector3& dest = vertices[vcount];
                        dest[0] = px;
                        dest[1] = py;
                        dest[2] = pz;
                        vcount++;
                  }
                  m_vertexIndexMapping.push_back(j);
            }
      }

      // ok..now make sure we didn't prune so many vertices it is now invalid.
//    if ( 1 )
      {
            btScalar bmin[3] = {  FLT_MAX,  FLT_MAX,  FLT_MAX };
            btScalar bmax[3] = { -FLT_MAX, -FLT_MAX, -FLT_MAX };

            for (unsigned int i=0; i<vcount; i++)
            {
                  const btVector3& p = vertices[i];
                  for (int j=0; j<3; j++)
                  {
                        if ( p[j] < bmin[j] ) bmin[j] = p[j];
                        if ( p[j] > bmax[j] ) bmax[j] = p[j];
                  }
            }

            btScalar dx = bmax[0] - bmin[0];
            btScalar dy = bmax[1] - bmin[1];
            btScalar dz = bmax[2] - bmin[2];

            if ( dx < EPSILON || dy < EPSILON || dz < EPSILON || vcount < 3)
            {
                  btScalar cx = dx*btScalar(0.5) + bmin[0];
                  btScalar cy = dy*btScalar(0.5) + bmin[1];
                  btScalar cz = dz*btScalar(0.5) + bmin[2];

                  btScalar len = FLT_MAX;

                  if ( dx >= EPSILON && dx < len ) len = dx;
                  if ( dy >= EPSILON && dy < len ) len = dy;
                  if ( dz >= EPSILON && dz < len ) len = dz;

                  if ( len == FLT_MAX )
                  {
                        dx = dy = dz = btScalar(0.01); // one centimeter
                  }
                  else
                  {
                        if ( dx < EPSILON ) dx = len * btScalar(0.05); // 1/5th the shortest non-zero edge.
                        if ( dy < EPSILON ) dy = len * btScalar(0.05);
                        if ( dz < EPSILON ) dz = len * btScalar(0.05);
                  }

                  btScalar x1 = cx - dx;
                  btScalar x2 = cx + dx;

                  btScalar y1 = cy - dy;
                  btScalar y2 = cy + dy;

                  btScalar z1 = cz - dz;
                  btScalar z2 = cz + dz;

                  vcount = 0; // add box

                  addPoint(vcount,vertices,x1,y1,z1);
                  addPoint(vcount,vertices,x2,y1,z1);
                  addPoint(vcount,vertices,x2,y2,z1);
                  addPoint(vcount,vertices,x1,y2,z1);
                  addPoint(vcount,vertices,x1,y1,z2);
                  addPoint(vcount,vertices,x2,y1,z2);
                  addPoint(vcount,vertices,x2,y2,z2);
                  addPoint(vcount,vertices,x1,y2,z2);

                  return true;
            }
      }

      return true;
}


Generated by  Doxygen 1.6.0   Back to index