Exemple #1
0
bool
GrahamScan::PruneInterior()
{
  SearchPointVector res;

  /* the result is usually one more than the input vector - is that a
   bug? */
  res.reserve(size + 1);

  if (size < 3) {
    std::copy(raw_points.begin(), raw_points.end(), std::back_inserter(res));
    return false;
    // nothing to do
  }

  PartitionPoints();
  BuildHull();

  for (unsigned i = 0; i + 1 < lower_hull.size(); i++)
    res.push_back(*lower_hull[i]);

  for (int i = upper_hull.size() - 1; i >= 0; i--)
    res.push_back(*upper_hull[i]);

  if (res.size() == size)
    return false;

  raw_vector.swap(res);
  return true;
}
dgConvexHull3d::dgConvexHull3d(const double* const vertexCloud, int32_t strideInBytes, int32_t count, double distTol, int32_t maxVertexCount)
    :m_count (0)
    ,m_diag()
    ,m_aabbP0 (dgBigVector (double (0.0), double (0.0), double (0.0), double (0.0)))
    ,m_aabbP1 (dgBigVector (double (0.0), double (0.0), double (0.0), double (0.0)))
    ,m_points(count)
{
    BuildHull (vertexCloud, strideInBytes, count, distTol, maxVertexCount);
}
ConvexData::ConvexData(CustomGeometry* custom)
{
    const Vector<PODVector<CustomGeometryVertex> >& srcVertices = custom->GetVertices();
    PODVector<Vector3> vertices;

    for (unsigned i = 0; i < srcVertices.Size(); ++i)
    {
        for (unsigned j = 0; j < srcVertices[i].Size(); ++j)
            vertices.Push(srcVertices[i][j].position_);
    }

    BuildHull(vertices);
}
dgCollisionConvexHull::dgCollisionConvexHull(dgMemoryAllocator* const allocator, dgUnsigned32 signature, dgInt32 count, dgInt32 strideInBytes, dgFloat32 tolerance, const dgFloat32* const vertexArray)
	:dgCollisionConvex(allocator, signature, m_convexHullCollision)
	,m_faceCount (0)
	,m_supportTreeCount (0)
	,m_faceArray (NULL)
	,m_vertexToEdgeMapping(NULL)
	,m_supportTree (NULL)
{
	m_edgeCount = 0;
	m_vertexCount = 0;
	m_vertex = NULL;
	m_simplex = NULL;
	m_rtti |= dgCollisionConvexHull_RTTI;

	BuildHull (count, strideInBytes, tolerance, vertexArray);
}
Exemple #5
0
ConvexData::ConvexData(CustomGeometry* custom)
{
    PODVector<Vector3> vertices;
    unsigned numGeometries = custom->GetNumGeometries();
    
    for (unsigned i = 0; i < numGeometries; ++i)
    {
        Geometry* geom = custom->GetLodGeometry(i, 0);
        if (!geom)
        {
            LOGWARNING("Skipping null geometry for convex hull collision");
            continue;
        }
        
        const unsigned char* vertexData;
        const unsigned char* indexData;
        unsigned vertexSize;
        unsigned indexSize;
        unsigned elementMask;
        
        geom->GetRawData(vertexData, vertexSize, indexData, indexSize, elementMask);
        if (!vertexData)
        {
            LOGWARNING("Skipping geometry with no CPU-side geometry data for convex hull collision - no vertex data");
            continue;
        }
        
        unsigned vertexStart = geom->GetVertexStart();
        unsigned vertexCount = geom->GetVertexCount();
        
        // Copy vertex data
        for (unsigned j = 0; j < vertexCount; ++j)
        {
            const Vector3& v = *((const Vector3*)(&vertexData[(vertexStart + j) * vertexSize]));
            vertices.Push(v);
        }
    }
    
    BuildHull(vertices);
}
dgConvexHull4d::dgConvexHull4d (dgMemoryAllocator* const allocator, const dgBigVector* const vertexCloud, dgInt32 count, dgFloat32 distTol)
	:dgList<dgConvexHull4dTetraherum>(allocator), m_mark(0), m_count (0), m_diag(), m_points(count, allocator) 
{
	BuildHull (allocator, vertexCloud, count, distTol);
}
dgDelaunayTetrahedralization::dgDelaunayTetrahedralization(
    dgMemoryAllocator* const allocator, const dgFloat64* const vertexCloud,
    dgInt32 count, dgInt32 strideInByte, dgFloat64 distTol) :
    dgConvexHull4d(allocator)
{
#ifdef _WIN32
  dgUnsigned32 controlWorld = dgControlFP (0xffffffff, 0);
  dgControlFP(_PC_53, _MCW_PC);
#endif

  dgStack<dgBigVector> pool(count);

  dgBigVector* const points = &pool[0];
  dgInt32 stride = dgInt32(strideInByte / sizeof(dgFloat64));
  for (dgInt32 i = 0; i < count; i++)
  {
    volatile float x = float(vertexCloud[i * stride + 0]);
    volatile float y = float(vertexCloud[i * stride + 1]);
    volatile float z = float(vertexCloud[i * stride + 2]);
    points[i] = dgBigVector(x, y, z, x * x + y * y + z * z);
  }

  dgInt32 oldCount = count;
  BuildHull(allocator, &pool[0], count, distTol);
#if 1
//	if ((oldCount > m_count) && (m_count >= 4)) {
  if (oldCount > m_count)
  {
    // this is probably a regular convex solid, which will have a zero volume hull
    // add the rest of the points by incremental insertion with small perturbation
    dgInt32 hullCount = m_count;

    for (dgInt32 i = 0; i < count; i++)
    {
      bool inHull = false;
      const dgHullVector* const hullPoints = &m_points[0];
      for (dgInt32 j = 0; j < hullCount; j++)
      {
        if (hullPoints[j].m_index == i)
        {
          inHull = true;
          break;
        }
      }
      if (!inHull)
      {
        dgBigVector q(points[i]);
        dgInt32 index = AddVertex(q);
        if (index == -1)
        {
          q.m_x += dgFloat64(1.0e-3f);
          q.m_y += dgFloat64(1.0e-3f);
          q.m_z += dgFloat64(1.0e-3f);
          index = AddVertex(q);
          _ASSERTE(index != -1);
        }_ASSERTE(index != -1);
//				m_points[index] = points[i];
        m_points[index].m_index = i;
      }
    }
  }
#else
  if (oldCount > m_count)
  {
    // this is probably a regular convex solid, which will have a zero volume hull
    // perturbate a point and try again
    dgBigVector p (points[0]);
    points[0].m_x += dgFloat64 (1.0e-0f);
    points[0].m_y += dgFloat64 (1.0e-0f);
    points[0].m_z += dgFloat64 (1.0e-0f);
    points[0].m_w = points[0].m_x * points[0].m_x + points[0].m_y * points[0].m_y + points[0].m_z * points[0].m_z;
    BuildHull (allocator, &pool[0], oldCount, distTol);
    _ASSERTE (oldCount == m_count);
    // restore the old point
    //points[0].m_w = points[0].m_x * points[0].m_x + points[0].m_y * points[0].m_y + points[0].m_z * points[0].m_z;
  }
#endif

#ifdef _DEBUG
  SortVertexArray();
#endif

#ifdef _WIN32
  dgControlFP(controlWorld, _MCW_PC);
#endif
}