Beispiel #1
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);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Create a brush at the origin using a specified set of polygons
        /// </summary>
        /// <returns>The custom brush game object.</returns>
        /// <param name="polygons">Polygons.</param>
        public GameObject CreateCustomBrush(Polygon[] polygons)
        {
            GameObject brushObject = new GameObject("AppliedBrush");

            brushObject.transform.parent = this.transform;
            PrimitiveBrush primitiveBrush = brushObject.AddComponent <PrimitiveBrush>();

            primitiveBrush.SetPolygons(polygons, true);

            return(brushObject);
        }
Beispiel #3
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);
            }
        }
Beispiel #4
0
        private void CreateBrush(List <Vector3> positions)
        {
            Polygon sourcePolygon = PolygonFactory.ConstructPolygon(positions, true);

            // Early out if it wasn't possible to create the polygon
            if (sourcePolygon == null)
            {
                return;
            }

            if (activePolygon != null)
            {
                for (int i = 0; i < sourcePolygon.Vertices.Length; i++)
                {
                    Vector2 newUV = GeometryHelper.GetUVForPosition(activePolygon, sourcePolygon.Vertices[i].Position);
                    sourcePolygon.Vertices[i].UV = newUV;
                }
            }

            Vector3 planeNormal = GetActivePlane().normal;

            //			Debug.Log(Vector3.Dot(sourcePolygon.Plane.normal, planeNormal));

            // Flip the polygon if the winding order is wrong
            if (Vector3.Dot(sourcePolygon.Plane.normal, planeNormal) < 0)
            {
                sourcePolygon.Flip();

                // Need to flip the UVs across the U (X) direction
                for (int i = 0; i < sourcePolygon.Vertices.Length; i++)
                {
                    Vector2 uv = sourcePolygon.Vertices[i].UV;
                    uv.x = 1 - uv.x;
                    sourcePolygon.Vertices[i].UV = uv;
                }
            }

            float   extrusionDistance = 1;
            Vector3 positionOffset    = Vector3.zero;

            if (selectingHeight)
            {
                extrusionDistance = prismHeight;
            }
            else
            {
                if (activePolygon != null && activeBrush != null)
                {
                    extrusionDistance = activeBrush.CalculateExtentsInAxis(planeNormal);
                }
                else
                {
                    Brush lastSelectedBrush = csgModel.LastSelectedBrush;
                    if (lastSelectedBrush != null)
                    {
                        Bounds lastSelectedBrushBounds = lastSelectedBrush.GetBoundsTransformed();

                        for (int i = 0; i < 3; i++)
                        {
                            if (!planeNormal[i].EqualsWithEpsilon(0))
                            {
                                if (lastSelectedBrushBounds.size[i] != 0)
                                {
                                    extrusionDistance = lastSelectedBrushBounds.size[i];

                                    if (planeNormal[i] > 0)
                                    {
                                        positionOffset[i] = lastSelectedBrushBounds.center[i] - lastSelectedBrushBounds.extents[i];
                                    }
                                    else
                                    {
                                        positionOffset[i] = lastSelectedBrushBounds.center[i] + lastSelectedBrushBounds.extents[i];
                                    }
                                }
                            }
                        }
                    }
                }

                // Subtractions should go through
                if (csgMode == CSGMode.Subtract)
                {
                    sourcePolygon.Flip();
                }
            }

            Quaternion rotation;

            Polygon[] polygons;
            SurfaceUtility.ExtrudePolygon(sourcePolygon, extrusionDistance, out polygons, out rotation);

            GameObject newObject = csgModel.CreateCustomBrush(polygons);

            PrimitiveBrush newBrush = newObject.GetComponent <PrimitiveBrush>();

            newObject.transform.rotation  = rotation;
            newObject.transform.position += positionOffset;

            if (activePolygon != null &&
                activePolygon.Material != csgModel.GetDefaultMaterial())
            {
                for (int i = 0; i < polygons.Length; i++)
                {
                    polygons[i].Material = activePolygon.Material;
                }
            }
            // Finally give the new brush the other set of polygons
            newBrush.SetPolygons(polygons, true);

            newBrush.Mode = csgMode;

            newBrush.ResetPivot();

            // Use this brush as the basis for drawing the next brush
            csgModel.SetLastSelectedBrush(newBrush);

            Undo.RegisterCreatedObjectUndo(newObject, "Draw Brush");
        }