/// <summary> /// Add the mesh data to the correct side and calulate normals /// </summary> /// <param name="side"></param> /// <param name="vertex1"></param> /// <param name="vertex1Uv"></param> /// <param name="vertex2"></param> /// <param name="vertex2Uv"></param> /// <param name="vertex3"></param> /// <param name="vertex3Uv"></param> /// <param name="shareVertices"></param> private void AddTrianglesNormalAndUvs(MeshSide side, Vector3 vertex1, Vector3?normal1, Vector2 uv1, Vector3 vertex2, Vector3?normal2, Vector2 uv2, Vector3 vertex3, Vector3?normal3, Vector2 uv3, bool shareVertices, bool addFirst) { if (side == MeshSide.Positive) { AddTrianglesNormalsAndUvs(ref _positiveSideVertices, ref _positiveSideTriangles, ref _positiveSideNormals, ref _positiveSideUvs, vertex1, normal1, uv1, vertex2, normal2, uv2, vertex3, normal3, uv3, shareVertices, addFirst); } else { AddTrianglesNormalsAndUvs(ref _negativeSideVertices, ref _negativeSideTriangles, ref _negativeSideNormals, ref _negativeSideUvs, vertex1, normal1, uv1, vertex2, normal2, uv2, vertex3, normal3, uv3, shareVertices, addFirst); } }
/// <summary> /// Setup the mesh object for the specified side /// </summary> /// <param name="side"></param> private void SetMeshData(MeshSide side) { if (side == MeshSide.Positive) { _positiveSideMesh.vertices = _positiveSideVertices.ToArray(); _positiveSideMesh.triangles = _positiveSideTriangles.ToArray(); _positiveSideMesh.normals = _positiveSideNormals.ToArray(); _positiveSideMesh.uv = _positiveSideUvs.ToArray(); } else { _negativeSideMesh.vertices = _negativeSideVertices.ToArray(); _negativeSideMesh.triangles = _negativeSideTriangles.ToArray(); _negativeSideMesh.normals = _negativeSideNormals.ToArray(); _negativeSideMesh.uv = _negativeSideUvs.ToArray(); } }
/// <summary> /// Compute the positive and negative meshes based on the plane and mesh /// </summary> private void ComputeNewMeshes() { int[] meshTriangles = _mesh.triangles; Vector3[] meshVerts = _mesh.vertices; Vector3[] meshNormals = _mesh.normals; Vector2[] meshUvs = _mesh.uv; for (int i = 0; i < meshTriangles.Length; i += 3) { //We need the verts in order so that we know which way to wind our new mesh triangles. Vector3 vert1 = meshVerts[meshTriangles[i]]; int vert1Index = Array.IndexOf(meshVerts, vert1); Vector2 uv1 = meshUvs[vert1Index]; Vector3 normal1 = meshNormals[vert1Index]; bool vert1Side = _plane.GetSide(vert1); Vector3 vert2 = meshVerts[meshTriangles[i + 1]]; int vert2Index = Array.IndexOf(meshVerts, vert2); Vector2 uv2 = meshUvs[vert2Index]; Vector3 normal2 = meshNormals[vert2Index]; bool vert2Side = _plane.GetSide(vert2); Vector3 vert3 = meshVerts[meshTriangles[i + 2]]; bool vert3Side = _plane.GetSide(vert3); int vert3Index = Array.IndexOf(meshVerts, vert3); Vector3 normal3 = meshNormals[vert3Index]; Vector2 uv3 = meshUvs[vert3Index]; //All verts are on the same side if (vert1Side == vert2Side && vert2Side == vert3Side) { //Add the relevant triangle MeshSide side = (vert1Side) ? MeshSide.Positive : MeshSide.Negative; AddTrianglesNormalAndUvs(side, vert1, normal1, uv1, vert2, normal2, uv2, vert3, normal3, uv3, true, false); } else { //we need the two points where the plane intersects the triangle. Vector3 intersection1; Vector3 intersection2; Vector2 intersection1Uv; Vector2 intersection2Uv; MeshSide side1 = (vert1Side) ? MeshSide.Positive : MeshSide.Negative; MeshSide side2 = (vert1Side) ? MeshSide.Negative : MeshSide.Positive; //vert 1 and 2 are on the same side if (vert1Side == vert2Side) { //Cast a ray from v2 to v3 and from v3 to v1 to get the intersections intersection1 = GetRayPlaneIntersectionPointAndUv(vert2, uv2, vert3, uv3, out intersection1Uv); intersection2 = GetRayPlaneIntersectionPointAndUv(vert3, uv3, vert1, uv1, out intersection2Uv); //Add the positive or negative triangles AddTrianglesNormalAndUvs(side1, vert1, null, uv1, vert2, null, uv2, intersection1, null, intersection1Uv, _useSharedVertices, false); AddTrianglesNormalAndUvs(side1, vert1, null, uv1, intersection1, null, intersection1Uv, intersection2, null, intersection2Uv, _useSharedVertices, false); AddTrianglesNormalAndUvs(side2, intersection1, null, intersection1Uv, vert3, null, uv3, intersection2, null, intersection2Uv, _useSharedVertices, false); } //vert 1 and 3 are on the same side else if (vert1Side == vert3Side) { //Cast a ray from v1 to v2 and from v2 to v3 to get the intersections intersection1 = GetRayPlaneIntersectionPointAndUv(vert1, uv1, vert2, uv2, out intersection1Uv); intersection2 = GetRayPlaneIntersectionPointAndUv(vert2, uv2, vert3, uv3, out intersection2Uv); //Add the positive triangles AddTrianglesNormalAndUvs(side1, vert1, null, uv1, intersection1, null, intersection1Uv, vert3, null, uv3, _useSharedVertices, false); AddTrianglesNormalAndUvs(side1, intersection1, null, intersection1Uv, intersection2, null, intersection2Uv, vert3, null, uv3, _useSharedVertices, false); AddTrianglesNormalAndUvs(side2, intersection1, null, intersection1Uv, vert2, null, uv2, intersection2, null, intersection2Uv, _useSharedVertices, false); } //Vert1 is alone else { //Cast a ray from v1 to v2 and from v1 to v3 to get the intersections intersection1 = GetRayPlaneIntersectionPointAndUv(vert1, uv1, vert2, uv2, out intersection1Uv); intersection2 = GetRayPlaneIntersectionPointAndUv(vert1, uv1, vert3, uv3, out intersection2Uv); AddTrianglesNormalAndUvs(side1, vert1, null, uv1, intersection1, null, intersection1Uv, intersection2, null, intersection2Uv, _useSharedVertices, false); AddTrianglesNormalAndUvs(side2, intersection1, null, intersection1Uv, vert2, null, uv2, vert3, null, uv3, _useSharedVertices, false); AddTrianglesNormalAndUvs(side2, intersection1, null, intersection1Uv, vert3, null, uv3, intersection2, null, intersection2Uv, _useSharedVertices, false); } //Add the newly created points on the plane. _pointsAlongPlane.Add(intersection1); _pointsAlongPlane.Add(intersection2); } } //If the object is solid, join the new points along the plane otherwise do the reverse winding if (_isSolid) { JoinPointsAlongPlane(); } else if (_createReverseTriangleWindings) { AddReverseTriangleWinding(); } if (_smoothVertices) { SmoothVertices(); } }