示例#1
0
        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();
        }
示例#4
0
        /// <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();
        }