Esempio n. 1
0
        /// <summary>
        /// Scales the brush by a local Vector3 scale from its pivot
        /// </summary>
        /// <param name="brush">The brush to be rescaled</param>
        /// <param name="rescaleValue">Local scale to apply</param>
        public static void Scale(PrimitiveBrush brush, Vector3 scaleValue)
        {
            Polygon[] polygons = brush.GetPolygons();

            for (int i = 0; i < polygons.Length; i++)
            {
                Polygon polygon = polygons[i];

                polygons[i].CalculatePlane();
                Vector3 previousPlaneNormal = polygons[i].Plane.normal;

                int vertexCount = polygon.Vertices.Length;

                Vector3[] newPositions = new Vector3[vertexCount];
                Vector2[] newUV        = new Vector2[vertexCount];

                for (int j = 0; j < vertexCount; j++)
                {
                    newPositions[j] = polygon.Vertices[j].Position;
                    newUV[j]        = polygon.Vertices[j].UV;
                }

                for (int j = 0; j < vertexCount; j++)
                {
                    Vertex vertex = polygon.Vertices[j];

                    Vector3 newPosition = vertex.Position.Multiply(scaleValue);
                    newPositions[j] = newPosition;

                    newUV[j] = GeometryHelper.GetUVForPosition(polygon, newPosition);
                }

                // Apply all the changes to the polygon
                for (int j = 0; j < vertexCount; j++)
                {
                    Vertex vertex = polygon.Vertices[j];
                    vertex.Position = newPositions[j];
                    vertex.UV       = newUV[j];
                }

                // Polygon geometry has changed, inform the polygon that it needs to recalculate its cached plane
                polygons[i].CalculatePlane();

                Vector3 newPlaneNormal = polygons[i].Plane.normal;

                // Find the rotation from the original polygon plane to the new polygon plane
                Quaternion normalRotation = Quaternion.FromToRotation(previousPlaneNormal, newPlaneNormal);

                // Rotate all the vertex normals by the new rotation
                for (int j = 0; j < vertexCount; j++)
                {
                    Vertex vertex = polygon.Vertices[j];
                    vertex.Normal = normalRotation * vertex.Normal;
                }
            }
#if UNITY_EDITOR
            EditorHelper.SetDirty(brush);
#endif
            brush.Invalidate(true);
        }
Esempio n. 2
0
        public static void InsertEdgeLoop(PrimitiveBrush brush, Plane localClipPlane)
        {
            // Clip the polygons against the plane
            List <Polygon> polygonsFront;
            List <Polygon> polygonsBack;

            if (PolygonFactory.SplitPolygonsByPlane(new List <Polygon>(brush.GetPolygons()), localClipPlane, true, out polygonsFront, out polygonsBack))
            {
                List <Polygon> allPolygons = new List <Polygon>();
                // Concat back into one list
                allPolygons.AddRange(polygonsFront);
                allPolygons.AddRange(polygonsBack);
                // Remove the inserted polygons
                for (int i = 0; i < allPolygons.Count; i++)
                {
                    if (allPolygons[i].ExcludeFromFinal)
                    {
                        allPolygons.RemoveAt(i);
                        i--;
                    }
                }
                // Update the brush with the new polygons
                brush.SetPolygons(allPolygons.ToArray(), true);
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Rebuilds the volume, creating or deleting the volume component and applying new settings.
        /// </summary>
        internal void RebuildVolume()
        {
            // volumes can only be primitive brushes at the moment.
            if (GetType() != typeof(PrimitiveBrush))
            {
                return;
            }
            PrimitiveBrush self = (PrimitiveBrush)this;

            // remove volumes from brushes that are no longer volumes:
            if (Mode != CSGMode.Volume && Volume != null)
            {
                // set volume handle to null.
                Volume = null;
                // delete any built volume.
                Transform volume1 = transform.Find(Constants.GameObjectVolumeComponentIdentifier);
                if (volume1 != null)
                {
                    GameObject.DestroyImmediate(volume1.gameObject);
                }
            }

            // generate all of the volume brushes:
            if (Mode == CSGMode.Volume && Volume != null)
            {
                // remove any existing built volume:
                Transform volume2 = transform.Find(Constants.GameObjectVolumeComponentIdentifier);
                if (volume2 != null)
                {
                    GameObject.DestroyImmediate(volume2.gameObject);
                }

                // create the game object with convex mesh collider:
                Mesh mesh = new Mesh();
                BrushFactory.GenerateMeshFromPolygonsFast(self.GetPolygons(), ref mesh, 0.0f);
                GameObject gameObject = CreateVolumeMeshCollider(mesh);
                gameObject.transform.position = transform.position;
                gameObject.transform.rotation = transform.rotation;

                // execute custom volume generation code:
                Volume.OnCreateVolume(gameObject);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Applies a clip or split operation to a brush by supplying a plane local to the brush. Clipping allows you to cut away and discard parts of the brush, while splitting allows you to split a brush in two.
        /// </summary>
        /// <returns>If keepBothSides is <c>true</c>, this returns the second brush if one was created.</returns>
        /// <param name="brush">Brush to clip/split</param>
        /// <param name="localPlane">Local plane to clip/split against</param>
        /// <param name="keepBothSides">If set to <c>true</c> split the brush and keep both sides.</param>
        /// <param name="resetPivots">If set to <c>true</c> make sure the pivot clipped brush and any new brush are at their center.</param>
        public static GameObject ApplyClipPlane(PrimitiveBrush brush, Plane localPlane, bool keepBothSides, bool resetPivots = true)
        {
            // Clip the polygons against the plane
            List <Polygon> polygonsFront;
            List <Polygon> polygonsBack;

            List <Polygon> polygonList = new List <Polygon>(brush.GetPolygons());

            if (PolygonFactory.SplitPolygonsByPlane(polygonList, localPlane, false, out polygonsFront, out polygonsBack))
            {
                // Update the brush with the new polygons
                brush.SetPolygons(polygonsFront.ToArray(), true);

                GameObject newObject = null;
                // If they have decided to split instead of clip, create a second brush with the other side
                if (keepBothSides)
                {
                    newObject = brush.Duplicate();

                    // Finally give the new brush the other set of polygons
                    newObject.GetComponent <PrimitiveBrush>().SetPolygons(polygonsBack.ToArray(), true);
                    newObject.transform.SetSiblingIndex(brush.transform.GetSiblingIndex());
                    // Reset the new brush's pivot
                    if (resetPivots)
                    {
                        newObject.GetComponent <PrimitiveBrush>().ResetPivot();
                    }
                }

                // Can't reset the first brush pivot until after the second brush is made, otherwise the second
                // brush is effectively translated twice, ending up in the wrong position
                if (resetPivots)
                {
                    brush.ResetPivot();
                }

                return(newObject);
            }
            else
            {
                return(null);
            }
        }