//---------------------------------------------------------------------------- ConvexClipper::ConvexClipper (const ConvexPolyhedron& rkPoly, Real fEpsilon) { m_fEpsilon = fEpsilon; const vector<Vector3>& rakPoint = rkPoly.GetPoints(); int iVQuantity = rkPoly.GetVQuantity(); m_akVertex.resize(iVQuantity); for (int iV = 0; iV < iVQuantity; iV++) m_akVertex[iV].m_kPoint = rakPoint[iV]; int iEQuantity = rkPoly.GetEQuantity(); m_akEdge.resize(iEQuantity); for (int iE = 0; iE < iEQuantity; iE++) { const MTEdge& rkE = rkPoly.GetEdge(iE); for (int i = 0; i < 2; i++) { m_akEdge[iE].m_aiVertex[i] = rkPoly.GetVLabel(rkE.GetVertex(i)); m_akEdge[iE].m_aiFace[i] = rkE.GetTriangle(i); } } int iTQuantity = rkPoly.GetTQuantity(); m_akFace.resize(iTQuantity); for (int iT = 0; iT < iTQuantity; iT++) { m_akFace[iT].m_kPlane = rkPoly.GetPlane(iT); const MTTriangle& rkT = rkPoly.GetTriangle(iT); for (int i = 0; i < 3; i++) m_akFace[iT].m_akEdge.insert(rkT.GetEdge(i)); } }
ConvexClipper<Real>::ConvexClipper (const ConvexPolyhedron<Real>& polyhedron, Real epsilon) : mEpsilon(epsilon) { const std::vector<Vector3<Real> >& points = polyhedron.GetPoints(); int numVertices = polyhedron.GetNumVertices(); mVertices.resize(numVertices); for (int v = 0; v < numVertices; ++v) { mVertices[v].Point = points[v]; } int numEdges = polyhedron.GetNumEdges(); mEdges.resize(numEdges); for (int e = 0; e < numEdges; ++e) { const MTEdge& edge = polyhedron.GetEdge(e); for (int i = 0; i < 2; ++i) { mEdges[e].Vertex[i] = polyhedron.GetVLabel(edge.GetVertex(i)); mEdges[e].Face[i] = edge.GetTriangle(i); } } int numTriangles = polyhedron.GetNumTriangles(); mFaces.resize(numTriangles); for (int t = 0; t < numTriangles; ++t) { mFaces[t].Plane = polyhedron.GetPlane(t); const MTTriangle& triangle = polyhedron.GetTriangle(t); for (int i = 0; i < 3; ++i) { mFaces[t].Edges.insert(triangle.GetEdge(i)); } } }
//---------------------------------------------------------------------------- void ConvexPolyhedron::CreateEggShape (const Vector3& rkCenter, Real fX0, Real fX1, Real fY0, Real fY1, Real fZ0, Real fZ1, int iMaxSteps, ConvexPolyhedron& rkEgg) { assert( fX0 > 0.0f && fX1 > 0.0f ); assert( fY0 > 0.0f && fY1 > 0.0f ); assert( fZ0 > 0.0f && fZ1 > 0.0f ); assert( iMaxSteps >= 0 ); // Start with an octahedron whose 6 vertices are (-x0,0,0), (x1,0,0), // (0,-y0,0), (0,y1,0), (0,0,-z0), (0,0,z1). The center point will be // added later. vector<Vector3> akPoint(6); akPoint[0] = Vector3(-fX0,0.0f,0.0f); akPoint[1] = Vector3(fX1,0.0f,0.0f); akPoint[2] = Vector3(0.0f,-fY0,0.0f); akPoint[3] = Vector3(0.0f,fY1,0.0f); akPoint[4] = Vector3(0.0f,0.0f,-fZ0); akPoint[5] = Vector3(0.0f,0.0f,fZ1); vector<int> aiConnect(24); aiConnect[ 0] = 1; aiConnect[ 1] = 3; aiConnect[ 2] = 5; aiConnect[ 3] = 3; aiConnect[ 4] = 0; aiConnect[ 5] = 5; aiConnect[ 6] = 0; aiConnect[ 7] = 2; aiConnect[ 8] = 5; aiConnect[ 9] = 2; aiConnect[10] = 1; aiConnect[11] = 5; aiConnect[12] = 3; aiConnect[13] = 1; aiConnect[14] = 4; aiConnect[15] = 0; aiConnect[16] = 3; aiConnect[17] = 4; aiConnect[18] = 2; aiConnect[19] = 0; aiConnect[20] = 4; aiConnect[21] = 1; aiConnect[22] = 2; aiConnect[23] = 4; rkEgg.InitialELabel() = 0; rkEgg.Create(akPoint,aiConnect); // Subdivide the triangles. The midpoints of the edges are computed. // The triangle is replaced by four sub triangles using the original 3 // vertices and the 3 new edge midpoints. int i; for (int iStep = 1; iStep <= iMaxSteps; iStep++) { int iVQuantity = rkEgg.GetVQuantity(); int iEQuantity = rkEgg.GetEQuantity(); int iTQuantity = rkEgg.GetTQuantity(); // compute lifted edge midpoints for (i = 0; i < iEQuantity; i++) { // get edge const MTEdge& rkE = rkEgg.GetEdge(i); int iV0 = rkEgg.GetVLabel(rkE.GetVertex(0)); int iV1 = rkEgg.GetVLabel(rkE.GetVertex(1)); // compute "lifted" centroid to points Vector3 kCen = rkEgg.Point(iV0)+rkEgg.Point(iV1); Real fXR = (kCen.x > 0.0f ? kCen.x/fX1 : kCen.x/fX0); Real fYR = (kCen.y > 0.0f ? kCen.y/fY1 : kCen.y/fY0); Real fZR = (kCen.z > 0.0f ? kCen.z/fZ1 : kCen.z/fZ0); kCen *= Math::InvSqrt(fXR*fXR+fYR*fYR+fZR*fZR); // Add the point to the array. Store the point index in the edge // label for support in adding new triangles. rkEgg.ELabel(i) = iVQuantity++; rkEgg.AddPoint(kCen); } // Add the new triangles and remove the old triangle. The removal // in slot i will cause the last added triangle to be moved to that // slot. This side effect will not interfere with the iteration // and removal of the triangles. for (i = 0; i < iTQuantity; i++) { const MTTriangle& rkT = rkEgg.GetTriangle(i); int iV0 = rkEgg.GetVLabel(rkT.GetVertex(0)); int iV1 = rkEgg.GetVLabel(rkT.GetVertex(1)); int iV2 = rkEgg.GetVLabel(rkT.GetVertex(2)); int iV01 = rkEgg.GetELabel(rkT.GetEdge(0)); int iV12 = rkEgg.GetELabel(rkT.GetEdge(1)); int iV20 = rkEgg.GetELabel(rkT.GetEdge(2)); rkEgg.Insert(iV0,iV01,iV20); rkEgg.Insert(iV01,iV1,iV12); rkEgg.Insert(iV20,iV12,iV2); rkEgg.Insert(iV01,iV12,iV20); rkEgg.Remove(iV0,iV1,iV2); } } // add center for (i = 0; i < (int)rkEgg.m_akPoint.size(); i++) rkEgg.m_akPoint[i] += rkCenter; rkEgg.UpdatePlanes(); }