private int ClipAgainstEdge(Edge edgeA, Edge edgeB, List <EdgeClip> clipedges) { int intersected = 0; int[] clipstatus = new int[3]; EdgeClip[] alledges = new EdgeClip[3]; for (int i = 0; i < 3; ++i) { alledges[i] = new EdgeClip(edgeA, edgeB.Tri.Edges[i]); clipstatus[i] = alledges[i].Clip(); if ((clipstatus[i] & EdgeClip.COINCIDENT) != 0) { mCoincident = alledges[i].Clipped; } else if ((clipstatus[i] & EdgeClip.INTERSECTING) != 0) { if (clipstatus[i] == EdgeClip.INTERSECTING) { clipedges.Insert(0, alledges[i]); } else { clipedges.Add(alledges[i]); } ++intersected; } } return(intersected); }
/* * returns INVALID if intersections points are the same * returns INSIDE if clipped triangle inside clipper triangle * returns CLIPPED if clipped triangles were generated */ ClipResult ClipTriangles(Triangle triA, Triangle triB, EdgeClip edge1, EdgeClip edge2, List <Triangle> clipped) { Vector3 temp1; Vector3 temp2; Triangle tri; const int ISECTA = 1; const int ISECTB = 2; const int ISECTC = 4; int mask = ISECTA | ISECTB | ISECTC; Vector3 va; Vector3 vb; Vector3 vc; Vector3 isect1 = edge1.IntersectionPoint; Vector3 isect2 = edge2.IntersectionPoint; if (edge1.ClippedEnd == edge2.ClippedStart) { va = triB.GetVertex(edge1.ClippedEnd); vb = triB.GetVertex(edge1.ClippedStart); vc = triB.GetVertex(edge2.ClippedEnd); } else // edge1.EdgeBStart != edge2.EdgeBEnd { va = triB.GetVertex(edge1.ClippedStart); vb = triB.GetVertex(edge1.ClippedEnd); vc = triB.GetVertex(edge2.ClippedStart); } temp1 = isect1 - isect2; if (temp1.sqrMagnitude <= EPSILON) { return(ClipResult.OUTSIDE); } temp1 = va - isect1; temp2 = va - isect2; if ((temp1.sqrMagnitude > EPSILON) && (temp2.sqrMagnitude > EPSILON)) { mask &= ~ISECTA; } temp1 = vb - isect1; temp2 = vb - isect2; if ((temp1.sqrMagnitude > EPSILON) && (temp2.sqrMagnitude > EPSILON)) { mask &= ~ISECTB; } temp1 = vc - isect1; temp2 = vc - isect2; if ((temp1.sqrMagnitude > EPSILON) && (temp2.sqrMagnitude > EPSILON)) { mask &= ~ISECTC; } switch (mask) { case ISECTA: tri = new Triangle(vb, isect1, isect2); if (!triA.Contains(tri)) { clipped.Add(tri); } tri = new Triangle(vc, isect1, isect2); if (!triA.Contains(tri)) { clipped.Add(tri); } return(ClipResult.CLIPPED); case ISECTB: tri = new Triangle(va, isect1, isect2); if (!triA.Contains(tri)) { clipped.Add(tri); } tri = new Triangle(vc, isect1, isect2); if (!triA.Contains(tri)) { clipped.Add(tri); } return(ClipResult.CLIPPED); case ISECTC: tri = new Triangle(va, isect1, isect2); if (!triA.Contains(tri)) { clipped.Add(tri); } tri = new Triangle(vb, isect1, isect2); if (!triA.Contains(tri)) { clipped.Add(tri); } return(ClipResult.CLIPPED); case ISECTA | ISECTB: return((triA.Contains(vc) > 0) ? ClipResult.INSIDE : ClipResult.COINCIDENT); case ISECTA | ISECTC: return((triA.Contains(vb) > 0) ? ClipResult.INSIDE : ClipResult.COINCIDENT); case ISECTB | ISECTC: return((triA.Contains(va) > 0) ? ClipResult.INSIDE : ClipResult.COINCIDENT); case 0: tri = new Triangle(va, isect1, isect2); if (!triA.Contains(tri)) { clipped.Add(tri); } tri = new Triangle(vb, isect1, isect2); if (!triA.Contains(tri)) { clipped.Add(tri); } tri = new Triangle(vb, vc, isect2); if (!triA.Contains(tri)) { clipped.Add(tri); } return(ClipResult.CLIPPED); } return(ClipResult.OUTSIDE); }