public static Pair <float?, float?> GetUVOffset(List <Polygon> polygons)
        {
            float?northOffset = 0;
            float?eastOffset  = 0;

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

                Vector2 uvOffset = SurfaceUtility.GetUVOffset(polygon);

                if (polygonIndex == 0)
                {
                    northOffset = uvOffset.y;
                    eastOffset  = uvOffset.x;
                }
                else
                {
                    if (!northOffset.HasValue || !northOffset.Value.EqualsWithEpsilon(uvOffset.y))
                    {
                        northOffset = null;
                    }

                    if (!eastOffset.HasValue || !eastOffset.Value.EqualsWithEpsilon(uvOffset.x))
                    {
                        eastOffset = null;
                    }
                }
            }

            return(new Pair <float?, float?> (eastOffset, northOffset));
        }
Exemple #2
0
        /// <summary>
        /// Creates a brush under the CSG Model with the specified attributes.
        /// </summary>
        /// <returns>The created game object.</returns>
        /// <param name="brushType">Brush type.</param>
        /// <param name="localPosition">Local position of the brush's transform</param>
        /// <param name="localSize">Local bounds size of the brush (Optional, defaults to 2,2,2).</param>
        /// <param name="localRotation">Local rotation of the brush (Optional, defaults to identity quaternion).</param>
        /// <param name="material">Material to apply to all faces, (Optional, defaults to null for default material).</param>
        /// <param name="csgMode">Whether the brush is additive or subtractive (Optional, defaults to additive).</param>
        /// <param name="brushName">Name for the game object (Optional, defaults to "AppliedBrush").</param>
        public GameObject CreateBrush(PrimitiveBrushType brushType, Vector3 localPosition, Vector3 localSize = default(Vector3), Quaternion localRotation = default(Quaternion), Material material = null, CSGMode csgMode = CSGMode.Add, string brushName = null)
        {
            GameObject brushObject;

            if (!string.IsNullOrEmpty(brushName))
            {
                brushObject = new GameObject(brushName);
            }
            else
            {
                brushObject = new GameObject("");
            }

            brushObject.transform.localScale    = this.transform.lossyScale;
            brushObject.transform.parent        = this.transform;
            brushObject.transform.localPosition = localPosition;
            if (localRotation != default(Quaternion))
            {
                brushObject.transform.localRotation = localRotation;
            }
            PrimitiveBrush primitiveBrush = brushObject.AddComponent <PrimitiveBrush>();

            primitiveBrush.BrushType = brushType;
            primitiveBrush.Mode      = csgMode;
            primitiveBrush.ResetPolygons();

            if (localSize != default(Vector3) &&
                localSize != new Vector3(2, 2, 2))
            {
                BrushUtility.Resize(primitiveBrush, localSize);
            }
            else
            {
                // Resize automatically invalidates a brush with changed polygons set, if no resize took place we still need to make sure it happens
                primitiveBrush.Invalidate(true);
            }

            if (material != null)
            {
                SurfaceUtility.SetAllPolygonsMaterials(primitiveBrush, material);
            }

            return(brushObject);
        }
        public static Vector2 GetUVOffset(Polygon polygon)
        {
            Vertex vertex1;
            Vertex vertex2;
            Vertex vertex3;

            // Get three vertices which will reliably give us good UV information (i.e. not collinear)
            SurfaceUtility.GetPrimaryPolygonDescribers(polygon, out vertex1, out vertex2, out vertex3);

            Vector2 newUV = GeometryHelper.GetUVForPosition(vertex1.Position,
                                                            vertex2.Position,
                                                            vertex3.Position,
                                                            vertex1.UV,
                                                            vertex2.UV,
                                                            vertex3.UV,
                                                            polygon.GetCenterPoint());

            return(newUV);
        }
        /// <summary>
        /// Creates a brush under the CSG Model with the specified attributes.
        /// </summary>
        /// <returns>The created game object.</returns>
        /// <param name="brushType">Brush type.</param>
        /// <param name="localPosition">Local position of the brush's transform</param>
        /// <param name="localSize">Local bounds size of the brush (Optional, defaults to 2,2,2).</param>
        /// <param name="localRotation">Local rotation of the brush (Optional, defaults to identity quaternion).</param>
        /// <param name="material">Material to apply to all faces, (Optional, defaults to null for default material).</param>
        /// <param name="csgMode">Whether the brush is additive or subtractive (Optional, defaults to additive).</param>
        /// <param name="brushName">Name for the game object (Optional, defaults to "AppliedBrush").</param>
        public GameObject CreateBrush(PrimitiveBrushType brushType, Vector3 localPosition, Vector3 localSize = default(Vector3), Quaternion localRotation = default(Quaternion), Material material = null, CSGMode csgMode = CSGMode.Add, string brushName = null)
        {
            GameObject brushObject;

            if (!string.IsNullOrEmpty(brushName))
            {
                brushObject = new GameObject(brushName);
            }
            else
            {
                brushObject = new GameObject("AppliedBrush");
            }

            brushObject.transform.parent        = this.transform;
            brushObject.transform.localPosition = localPosition;
            if (localRotation != default(Quaternion))
            {
                brushObject.transform.localRotation = localRotation;
            }
            PrimitiveBrush primitiveBrush = brushObject.AddComponent <PrimitiveBrush>();

            primitiveBrush.BrushType = brushType;
            primitiveBrush.Mode      = csgMode;
            primitiveBrush.ResetPolygons();

            if (localSize != default(Vector3) &&
                localSize != new Vector3(2, 2, 2))
            {
                BrushUtility.Resize(primitiveBrush, localSize);
//				primitiveBrush.Invalidate(true);
            }

            if (material != null)
            {
                SurfaceUtility.SetAllPolygonsMaterials(primitiveBrush, material);
            }

            return(brushObject);
        }
        public static void SplitIntersecting(PrimitiveBrush[] brushes)
        {
            List <Brush> intersections = new List <Brush>();

            foreach (PrimitiveBrush brush in brushes)
            {
                intersections.AddRange(brush.BrushCache.IntersectingVisualBrushes);
            }

            foreach (PrimitiveBrush brush in brushes)
            {
                List <PrimitiveBrush> newBrushes = new List <PrimitiveBrush>();

                foreach (Brush intersectingBrush in intersections)
                {
                    PrimitiveBrush brushToClip = (PrimitiveBrush)intersectingBrush;

                    Polygon[] polygons = brush.GetPolygons();

                    // A brush may have several polygons that share a plane, find all the distinct polygon planes
                    List <Plane> distinctPlanes = new List <Plane>();

                    for (int polygonIndex = 0; polygonIndex < polygons.Length; polygonIndex++)
                    {
                        Polygon polygon = polygons[polygonIndex];
                        Vertex  vertex1, vertex2, vertex3;
                        SurfaceUtility.GetPrimaryPolygonDescribers(polygon, out vertex1, out vertex2, out vertex3);

                        Vector3 position1 = vertex1.Position;
                        Vector3 position2 = vertex2.Position;
                        Vector3 position3 = vertex3.Position;

                        // Transform from local to brush to local to intersectingBrush
                        position1 = intersectingBrush.transform.InverseTransformPoint(brush.transform.TransformPoint(position1));
                        position2 = intersectingBrush.transform.InverseTransformPoint(brush.transform.TransformPoint(position2));
                        position3 = intersectingBrush.transform.InverseTransformPoint(brush.transform.TransformPoint(position3));

                        // Calculate plane in intersectingBrush's local space
                        Plane polygonPlane = new Plane(position1, position2, position3);

                        bool found = false;
                        // See if it already exists
                        for (int i = 0; i < distinctPlanes.Count; i++)
                        {
                            if (MathHelper.PlaneEqualsLooser(distinctPlanes[i], polygonPlane))
                            {
                                found = true;
                                break;
                            }
                        }

                        // Not added to an existing group, so add new
                        if (!found)
                        {
                            // Add a new group for the polygon
                            distinctPlanes.Add(polygonPlane);
                        }
                    }

                    foreach (Plane clipPlane in distinctPlanes)
                    {
#if UNITY_EDITOR
                        UnityEditor.Undo.RecordObject(brushToClip, "Split Intersecting Brushes");
                        UnityEditor.Undo.RecordObject(brushToClip.transform, "Split Intersecting Brushes");
#endif

                        GameObject newObject = ClipUtility.ApplyClipPlane(brushToClip, clipPlane, true, false);

                        if (newObject != null)
                        {
#if UNITY_EDITOR
                            UnityEditor.Undo.RegisterCreatedObjectUndo(newObject, "Split Intersecting Brushes");
#endif
                            newBrushes.Add(newObject.GetComponent <PrimitiveBrush>());
                        }
                    }

                    brushToClip.ResetPivot();
                }

                foreach (PrimitiveBrush newBrush in newBrushes)
                {
                    newBrush.ResetPivot();
                }

                intersections.AddRange(newBrushes.ConvertAll <Brush>(item => (Brush)item));
            }
        }
Exemple #6
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");
        }