// Split this Face with given Plane public bool Split(Plane inPlane, out Face outFront, out Face outBack) { outFront = new Face(); outBack = new Face(); float[] distance = new float[vertices.Length + 1]; EPlaneSide[] side = new EPlaneSide[vertices.Length + 1]; for (int i = 0; i < vertices.Length; ++i) { distance[i] = inPlane.GetDistanceToPoint(vertices[i]); side[i] = Side(inPlane, vertices[i]); } distance[vertices.Length] = distance[0]; side[vertices.Length] = side[0]; for (int i = 0; i < vertices.Length; ++i) { // if we lie on plane, add them to both if (side[i] == EPlaneSide.Side_Planar) { outFront.AddVertex(vertices[i], uv[i]); outBack.AddVertex(vertices[i], uv[i]); // nothing todo with this vertex continue; } // if we are on the front, add it to front face if (side[i] == EPlaneSide.Side_Front) { outFront.AddVertex(vertices[i], uv[i]); } // if we are on the back, add it to the back side else if (side[i] == EPlaneSide.Side_Back) { outBack.AddVertex(vertices[i], uv[i]); } // check if the next vertex is planar or on the same side, then we do not split if (side[i + 1] == EPlaneSide.Side_Planar || side[i] == side[i + 1]) { continue; } // create split point Vector3 nextVector = vertices[(i + 1) % vertices.Length]; Vector2 nextUV = uv[(i + 1) % uv.Length]; Vector3 newVector, newUV; // if we were on the front if (side[i] == EPlaneSide.Side_Front) { float t = distance[i] / (distance[i] - distance[i + 1]); newVector = vertices[i] + t * (nextVector - vertices[i]); newUV = uv[i] + t * (nextUV - uv[i]); } else // back side... { float t = distance[i + 1] / (distance[i + 1] - distance[i]); newVector = nextVector + t * (vertices[i] - nextVector); newUV = nextUV + t * (uv[i] - nextUV); } // split points are added // add to front outFront.AddVertex(newVector, newUV); // add to back outBack.AddVertex(newVector, newUV); } // Debugging checks if (outFront.vertices.Length < 3 || outBack.vertices.Length < 3) { Debug.Log("Degenerate Faces"); } // todo... outFront.material = material; // outBack.material = material; return(true); }
public bool Merge(Face inOther, out Face outFace) { outFace = null; // do not share same material if (material != inOther.material || vertices.Length < 1) { return(false); } Vector3 p1, p2; Vector3 p3, p4; int i = 0, j = 0; // just to fix compiler error p1 = vertices[0]; p2 = vertices[1 % vertices.Length]; // check if we share an edge for (i = 0; i < vertices.Length; ++i) { // get edge p1 = vertices[i]; p2 = vertices[(i + 1) % vertices.Length]; // go through all edges of other face for (j = 0; j < inOther.vertices.Length; ++j) { // get other edge p3 = inOther.vertices[j]; p4 = inOther.vertices[(j + 1) % inOther.vertices.Length]; // check if we are sharing an edge if (p1.Equals(p4) && p2.Equals(p3)) { break; } } // found edge if (j < inOther.vertices.Length) { break; } } // no edge found if (i == vertices.Length) { return(false); } // ... Vector3 back = vertices[(i + vertices.Length - 1) % vertices.Length]; Vector3 delta = p1 - back; Vector3 normal = Vector3.Cross(GetPlane().normal, delta); normal.Normalize(); back = inOther.vertices[(j + 2) % inOther.vertices.Length]; delta = back - p1; float dot = Vector3.Dot(delta, normal); // not a convex polygon if (dot > BooleanSettings.Epsilonf) { return(false); } // if they are co linear bool keep1 = (dot < -BooleanSettings.Epsilonf); // ... back = vertices[(i + 2) % vertices.Length]; delta = back - p2; normal = Vector3.Cross(GetPlane().normal, delta); normal.Normalize(); back = inOther.vertices[(j + inOther.vertices.Length - 1) % inOther.vertices.Length]; delta = back - p2; dot = Vector3.Dot(delta, normal); // not convex if (dot > BooleanSettings.Epsilonf) { return(false); } bool keep2 = (dot < -BooleanSettings.Epsilonf); bool keep = false; // create out face outFace = new Face(); outFace.flags = flags; outFace.material = material; // copy vertices from this for (int k = (i + 1) % vertices.Length; k != i; k = (k + 1) % vertices.Length) { if (!keep && k == (i + 1) % vertices.Length && !keep2) { continue; } // copy vector outFace.AddVertex(vertices[k], uv[k]); } // copy vertices from other for (int k = (j + 1) % inOther.vertices.Length; k != j; k = (k + 1) % inOther.vertices.Length) { if (!keep && k == (j + 1) % inOther.vertices.Length && !keep1) { continue; } outFace.AddVertex(inOther.vertices[k], inOther.uv[k]); } return(true); }