public override void OnInspectorGUI() { DrawDefaultInspector(); //base.OnInspectorGUI(); CustomPlane plane = target as CustomPlane; EditorGUILayout.Space(); EditorGUILayout.Space(); if (GUILayout.Button("Build Object")) { plane.GeneratePlane(); } if (GUILayout.Button("Generate Primary Road")) { plane.GeneratePrimaryRoad(); } if (GUILayout.Button("Generate Second Primary Road")) { plane.GenerateSecondPrimaryRoad(); } if (GUILayout.Button("Destroy Roads")) { plane.DestroyRoads(); } if (GUILayout.Button("Generate Full Network")) { plane.GenerateFullNetwork(); } if (GUILayout.Button("Test Code")) { plane.TestCode(); } }
void Destroy() { if (_plane != null) { _plane.Destroy(); _plane = null; } endAlpha = ResetEndAlpha; transformList.Clear(); }
void GenerateFogOfWar(GameEvent e) { if (e.type == GameEvent.GENERATE_FOW) { Events.instance.RemoveListener <GameEvent>(GenerateFogOfWar); _plane = new CustomPlane(e.width * e.gridSize, e.height * e.gridSize, (e.width * 8 / 512)); _mesh.vertices = _plane.getVertices(); _mesh.triangles = _plane.getTriangles(); _mesh.uv = _plane.getUVs(); _mesh.colors32 = _plane.getColors(); gameObject.transform.Translate(new Vector3(-_plane.width / 2, 0, -_plane.height / 2)); MeshCollider collider = gameObject.AddComponent <MeshCollider>(); collider.sharedMesh = _mesh; _lastExploredIndex = new TVec2 <int>(-1, -1); } }
// Use this for initialization void Start() { gameObject.AddComponent <MeshFilter>(); gameObject.AddComponent <MeshRenderer>(); Mesh mesh = GetComponent <MeshFilter>().mesh; mesh.Clear(); CustomPlane plane = new CustomPlane(512, 512, 16, 200, 0); mesh.vertices = plane.getVertices(); mesh.triangles = plane.getTriangles(); mesh.uv = plane.getUVs(); mesh.colors32 = plane.getColors(); Renderer renderer = gameObject.GetComponent <Renderer>(); Shader shader = Shader.Find("Custom/VertexAlphaFow"); renderer.material = new Material(shader); }
public void GenerateFOW(int width, int height, int gridSize, float yPos) { _mesh = GetComponent <MeshFilter>().mesh; _mesh.Clear(); _plane = new CustomPlane(width * gridSize, height * gridSize, gridSize, startAlpha, endAlpha); _mesh.vertices = _plane.getVertices(); _mesh.triangles = _plane.getTriangles(); _mesh.uv = _plane.getUVs(); _mesh.colors32 = _plane.getColors(); transform.position = new Vector3(0.0f, yPos, 0.0f); // MeshCollider collider = gameObject.AddComponent<MeshCollider>(); // collider.sharedMesh = _mesh; _lastExploredIndex = new TVec2 <int>(-1, -1); this.rayHeight = yPos * 2; canUpdate = true; }
public void GenerateNavFloor(int width, int height, int gridSize) { _meshFilter = gameObject.AddComponent <MeshFilter>(); _meshFilter.mesh.Clear(); CustomPlane plane = new CustomPlane(width, height, gridSize, 255, 0); _meshFilter.mesh.vertices = plane.getVertices(); _meshFilter.mesh.triangles = plane.getTriangles(); _meshFilter.mesh.uv = plane.getUVs(); _meshFilter.mesh.colors32 = plane.getColors(); _meshFilter.mesh.RecalculateNormals(); BoxCollider collider = gameObject.AddComponent <BoxCollider>(); collider.material.dynamicFriction = 1f; collider.material.staticFriction = 1f; gameObject.transform.position = new Vector3(0.0f, 5.0f, 0.0f); }
// Slice mesh along plane intersection public static void SliceMesh(GameObject obj, CustomPlane plane, bool isConvex) { // original GameObject data Transform objTransform = obj.transform; Mesh objMesh = obj.GetComponent<MeshFilter>().mesh; Vector3[] meshVerts = objMesh.vertices; int[] meshTris = objMesh.triangles; Vector2[] meshUVs = objMesh.uv; // Slice mesh data slice1Verts = new List<Vector3>(); slice2Verts = new List<Vector3>(); slice1Tris = new List<int>(); slice2Tris = new List<int>(); slice1UVs = new List<Vector2>(); slice2UVs = new List<Vector2>(); lineLoop = new List<Line>(); // Loop through triangles for(int i = 0; i < meshTris.Length / 3; i++) { // Define triangle Vector3[] triVertsLocal = new Vector3[3]; Vector3[] triVertsWorld = new Vector3[3]; Vector2[] triUVs = new Vector2[3]; for(int j = 0; j < 3; j++) { int meshIndexor = (i + 1) * 3 - (3 - j); triVertsLocal[j] = meshVerts[meshTris[meshIndexor]]; // local model space vertices triVertsWorld[j] = objTransform.TransformPoint(triVertsLocal[j]); // world space vertices triUVs[j] = meshUVs[meshTris[meshIndexor]]; // original uv coordinates } // Side test: (0) = intersecting plane; (+) = above plane; (-) = below plane; float vert1Side = plane.GetSide(triVertsWorld[0]); float vert2Side = plane.GetSide(triVertsWorld[1]); float vert3Side = plane.GetSide(triVertsWorld[2]); // assign triangles that do not intersect plane if(vert1Side > 0 && vert2Side > 0 && vert3Side > 0) { // Slice 1 for(int j = 0; j < triVertsLocal.Length; j++) { slice1Verts.Add(triVertsLocal[j]); slice1Tris.Add(slice1Verts.Count - 1); slice1UVs.Add(triUVs[j]); } } else if(vert1Side < 0 && vert2Side < 0 && vert3Side < 0) { // Slice 2 for(int j = 0; j < triVertsLocal.Length; j++) { slice2Verts.Add(triVertsLocal[j]); slice2Tris.Add(slice2Verts.Count - 1); slice2UVs.Add(triUVs[j]); } } else if(vert1Side == 0 || vert2Side == 0 || vert3Side == 0) { Debug.Log ("Point-Plane Intersection"); return; } else { // Intersecting Triangles Vector3[] slicedTriVerts = new Vector3[5]; Vector2[] slicedTriUVs = new Vector2[5]; Vector3[] triVertsWorld2 = new Vector3[3]; int[] vertOrder; // triangle vertex-order CW vs. CCW if(vert1Side * vert2Side > 0) { int[] triOrder = {2,0,1}; for(int j = 0; j < triOrder.Length; j++) { slicedTriVerts[j] = triVertsLocal[triOrder[j]]; slicedTriUVs[j] = triUVs[triOrder[j]]; triVertsWorld2[j] = triVertsWorld[triOrder[j]]; } vertOrder = vertOrderCW; } else if(vert1Side * vert3Side > 0) { int[] triOrder = {1,0,2}; for(int j = 0; j < triOrder.Length; j++) { slicedTriVerts[j] = triVertsLocal[triOrder[j]]; slicedTriUVs[j] = triUVs[triOrder[j]]; triVertsWorld2[j] = triVertsWorld[triOrder[j]]; } vertOrder = vertOrderCCW; } else { int[] triOrder = {0,1,2}; for(int j = 0; j < triOrder.Length; j++) { slicedTriVerts[j] = triVertsLocal[triOrder[j]]; slicedTriUVs[j] = triUVs[triOrder[j]]; triVertsWorld2[j] = triVertsWorld[triOrder[j]]; } vertOrder = vertOrderCW; } // Points of Intersection Vector3 poi1 = plane.VectorPlanePOI(triVertsWorld2[0], (triVertsWorld2[1] - triVertsWorld2[0]).normalized); Vector3 poi2 = plane.VectorPlanePOI(triVertsWorld2[0], (triVertsWorld2[2] - triVertsWorld2[0]).normalized); slicedTriVerts[3] = objTransform.InverseTransformPoint(poi1); slicedTriVerts[4] = objTransform.InverseTransformPoint(poi2); lineLoop.Add(new Line(slicedTriVerts[3], slicedTriVerts[4], poi1, poi2)); // POI UVs float t1 = Vector3.Distance(slicedTriVerts[0], slicedTriVerts[3]) / Vector3.Distance(slicedTriVerts[0], slicedTriVerts[1]); float t2 = Vector3.Distance(slicedTriVerts[0], slicedTriVerts[4]) / Vector3.Distance(slicedTriVerts[0], slicedTriVerts[2]); slicedTriUVs[3] = Vector2.Lerp(slicedTriUVs[0], slicedTriUVs[1], t1); slicedTriUVs[4] = Vector2.Lerp(slicedTriUVs[0], slicedTriUVs[2], t2); // Add bisected triangle to slice respectively if(plane.GetSide(triVertsWorld2[0]) > 0) { // Slice 1 for(int j = 0; j < 3; j++) { slice1Verts.Add(slicedTriVerts[vertOrder[j]]); slice1Tris.Add(slice1Verts.Count - 1); slice1UVs.Add(slicedTriUVs[vertOrder[j]]); } // Slice 2 for(int j = 3; j < 9; j++) { slice2Verts.Add(slicedTriVerts[vertOrder[j]]); slice2Tris.Add(slice2Verts.Count - 1); slice2UVs.Add(slicedTriUVs[vertOrder[j]]); } } else { // Slice 2 for(int j = 0; j < 3; j++) { slice2Verts.Add(slicedTriVerts[vertOrder[j]]); slice2Tris.Add(slice2Verts.Count - 1); slice2UVs.Add(slicedTriUVs[vertOrder[j]]); } // Slice 1 for(int j = 3; j < 9; j++) { slice1Verts.Add(slicedTriVerts[vertOrder[j]]); slice1Tris.Add(slice1Verts.Count - 1); slice1UVs.Add(slicedTriUVs[vertOrder[j]]); } } } } if(lineLoop.Count > 0) { // Fill convex mesh if(isConvex) { Vector3 normal = plane.normal; do { Polygon polygon = new Polygon(lineLoop, normal); Vector3 polygonNormal = (polygon.isClockWise) ? normal : -normal; TriangulatePolygon(polygon.edges, polygonNormal, polygon.isClockWise); } while(lineLoop.Count != 0); } // Build Meshes if(slice1Verts.Count > 0) { BuildSlice(obj, objTransform, slice1Verts.ToArray(), slice1Tris.ToArray(), slice1UVs.ToArray()); } if(slice2Verts.Count > 0) { BuildSlice(obj, objTransform, slice2Verts.ToArray(), slice2Tris.ToArray(), slice2UVs.ToArray()); } // Delete original GameObject.Destroy(obj); } }
private void resetLayout() { for (int i = 1; i < this.planes.Length; i++) { Destroy(this.planes[i].planeRenderer); } CustomPlane[] tmp = new CustomPlane[1]; tmp[0] = this.planes[0]; this.planes = tmp; }
void OnGUI() { Vector2 winSize = GetMainGameViewSize(); GUILayout.BeginVertical("box"); //planesListScrollPosition = GUI.BeginScrollView(new Rect(0, 0, 110, 100), planesListScrollPosition, new Rect(0, 0, 80, this.planes.Length * 32)); if (GUILayout.Button("Add Layer", new GUILayoutOption[0])) { CustomPlane[] newPlaneList = new CustomPlane[this.planes.Length+1]; for (int i = 0; i < this.planes.Length;i++) { newPlaneList[i] = this.planes[i]; } //Plane tmpPlane = new Plane(new Vector3(1, 1, 0), -this.planes.Length); //Renderer tmpRenderer = new Renderer(); //tmpRenderer.gameObject = tmpPlane; //tmpRenderer. newPlaneList[this.planes.Length] = new CustomPlane((Renderer) Instantiate(planeRenderer), this.planes.Length); this.planes = newPlaneList; } if (GUILayout.Button("Background", new GUILayoutOption[0])){ this.selectedPlane = 0; } for (int i = 1; i < this.planes.Length; i++) { if (GUILayout.Button((i == this.selectedPlane? "-->" : "") + "Layer #" + i.ToString(), new GUILayoutOption[0])){ this.selectedPlane = i; } } //GUI.EndScrollView(); GUILayout.EndVertical(); if (this.selectedPlane > 0) { //textureListScrollPosition = GUI.BeginScrollView(new Rect(0, 100, 100, 200), textureListScrollPosition, new Rect(0, 0, 80, this.textureFiles.Length * 32)); if (GUILayout.Button("Delete Layer", new GUILayoutOption[0])) { Destroy(this.planes[this.selectedPlane].planeRenderer); CustomPlane[] tmpPlanes = new CustomPlane[this.planes.Length-1]; for (int i = 0; i < this.selectedPlane; i++) { tmpPlanes[i] = this.planes[i]; } for (int i = this.selectedPlane+1; i < this.planes.Length; i++) { tmpPlanes[i-1] = this.planes[i]; } this.planes = tmpPlanes; this.selectedPlane = 0; return; } GUILayout.BeginVertical("box"); foreach(FileInfo file in this.textureFiles) { if (GUILayout.Button(file.Name, new GUILayoutOption[0])) { this.planes[this.selectedPlane].updateTexture(file.FullName); //newMaterial.mainTexture = texture; //newMaterial.SetTextureScale("_MainTex", new Vector2(3F, 3F)); //this.usedTexture = texture; } } //GUI.EndScrollView(); GUILayout.EndVertical(); float newWidth = GUI.HorizontalScrollbar(new Rect(0, winSize.y-35, winSize.x-35, winSize.y-55), this.planes[this.selectedPlane].getWidth(), 1, 1, 10); float newHeight = GUI.VerticalScrollbar(new Rect(winSize.x-15, 0, winSize.x, winSize.y-55), this.planes[this.selectedPlane].getHeight(), 1, 1, 10); this.planes[this.selectedPlane].resize(newWidth, newHeight); GUILayout.Label(newWidth.ToString() +"x" + newHeight.ToString(), new GUILayoutOption[0]); } if (this.selectedPlane == 0) { if(GUI.Button(new Rect(winSize.x-100, winSize.y-35, 100, 35), "Load")) { this.loadStructure(); } if(GUI.Button(new Rect(winSize.x-100, winSize.y-70, 100, 35), "Save")) { this.saveStructure(); } } /* //input Material newMaterial = new Material(usedShader); Vector2 winSize = GetMainGameViewSize(); string newName = GUI.TextField(new Rect(winSize.x-100, winSize.y-20, 100, 20), this.shaderSearchString); if (newName != this.shaderSearchString) { this.shaderSearchString = newName; Shader shd = Shader.Find(this.shaderSearchString); if (shd != null) { newMaterial = new Material(shd); this.usedShader = shd; } } // textures newMaterial.mainTexture = this.usedTexture; foreach(FileInfo file in this.textureFiles) { if (GUILayout.Button(file.Name)) { FileStream rd = file.OpenRead(); byte[] data = new byte[file.Length]; rd.Read(data, 0, (int) file.Length); Texture2D texture = new Texture2D(4, 4); texture.LoadImage(data); newMaterial.mainTexture = texture; //newMaterial.SetTextureScale("_MainTex", new Vector2(3F, 3F)); this.usedTexture = texture; } } //texture scale this.textureHorizontalScale = GUI.HorizontalScrollbar(new Rect(0, winSize.y-35, winSize.x-35, winSize.y-55), this.textureHorizontalScale, 1, 1, 10); this.textureVerticalScale = GUI.VerticalScrollbar(new Rect(winSize.x-15, 0, winSize.x, winSize.y-55), this.textureVerticalScale, 1, 1, 10); //this.textureHorizontalOffset = GUI.HorizontalScrollbar(new Rect(0, winSize.y-55, winSize.x-35, winSize.y-40), this.textureHorizontalOffset, 1, 1, 10); //this.textureVerticalOffset = 10 - GUI.VerticalScrollbar(new Rect(winSize.x-35, 0, winSize.x-10, winSize.y-55), 10 - this.textureVerticalOffset, 1, 1, 10); //newMaterial.SetTextureScale("_MainTex", new Vector2(this.textureHorizontalScale, this.textureVerticalScale)); newPlane.transform.localScale = new Vector3(this.textureHorizontalScale,1, this.textureVerticalScale); newMaterial.SetTextureOffset("_MainTex", new Vector2(this.textureHorizontalOffset, this.textureVerticalOffset)); newPlane.material = newMaterial; if (this.debug) { GUILayout.Label("x:" + this.mouseX.ToString() + "::" + Input.mousePosition.x, new GUILayoutOption[0]); GUILayout.Label("y:" + this.mouseY.ToString() + "::" + Input.mousePosition.y, new GUILayoutOption[0]); GUILayout.Label("z:" + this.mouseZ.ToString() + "::" + Input.mousePosition.z, new GUILayoutOption[0]); GUILayout.Label("l" + (Input.GetMouseButton(0)? "+" : "-")+"r" + (Input.GetMouseButton(1)? "+" : "-")+"m" + (Input.GetMouseButton(2)? "+" : "-"), new GUILayoutOption[0]); GUILayout.Label("ray:{" + this.mouseRay.x + "," + this.mouseRay.y + "," + this.mouseRay.z + "}", new GUILayoutOption[0]); GUILayout.Label("Scale:{" + this.textureHorizontalScale + "," + this.textureVerticalScale + "}", new GUILayoutOption[0]); } */ }
private void loadStructure() { FileInfo fi = new FileInfo("./SaveFile1.psv"); StreamReader rdr = fi.OpenText(); string[] tmpData = rdr.ReadToEnd().Split(new string[]{"}}{{"}, System.StringSplitOptions.RemoveEmptyEntries); rdr.Close(); CustomPlane[] newLayout = new CustomPlane[tmpData.Length + 1]; for (int i = 0; i< tmpData.Length; i++) { Debug.Log("layer: " + tmpData[i]); tmpData[i] = tmpData[i].Replace("{", ""); string[] pars = tmpData[i].Split(new string[]{"}"}, System.StringSplitOptions.RemoveEmptyEntries); newLayout[i+1] = new CustomPlane((Renderer) Instantiate(planeRenderer), i+1); for (int j = 0; j < pars.Length; j++) { Debug.Log("param: " + pars[j]); string[] coords; Vector3 position; switch (pars[j].Substring(0,1)) { case "p": //position coords = pars[j].Split(new string[]{"p:", ";"}, System.StringSplitOptions.RemoveEmptyEntries); position = new Vector3(0, 0, 0); position.x = (float) System.Convert.ToDouble(coords[0]); position.y = (float) System.Convert.ToDouble(coords[1]); position.z = (float) System.Convert.ToDouble(coords[2]); newLayout[i+1].move(position); break; case "s": //size coords = pars[j].Split(new string[]{"s:", ";"}, System.StringSplitOptions.RemoveEmptyEntries); position = new Vector3(0, 0, 0); position.x = (float) System.Convert.ToDouble(coords[0]); position.y = (float) System.Convert.ToDouble(coords[1]); position.z = (float) System.Convert.ToDouble(coords[2]); newLayout[i+1].resize(position); break; case "t": //string. newLayout[i+1].updateTexture(pars[j].Substring(2)); //texture break; default: Debug.LogError("Error loading layer: " + pars[j]); for (int k = 0; k <=i; k++) { Destroy(newLayout[k+1].planeRenderer); } return; } } } newLayout[0] = this.planes[0]; this.planes = newLayout; }
///<summary> ///equation plane N1x(x - xA) + N1y(y - yA) + N1z(z - zA) + d1 = 0 | A e plane<para/> ///equation plane N2x(x - xB) + N2y(y - yB) + N2z(z - zB) + d2 = 0 | B e plane<para/> ///x1 + x1 + y1 + y1 + z1 + z1 + d1 + d1 = x2 + x2 + y2 + y2 + z2 + z2 + d2 + d2<para/> ///find intersection point p with two planes<para/> ///</summary> public static bool IntersectionPlanToPlan(out Vector3 _intersection, out Vector3 _sliceDir, CustomPlane _plane1, CustomPlane _plane2) { _sliceDir = Vector3.Cross(_plane1.Normal, _plane2.Normal); _intersection = Vector3.zero; float x1 = _plane1.UnKnowns.x; float y1 = _plane1.UnKnowns.y; float z1 = _plane1.UnKnowns.z; float d1 = _plane1.UnKnowns.w; float x2 = _plane2.UnKnowns.x; float y2 = _plane2.UnKnowns.y; float z2 = _plane2.UnKnowns.z; float d2 = _plane2.UnKnowns.w; float x = 0.0f; float y = 0.0f; float z = 0.0f; if (_sliceDir.x != 0.0f) { x = 0.0f; z = ((y2 / y1) * d1 - d2) / (z2 - z1 * y2 / y1); y = (-z1 * z - d1) / y1; } else if (_sliceDir.y != 0.0f) { y = 0.0f; z = ((x2 / x1) * d1 - d2) / (z2 - z1 * x2 / x1); x = (-z1 * z - d1) / x1; } else if (_sliceDir.z != 0.0f) { z = 0.0f; y = ((x2 / x1) * d1 - d2) / (y2 - y1 * x2 / x1); x = (-y1 * y - d1) / x1; } else { return(false); } _intersection.x = x; _intersection.y = y; _intersection.z = z; return(true); }
public static void FindNewTriangles(MeshFilter _mf, ref SliceData _data, bool _showDebug) { CustomPlane secondPlane = new CustomPlane(); Vector3 pointOnSliceVec; Vector3 sliceDir; Vector3 finalPoint; for (int i = 0, FaceID = 0; i < _mf.mesh.triangles.Length; i += 3, FaceID += 2) { Vector3 V1 = _mf.transform.TransformPoint(_mf.mesh.vertices[_mf.mesh.triangles[i]]); Vector3 V2 = _mf.transform.TransformPoint(_mf.mesh.vertices[_mf.mesh.triangles[i + 1]]); Vector3 V3 = _mf.transform.TransformPoint(_mf.mesh.vertices[_mf.mesh.triangles[i + 2]]); if (_showDebug) { _data.AddNewSlVectorDebug(V1, Vector3.zero, Color.magenta, false, true); _data.AddNewSlVectorDebug(V2, Vector3.zero, Color.magenta, false, true); _data.AddNewSlVectorDebug(V3, Vector3.zero, Color.magenta, false, true); } secondPlane.Set3Points(V1, V2, V3); Face face1 = new Face(); Face face2 = new Face(); _data.AddFace(FaceID, face1); _data.AddFace(FaceID + 1, face2); Edge[] edges = { new Edge(V1, V2), new Edge(V2, V3), new Edge(V3, V1) }; if (!IntersectionPlanToPlan(out pointOnSliceVec, out sliceDir, _data.CtmPlane, secondPlane)) { foreach (Edge e in edges) { _data.AddEdge(FaceID, new Edge(e.Points[0])); } continue; } bool drawSlice = false; foreach (Edge e in edges) { if (IntersectionVectorToVector(out finalPoint, e.Points[0], e.Points[1], pointOnSliceVec, sliceDir)) { if (_showDebug) { drawSlice = true; _data.AddNewSlVectorDebug(finalPoint, Vector3.zero, Color.magenta, true, false); } _data.AddSeperateEdges(FaceID, e, finalPoint); } else { _data.AddEdge(FaceID, new Edge(e.Points[0])); } } if (drawSlice && _showDebug) { _data.AddNewSlVectorDebug(pointOnSliceVec, sliceDir, Color.green); } } if (_showDebug) { _data.CleanUnusedDebugIntersections(); } }
// Slice mesh along plane intersection public static void SliceMesh(GameObject obj, CustomPlane plane, bool isConvex) { // original GameObject data Transform objTransform = obj.transform; Mesh objMesh = obj.GetComponent <MeshFilter>().mesh; Vector3[] meshVerts = objMesh.vertices; int[] meshTris = objMesh.triangles; Vector2[] meshUVs = objMesh.uv; // Slice mesh data slice1Verts = new List <Vector3>(); slice2Verts = new List <Vector3>(); slice1Tris = new List <int>(); slice2Tris = new List <int>(); slice1UVs = new List <Vector2>(); slice2UVs = new List <Vector2>(); lineLoop = new List <Line>(); // Loop through triangles for (int i = 0; i < meshTris.Length / 3; i++) { // Define triangle Vector3[] triVertsLocal = new Vector3[3]; Vector3[] triVertsWorld = new Vector3[3]; Vector2[] triUVs = new Vector2[3]; for (int j = 0; j < 3; j++) { int meshIndexor = (i + 1) * 3 - (3 - j); triVertsLocal[j] = meshVerts[meshTris[meshIndexor]]; // local model space vertices triVertsWorld[j] = objTransform.TransformPoint(triVertsLocal[j]); // world space vertices triUVs[j] = meshUVs[meshTris[meshIndexor]]; // original uv coordinates } // Side test: (0) = intersecting plane; (+) = above plane; (-) = below plane; float vert1Side = plane.GetSide(triVertsWorld[0]); float vert2Side = plane.GetSide(triVertsWorld[1]); float vert3Side = plane.GetSide(triVertsWorld[2]); // assign triangles that do not intersect plane if (vert1Side > 0 && vert2Side > 0 && vert3Side > 0) // Slice 1 { for (int j = 0; j < triVertsLocal.Length; j++) { slice1Verts.Add(triVertsLocal[j]); slice1Tris.Add(slice1Verts.Count - 1); slice1UVs.Add(triUVs[j]); } } else if (vert1Side < 0 && vert2Side < 0 && vert3Side < 0) // Slice 2 { for (int j = 0; j < triVertsLocal.Length; j++) { slice2Verts.Add(triVertsLocal[j]); slice2Tris.Add(slice2Verts.Count - 1); slice2UVs.Add(triUVs[j]); } } else if (vert1Side == 0 || vert2Side == 0 || vert3Side == 0) { Debug.Log("Point-Plane Intersection"); return; } else // Intersecting Triangles { Vector3[] slicedTriVerts = new Vector3[5]; Vector2[] slicedTriUVs = new Vector2[5]; Vector3[] triVertsWorld2 = new Vector3[3]; int[] vertOrder; // triangle vertex-order CW vs. CCW if (vert1Side * vert2Side > 0) { int[] triOrder = { 2, 0, 1 }; for (int j = 0; j < triOrder.Length; j++) { slicedTriVerts[j] = triVertsLocal[triOrder[j]]; slicedTriUVs[j] = triUVs[triOrder[j]]; triVertsWorld2[j] = triVertsWorld[triOrder[j]]; } vertOrder = vertOrderCW; } else if (vert1Side * vert3Side > 0) { int[] triOrder = { 1, 0, 2 }; for (int j = 0; j < triOrder.Length; j++) { slicedTriVerts[j] = triVertsLocal[triOrder[j]]; slicedTriUVs[j] = triUVs[triOrder[j]]; triVertsWorld2[j] = triVertsWorld[triOrder[j]]; } vertOrder = vertOrderCCW; } else { int[] triOrder = { 0, 1, 2 }; for (int j = 0; j < triOrder.Length; j++) { slicedTriVerts[j] = triVertsLocal[triOrder[j]]; slicedTriUVs[j] = triUVs[triOrder[j]]; triVertsWorld2[j] = triVertsWorld[triOrder[j]]; } vertOrder = vertOrderCW; } // Points of Intersection Vector3 poi1 = plane.VectorPlanePOI(triVertsWorld2[0], (triVertsWorld2[1] - triVertsWorld2[0]).normalized); Vector3 poi2 = plane.VectorPlanePOI(triVertsWorld2[0], (triVertsWorld2[2] - triVertsWorld2[0]).normalized); slicedTriVerts[3] = objTransform.InverseTransformPoint(poi1); slicedTriVerts[4] = objTransform.InverseTransformPoint(poi2); lineLoop.Add(new Line(slicedTriVerts[3], slicedTriVerts[4], poi1, poi2)); // POI UVs float t1 = Vector3.Distance(slicedTriVerts[0], slicedTriVerts[3]) / Vector3.Distance(slicedTriVerts[0], slicedTriVerts[1]); float t2 = Vector3.Distance(slicedTriVerts[0], slicedTriVerts[4]) / Vector3.Distance(slicedTriVerts[0], slicedTriVerts[2]); slicedTriUVs[3] = Vector2.Lerp(slicedTriUVs[0], slicedTriUVs[1], t1); slicedTriUVs[4] = Vector2.Lerp(slicedTriUVs[0], slicedTriUVs[2], t2); // Add bisected triangle to slice respectively if (plane.GetSide(triVertsWorld2[0]) > 0) { // Slice 1 for (int j = 0; j < 3; j++) { slice1Verts.Add(slicedTriVerts[vertOrder[j]]); slice1Tris.Add(slice1Verts.Count - 1); slice1UVs.Add(slicedTriUVs[vertOrder[j]]); } // Slice 2 for (int j = 3; j < 9; j++) { slice2Verts.Add(slicedTriVerts[vertOrder[j]]); slice2Tris.Add(slice2Verts.Count - 1); slice2UVs.Add(slicedTriUVs[vertOrder[j]]); } } else { // Slice 2 for (int j = 0; j < 3; j++) { slice2Verts.Add(slicedTriVerts[vertOrder[j]]); slice2Tris.Add(slice2Verts.Count - 1); slice2UVs.Add(slicedTriUVs[vertOrder[j]]); } // Slice 1 for (int j = 3; j < 9; j++) { slice1Verts.Add(slicedTriVerts[vertOrder[j]]); slice1Tris.Add(slice1Verts.Count - 1); slice1UVs.Add(slicedTriUVs[vertOrder[j]]); } } } } if (lineLoop.Count > 0) { // Fill convex mesh if (isConvex) { Vector3 normal = plane.normal; do { Polygon polygon = new Polygon(lineLoop, normal); Vector3 polygonNormal = (polygon.isClockWise) ? normal : -normal; TriangulatePolygon(polygon.edges, polygonNormal, polygon.isClockWise); } while(lineLoop.Count != 0); } // Build Meshes if (slice1Verts.Count > 0) { BuildSlice(obj, objTransform, slice1Verts.ToArray(), slice1Tris.ToArray(), slice1UVs.ToArray()); } if (slice2Verts.Count > 0) { BuildSlice(obj, objTransform, slice2Verts.ToArray(), slice2Tris.ToArray(), slice2UVs.ToArray()); } // Delete original GameObject.Destroy(obj); } }