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); }
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 }