public static bool SplitPolygonAtEdge(Polygon polygon, Edge edge, out Vertex newVertex) { newVertex = null; List <Vertex> vertices = new List <Vertex>(polygon.Vertices); for (int i = 0; i < polygon.Vertices.Length; i++) { Vector3 position1 = polygon.Vertices[i].Position; Vector3 position2 = polygon.Vertices[(i + 1) % polygon.Vertices.Length].Position; if ((edge.Vertex1.Position.EqualsWithEpsilon(position1) && edge.Vertex2.Position.EqualsWithEpsilon(position2)) || (edge.Vertex1.Position.EqualsWithEpsilon(position2) && edge.Vertex2.Position.EqualsWithEpsilon(position1))) { newVertex = Vertex.Lerp(polygon.Vertices[i], polygon.Vertices[(i + 1) % polygon.Vertices.Length], 0.5f); vertices.Insert(i + 1, newVertex); break; } } if (vertices.Count == polygon.Vertices.Length) { // Could not add vertex to adjacent polygon return(false); } polygon.SetVertices(vertices.ToArray()); return(true); }
public static void ExtrudePolygonOld(Polygon sourcePolygon, out Polygon[] outputPolygons, out Quaternion rotation) { float extrusionDistance = 1; Polygon newPolygon = sourcePolygon.DeepCopy(); newPolygon.UniqueIndex = -1; newPolygon.Flip(); Vector3 normal = sourcePolygon.Plane.normal; Polygon oppositePolygon = sourcePolygon.DeepCopy(); oppositePolygon.UniqueIndex = -1; Vertex[] vertices = oppositePolygon.Vertices; for (int i = 0; i < vertices.Length; i++) { vertices[i].Position += normal; } oppositePolygon.SetVertices(vertices); Polygon[] brushSides = new Polygon[sourcePolygon.Vertices.Length]; for (int i = 0; i < newPolygon.Vertices.Length; i++) { Vertex vertex1 = newPolygon.Vertices[i].DeepCopy(); Vertex vertex2 = newPolygon.Vertices[(i + 1) % newPolygon.Vertices.Length].DeepCopy(); Vector2 uvDelta = vertex2.UV - vertex1.UV; float sourceDistance = Vector3.Distance(vertex1.Position, vertex2.Position); Vector2 rotatedUVDelta = uvDelta.Rotate(90) * (extrusionDistance / sourceDistance); Vertex vertex3 = vertex1.DeepCopy(); vertex3.Position += normal * extrusionDistance; vertex3.UV += rotatedUVDelta; Vertex vertex4 = vertex2.DeepCopy(); vertex4.Position += normal * extrusionDistance; vertex4.UV += rotatedUVDelta; Vertex[] newVertices = new Vertex[] { vertex1, vertex2, vertex4, vertex3 }; brushSides[i] = new Polygon(newVertices, sourcePolygon.Material, false, false); brushSides[i].Flip(); brushSides[i].ResetVertexNormals(); } List <Polygon> polygons = new List <Polygon>(); polygons.Add(newPolygon); polygons.Add(oppositePolygon); polygons.AddRange(brushSides); outputPolygons = polygons.ToArray(); rotation = Quaternion.identity; }
public static void ExtrudePolygon(Polygon sourcePolygon, out Polygon[] outputPolygons, out Quaternion rotation) { float extrusionDistance = 1; Polygon basePolygon = sourcePolygon.DeepCopy(); basePolygon.UniqueIndex = -1; rotation = Quaternion.LookRotation(basePolygon.Plane.normal); Quaternion cancellingRotation = Quaternion.Inverse(rotation); Vertex[] vertices = basePolygon.Vertices; // Vector3 offsetPosition = vertices[0].Position; for (int i = 0; i < vertices.Length; i++) { // vertices[i].Position -= offsetPosition; vertices[i].Position = cancellingRotation * vertices[i].Position; vertices[i].Normal = cancellingRotation * vertices[i].Normal; } // Vector3 newOffsetPosition = vertices[0].Position; // Vector3 delta = newOffsetPosition - offsetPosition; // for (int i = 0; i < vertices.Length; i++) // { // vertices[i].Position += delta; // } basePolygon.SetVertices(vertices); Vector3 normal = basePolygon.Plane.normal; Polygon oppositePolygon = basePolygon.DeepCopy(); oppositePolygon.UniqueIndex = -1; basePolygon.Flip(); vertices = oppositePolygon.Vertices; for (int i = 0; i < vertices.Length; i++) { vertices[i].Position += normal; } oppositePolygon.SetVertices(vertices); Polygon[] brushSides = new Polygon[sourcePolygon.Vertices.Length]; for (int i = 0; i < basePolygon.Vertices.Length; i++) { Vertex vertex1 = basePolygon.Vertices[i].DeepCopy(); Vertex vertex2 = basePolygon.Vertices[(i + 1) % basePolygon.Vertices.Length].DeepCopy(); Vector2 uvDelta = vertex2.UV - vertex1.UV; float sourceDistance = Vector3.Distance(vertex1.Position, vertex2.Position); Vector2 rotatedUVDelta = uvDelta.Rotate(90) * (extrusionDistance / sourceDistance); Vertex vertex3 = vertex1.DeepCopy(); vertex3.Position += normal * extrusionDistance; vertex3.UV += rotatedUVDelta; Vertex vertex4 = vertex2.DeepCopy(); vertex4.Position += normal * extrusionDistance; vertex4.UV += rotatedUVDelta; Vertex[] newVertices = new Vertex[] { vertex1, vertex2, vertex4, vertex3 }; brushSides[i] = new Polygon(newVertices, sourcePolygon.Material, false, false); brushSides[i].Flip(); brushSides[i].ResetVertexNormals(); } List <Polygon> polygons = new List <Polygon>(); polygons.Add(basePolygon); polygons.Add(oppositePolygon); polygons.AddRange(brushSides); outputPolygons = polygons.ToArray(); }
/// <summary> /// Creates a brush by extruding a supplied polygon by a specified extrusion distance. /// </summary> /// <param name="sourcePolygon">Source polygon, typically transformed into world space.</param> /// <param name="extrusionDistance">Extrusion distance, this is the height (or depth) of the created geometry perpendicular to the source polygon.</param> /// <param name="outputPolygons">Output brush polygons.</param> /// <param name="rotation">The rotation to be supplied to the new brush transform.</param> public static void ExtrudePolygon(Polygon sourcePolygon, float extrusionDistance, out Polygon[] outputPolygons, out Quaternion rotation) { bool flipped = false; if (extrusionDistance < 0) { sourcePolygon.Flip(); extrusionDistance = -extrusionDistance; flipped = true; } // Create base polygon Polygon basePolygon = sourcePolygon.DeepCopy(); basePolygon.UniqueIndex = -1; rotation = Quaternion.LookRotation(basePolygon.Plane.normal); Quaternion cancellingRotation = Quaternion.Inverse(rotation); Vertex[] vertices = basePolygon.Vertices; for (int i = 0; i < vertices.Length; i++) { vertices[i].Position = cancellingRotation * vertices[i].Position; vertices[i].Normal = cancellingRotation * vertices[i].Normal; } basePolygon.SetVertices(vertices); // Create the opposite polygon by duplicating the base polygon, offsetting and flipping Vector3 normal = basePolygon.Plane.normal; Polygon oppositePolygon = basePolygon.DeepCopy(); oppositePolygon.UniqueIndex = -1; basePolygon.Flip(); vertices = oppositePolygon.Vertices; for (int i = 0; i < vertices.Length; i++) { vertices[i].Position += normal * extrusionDistance; // vertices[i].UV.x *= -1; // Flip UVs } oppositePolygon.SetVertices(vertices); // Now create each of the brush side polygons Polygon[] brushSides = new Polygon[sourcePolygon.Vertices.Length]; for (int i = 0; i < basePolygon.Vertices.Length; i++) { Vertex vertex1 = basePolygon.Vertices[i].DeepCopy(); Vertex vertex2 = basePolygon.Vertices[(i + 1) % basePolygon.Vertices.Length].DeepCopy(); // Create new UVs for the sides, otherwise we'll get distortion float sourceDistance = Vector3.Distance(vertex1.Position, vertex2.Position); float uvDistance = Vector2.Distance(vertex1.UV, vertex2.UV); float uvScale = sourceDistance / uvDistance; vertex1.UV = Vector2.zero; if (flipped) { vertex2.UV = new Vector2(-sourceDistance / uvScale, 0); } else { vertex2.UV = new Vector2(sourceDistance / uvScale, 0); } Vector2 uvDelta = vertex2.UV - vertex1.UV; Vector2 rotatedUVDelta = uvDelta.Rotate(90) * (extrusionDistance / sourceDistance); Vertex vertex3 = vertex1.DeepCopy(); vertex3.Position += normal * extrusionDistance; vertex3.UV += rotatedUVDelta; Vertex vertex4 = vertex2.DeepCopy(); vertex4.Position += normal * extrusionDistance; vertex4.UV += rotatedUVDelta; Vertex[] newVertices = new Vertex[] { vertex1, vertex2, vertex4, vertex3 }; brushSides[i] = new Polygon(newVertices, sourcePolygon.Material, false, false); brushSides[i].Flip(); brushSides[i].ResetVertexNormals(); } List <Polygon> polygons = new List <Polygon>(); polygons.Add(basePolygon); polygons.Add(oppositePolygon); polygons.AddRange(brushSides); outputPolygons = polygons.ToArray(); }