示例#1
0
        public static void TranslatePivot(CSGBrush[] brushes, Vector3 offset)
        {
            if (brushes == null ||
                brushes.Length == 0 ||
                offset.sqrMagnitude < MathConstants.ConsideredZero)
            {
                return;
            }

            for (int i = 0; i < brushes.Length; i++)
            {
                brushes[i].transform.position += offset;
            }

            GeometryUtility.MoveControlMeshVertices(brushes, -offset);
            SurfaceUtility.TranslateSurfacesInWorldSpace(brushes, -offset);
            ControlMeshUtility.RebuildShapes(brushes);
        }
示例#2
0
        public static void SetPivot(CSGBrush brush, Vector3 newCenter)
        {
            if (!brush)
            {
                return;
            }

            var transform  = brush.transform;
            var realCenter = transform.position;
            var difference = newCenter - realCenter;

            if (difference.sqrMagnitude < MathConstants.ConsideredZero)
            {
                return;
            }

            transform.position += difference;

            GeometryUtility.MoveControlMeshVertices(brush, -difference);
            SurfaceUtility.TranslateSurfacesInWorldSpace(brush, -difference);
            ControlMeshUtility.RebuildShape(brush);
        }
示例#3
0
        protected override void HandleCreateShapeEvents(SceneView sceneView, Rect sceneRect)
        {        /*
                  *     if (settings.vertices.Length < 2)
                  *     {
                  *             if (editMode == EditMode.Extrude2DShape ||
                  *                     editMode == EditMode.EditVertices)
                  *                     editMode = EditMode.CreatePlane;
                  *     }
                  */
            bool     pointOnEdge      = false;
            bool     havePlane        = false;
            bool     vertexOnGeometry = false;
            CSGBrush vertexOnBrush    = null;

            CSGPlane hoverBuildPlane = buildPlane;
            var      camera          = sceneView.camera;

            if (camera != null &&
                camera.pixelRect.Contains(Event.current.mousePosition))
            {
                if (!hoverDefaultPlane.HasValue ||
                    settings.vertices.Length == 0)
                {
                    bool forceGrid = RealtimeCSG.CSGGrid.ForceGrid;
                    RealtimeCSG.CSGGrid.ForceGrid = false;
                    hoverDefaultPlane             = RealtimeCSG.CSGGrid.CurrentGridPlane;
                    RealtimeCSG.CSGGrid.ForceGrid = forceGrid;
                    firstSnappedEdges             = null;
                    firstSnappedBrush             = null;
                    firstSnappedPlanes            = null;
                    base.geometryModel            = null;
                }
                if (editMode == EditMode.CreatePlane)
                {
                    LegacyBrushIntersection intersection;
                    if (!IgnoreDepthForRayCasts(camera) && !havePlane &&
                        EditorWindow.mouseOverWindow == sceneView &&
                        SceneQueryUtility.FindWorldIntersection(camera, Event.current.mousePosition, out intersection))
                    {
                        worldPosition   = intersection.worldIntersection;
                        hoverBuildPlane = intersection.worldPlane;
                        vertexOnBrush   = intersection.brush;

                        vertexOnGeometry = true;
                    }
                    else
                    {
                        hoverBuildPlane = hoverDefaultPlane.Value;
                        vertexOnBrush   = null;

                        var mouseRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
                        worldPosition    = hoverBuildPlane.RayIntersection(mouseRay);
                        vertexOnGeometry = false;
                    }

                    ResetVisuals();
                    if (snapFunction != null)
                    {
                        CSGBrush snappedOnBrush;
                        worldPosition = snapFunction(camera, worldPosition, hoverBuildPlane, ref visualSnappedEdges, out snappedOnBrush, generatedBrushes);
                        if (snappedOnBrush != null)
                        {
                            pointOnEdge = (visualSnappedEdges != null &&
                                           visualSnappedEdges.Count > 0);
                            vertexOnBrush    = snappedOnBrush;
                            vertexOnGeometry = true;
                        }
                    }

                    if (settings.vertices.Length == 1)
                    {
                        if (hoverBuildPlane.normal != MathConstants.zeroVector3)
                        {
                            editMode  = EditMode.CreateShape;
                            havePlane = true;
                        }
                    }
                    else
                    if (settings.vertices.Length == 2)
                    {
                        onLastPoint = true;
                    }
                }
                else
                {
                    var mouseRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
                    worldPosition = hoverBuildPlane.RayIntersection(mouseRay);

                    ResetVisuals();
                    if (snapFunction != null)
                    {
                        CSGBrush snappedOnBrush;
                        worldPosition = snapFunction(camera, worldPosition, hoverBuildPlane, ref visualSnappedEdges, out snappedOnBrush, generatedBrushes);
                        if (snappedOnBrush != null)
                        {
                            pointOnEdge = (visualSnappedEdges != null &&
                                           visualSnappedEdges.Count > 0);
                            vertexOnBrush = snappedOnBrush;
                        }
                    }
                }

                if (geometryModel == null && vertexOnBrush != null)
                {
                    if (vertexOnBrush.ChildData != null && vertexOnBrush.ChildData.Model)
                    {
                        geometryModel = vertexOnBrush.ChildData.Model;
                    }
                }

                if (worldPosition != prevWorldPosition)
                {
                    prevWorldPosition = worldPosition;
                    if (Event.current.type != EventType.Repaint)
                    {
                        CSG_EditorGUIUtility.RepaintAll();
                    }
                }

                visualSnappedGrid  = RealtimeCSG.CSGGrid.FindAllGridEdgesThatTouchPoint(camera, worldPosition);
                visualSnappedBrush = vertexOnBrush;
            }

            RealtimeCSG.CSGGrid.SetForcedGrid(camera, hoverBuildPlane);


            if (!SceneDragToolManager.IsDraggingObjectInScene &&
                Event.current.type == EventType.Repaint)
            {
                PaintSnapVisualisation();
                PaintCircle(sceneView, base.shapeId);
            }


            var type = Event.current.GetTypeForControl(base.shapeId);

            switch (type)
            {
            case EventType.Layout:
            {
                return;
            }

            case EventType.ValidateCommand:
            case EventType.KeyDown:
            {
                if (GUIUtility.hotControl == base.shapeId)
                {
                    if (Keys.PerformActionKey.IsKeyPressed() ||
                        Keys.DeleteSelectionKey.IsKeyPressed() ||
                        Keys.CancelActionKey.IsKeyPressed())
                    {
                        Event.current.Use();
                    }
                }
                return;
            }

            case EventType.KeyUp:
            {
                if (GUIUtility.hotControl == base.shapeId)
                {
                    if (Keys.CylinderBuilderMode.IsKeyPressed() ||
                        Keys.PerformActionKey.IsKeyPressed())
                    {
                        HotKeyReleased();
                        Event.current.Use();
                        return;
                    }
                    if (Keys.DeleteSelectionKey.IsKeyPressed() ||
                        Keys.CancelActionKey.IsKeyPressed())
                    {
                        Cancel();
                        Event.current.Use();
                        return;
                    }
                }
                return;
            }

            case EventType.MouseDown:
            {
                if (!sceneRect.Contains(Event.current.mousePosition))
                {
                    break;
                }
                if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
                {
                    return;
                }
                if ((GUIUtility.hotControl != 0 && GUIUtility.hotControl != shapeEditId && GUIUtility.hotControl != base.shapeId) ||
                    Event.current.button != 0)
                {
                    return;
                }

                Event.current.Use();
                if (settings.vertices.Length == 0)
                {
                    if ((GUIUtility.hotControl == 0 ||
                         GUIUtility.hotControl == base.shapeEditId) && base.shapeId != -1)
                    {
                        base.CalculateWorldSpaceTangents(camera);
                        GUIUtility.hotControl             = base.shapeId;
                        GUIUtility.keyboardControl        = base.shapeId;
                        EditorGUIUtility.editingTextField = false;
                    }
                }

                if (GUIUtility.hotControl == base.shapeId && settings.vertices.Length < 2)
                {
                    if (!float.IsNaN(worldPosition.x) && !float.IsInfinity(worldPosition.x) &&
                        !float.IsNaN(worldPosition.y) && !float.IsInfinity(worldPosition.y) &&
                        !float.IsNaN(worldPosition.z) && !float.IsInfinity(worldPosition.z))
                    {
                        if (hoverBuildPlane.normal.sqrMagnitude != 0)
                        {
                            buildPlane = hoverBuildPlane;
                        }
                        CalculateWorldSpaceTangents(camera);

                        if (settings.vertices.Length == 0)
                        {
                            if (pointOnEdge)
                            {
                                firstSnappedEdges  = visualSnappedEdges.ToArray();
                                firstSnappedBrush  = visualSnappedBrush;
                                firstSnappedPlanes = null;
                            }
                            else
                            {
                                firstSnappedBrush  = null;
                                firstSnappedEdges  = null;
                                firstSnappedPlanes = null;
                            }
                            geometryPlane   = buildPlane;
                            planeOnGeometry = vertexOnGeometry;
                        }
                        else
                        {
                            if (firstSnappedEdges != null)
                            {
                                if (firstSnappedPlanes == null)
                                {
                                    CreateSnappedPlanes();
                                }

                                bool outside = true;
                                for (int i = 0; i < firstSnappedPlanes.Length; i++)
                                {
                                    if (firstSnappedPlanes[i].Distance(worldPosition) <= MathConstants.DistanceEpsilon)
                                    {
                                        outside = false;
                                        break;
                                    }
                                }

                                planeOnGeometry = !outside;
                            }

                            if (vertexOnGeometry)
                            {
                                var plane    = hoverDefaultPlane.Value;
                                var distance = plane.Distance(worldPosition);
                                plane.d          += distance;
                                hoverDefaultPlane = plane;

                                for (int i = 0; i < settings.vertices.Length; i++)
                                {
                                    if (!settings.onGeometryVertices[i])
                                    {
                                        settings.vertices[i]           = GeometryUtility.ProjectPointOnPlane(plane, settings.vertices[i]);
                                        settings.onGeometryVertices[i] = true;
                                    }
                                }
                            }
                        }
                        ArrayUtility.Add(ref settings.onGeometryVertices, vertexOnGeometry);
                        settings.AddPoint(worldPosition);
                        CSG_EditorGUIUtility.RepaintAll();
                        if (settings.vertices.Length == 2)
                        {
                            HotKeyReleased();
                        }
                    }
                }
                return;
            }

            case EventType.MouseDrag:
            {
                if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
                {
                    break;
                }
                if (GUIUtility.hotControl == base.shapeId && Event.current.button == 0)
                {
                    Event.current.Use();
                }
                return;
            }

            case EventType.MouseUp:
            {
                if (GUIUtility.hotControl != base.shapeId)
                {
                    return;
                }
                if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
                {
                    return;
                }
                if (Event.current.button == 0)
                {
                    Event.current.Use();

                    ResetVisuals();
                    if (onLastPoint)
                    {
                        GUIUtility.hotControl             = 0;
                        GUIUtility.keyboardControl        = 0;
                        EditorGUIUtility.editingTextField = false;

                        editMode = EditMode.CreateShape;
                        HotKeyReleased();
                    }
                }
                return;
            }
            }
        }
示例#4
0
        protected void GrabHeightHandle(int index, bool ignoreFirstMouseUp = false)
        {
            var camera = SceneView.currentDrawingSceneView.camera;

            if (camera == null)
            {
                return;
            }

            firstClick                        = ignoreFirstMouseUp;
            editMode                          = EditMode.ExtrudeShape;
            GUIUtility.hotControl             = extrusionPoints[index].ID;
            GUIUtility.keyboardControl        = extrusionPoints[index].ID;
            EditorGUIUtility.editingTextField = false;
            EditorGUIUtility.SetWantsMouseJumping(1);

            var     surfaceDirection = buildPlane.normal;
            var     closestAxisForward = GeometryUtility.SnapToClosestAxis(-camera.transform.forward);
            var     closestAxisArrow = GeometryUtility.SnapToClosestAxis(surfaceDirection);
            Vector3 tangent, normal;
            float   dot = Mathf.Abs(Vector3.Dot(closestAxisForward, closestAxisArrow));

            if (dot != 1)
            {
                Vector3 v1, v2;
                if (closestAxisForward.x == 0 && closestAxisForward.y == 0)
                {
                    v1 = new Vector3(1, 0, 0);
                    v2 = new Vector3(0, 1, 0);
                }
                else
                if (closestAxisForward.x == 0 && closestAxisForward.z == 0)
                {
                    v1 = new Vector3(1, 0, 0);
                    v2 = new Vector3(0, 0, 1);
                }
                else
                //if (closestAxisForward.y == 0 && closestAxisForward.z == 0)
                {
                    v1 = new Vector3(0, 1, 0);
                    v2 = new Vector3(0, 0, 1);
                }

                var   backward = -camera.transform.forward;
                float dot1     = Vector3.Dot(backward, v1);
                float dot2     = Vector3.Dot(backward, v2);
                if (dot1 < dot2)
                {
                    tangent = v1;
                }
                else
                {
                    tangent = v2;
                }
            }
            else
            {
                tangent = GeometryUtility.SnapToClosestAxis(Vector3.Cross(surfaceDirection, -camera.transform.forward));
            }

            normal = Vector3.Cross(surfaceDirection, tangent);

            if (camera.orthographic)
            {
                normal = -camera.transform.forward;
            }

            if (normal == MathConstants.zeroVector3)
            {
                normal = GeometryUtility.SnapToClosestAxis(-camera.transform.forward);
            }

            movePlane = new CSGPlane(normal, extrusionPoints[index].Position);
            if (!camera.orthographic && Mathf.Abs(movePlane.Distance(camera.transform.position)) < 2.0f)
            {
                var new_tangent = Vector3.Cross(normal, closestAxisForward);
                if (new_tangent != MathConstants.zeroVector3)
                {
                    tangent   = new_tangent;
                    normal    = Vector3.Cross(surfaceDirection, tangent);
                    movePlane = new CSGPlane(normal, extrusionPoints[index].Position);
                }
            }

            movePolygonDirection = haveForcedDirection ? forcedDirection : buildPlane.normal;

            if (!isFinished)
            {
                Grid.SetForcedGrid(movePlane);
            }

            var plane = new CSGPlane(buildPlane.normal, extrusionPoints[index].Position);

            heightPosition = Event.current.mousePosition;

            heightHandleOffset = (plane.Distance(GetHeightHandlePosition(extrusionPoints[index].Position)) * movePolygonDirection);

            if (float.IsInfinity(heightHandleOffset.x) || float.IsNaN(heightHandleOffset.x) ||
                float.IsInfinity(heightHandleOffset.y) || float.IsNaN(heightHandleOffset.y) ||
                float.IsInfinity(heightHandleOffset.z) || float.IsNaN(heightHandleOffset.z))
            {
                heightHandleOffset = Vector3.zero;
            }
        }
示例#5
0
        public Vector3[] GetVertices(CSGPlane buildPlane, Vector3 worldPosition, Vector3 gridTangent, Vector3 gridBinormal, out bool isValid)
        {
            if (vertices.Length < 1)
            {
                isValid = false;
                return(vertices);
            }

            if (circleSides < 3)
            {
                circleSides = 3;
            }

            //var tangent = GeometryUtility.CalculateTangent(buildPlane.normal);

            var vertex1 = (vertices.Length > 1) ? vertices[1] : worldPosition;

            var delta = (vertex1 - vertices[0]);

            radiusA = delta.magnitude;

            if (radiusA <= MathConstants.DistanceEpsilon)
            {
                isValid = false;
                return(new Vector3[0]);
            }


            var matrix       = GeometryUtility.Rotate2DToPlaneMatrix(buildPlane);
            var realVertices = new Vector3[circleSides];

            float angle_offset = GeometryUtility.SignedAngle(gridTangent, delta / radiusA, buildPlane.normal);

            if (circleDistanceToSide)
            {
                angle_offset += 90;
                if ((circleSides & 1) != 1)
                {
                    angle_offset += (180.0f / circleSides);
                }
            }
            else
            {
                angle_offset -= 90;
            }

            angle_offset += circleOffset;
            angle_offset *= Mathf.Deg2Rad;

            Vector3 p1 = MathConstants.zeroVector3;

            for (int i = 0; i < circleSides; i++)
            {
                var angle = ((i * Mathf.PI * 2.0f) / (float)circleSides) + angle_offset;

                p1.x = (Mathf.Sin(angle) * radiusA);
                p1.z = (Mathf.Cos(angle) * radiusA);

                realVertices[i] = p1;
            }

            if (circleRecenter)
            {
                var dirx = matrix.MultiplyVector(delta.normalized);
                var dirz = Vector3.Cross(Vector3.up, dirx);

                float minx = float.PositiveInfinity;
                float minz = float.PositiveInfinity;
                float maxx = float.NegativeInfinity;
                float maxz = float.NegativeInfinity;
                for (int i = 0; i < circleSides; i++)
                {
                    var point = realVertices[i];
                    var x     = Vector3.Dot(point, dirx);
                    var z     = Vector3.Dot(point, dirz);

                    minx = Mathf.Min(x, minx);
                    minz = Mathf.Min(z, minz);

                    maxx = Mathf.Max(x, maxx);
                    maxz = Mathf.Max(z, maxz);
                }

                var scalex  = (radiusA * 2) / (maxx - minx);
                var scalez  = (radiusA * 2) / (maxz - minz);
                var centerx = ((maxx + minx) * -0.5f) * dirx;
                var centerz = ((maxz + minz) * -0.5f) * dirz;

                for (int i = 0; i < circleSides; i++)
                {
                    var point = realVertices[i];
                    var x     = Vector3.Dot(point, dirx);
                    var z     = Vector3.Dot(point, dirz);


                    var ptx = x * dirx;
                    var ptz = z * dirz;

                    ptx            += centerx;
                    ptz            += centerz;
                    ptx            *= scalex;
                    ptz            *= scalez;
                    realVertices[i] = ptx + ptz;
                }
            }

            for (int i = 0; i < circleSides; i++)
            {
                var point = realVertices[i];
                realVertices[i] = GeometryUtility.ProjectPointOnPlane(buildPlane, vertices[0] + matrix.MultiplyPoint(point));
            }

            isValid = true;
            return(realVertices);
        }
示例#6
0
        internal override bool CreateControlMeshForBrushIndex(CSGModel parentModel, CSGBrush brush, ShapePolygon polygon, Matrix4x4 localToWorld, float height, out ControlMesh newControlMesh, out Shape newShape)
        {
            bool smooth            = settings.circleSmoothShading;
            bool singleSurfaceEnds = settings.circleSingleSurfaceEnds;
            var  direction         = haveForcedDirection ? forcedDirection : buildPlane.normal;

            if (!ShapePolygonUtility.GenerateControlMeshFromVertices(polygon,
                                                                     localToWorld,
                                                                     GeometryUtility.RotatePointIntoPlaneSpace(buildPlane, direction),
                                                                     height,

                                                                     new TexGen(),

                                                                     smooth,
                                                                     singleSurfaceEnds,
                                                                     out newControlMesh,
                                                                     out newShape))
            {
                return(false);
            }

            var parentScale    = parentTransform.lossyScale;
            var parentInverted = (Math.Sign(parentScale.x) * Math.Sign(parentScale.y) * Math.Sign(parentScale.z)) < 0;

            if (parentInverted)
            {
                ControlMeshUtility.InvertControlMesh(newControlMesh);
                ControlMeshUtility.InvertShape(newShape);
            }

            brush.Shape       = newShape;
            brush.ControlMesh = newControlMesh;
            InternalCSGModelManager.ValidateBrush(brush, true);
            ControlMeshUtility.RebuildShape(brush);

            var   vertices      = polygon.Vertices;
            float circumference = 0.0f;

            for (int j = vertices.Length - 1, i = 0; i < vertices.Length; j = i, i++)
            {
                circumference += (vertices[j] - vertices[i]).magnitude;
            }

            var shape = brush.Shape;

            float desiredTextureLength = Mathf.Max(1.0f, Mathf.Round(circumference));
            float scalar = desiredTextureLength / circumference;

            shape.TexGens[0].Scale.x       = scalar;
            shape.TexGens[0].Scale.y       = shape.TexGens[0].Scale.y;
            shape.TexGens[0].Translation.x = 0;

            var count = vertices.Length;

            if (!singleSurfaceEnds)
            {
                GeometryUtility.ContinueTexGenFromSurfaceToSurface(brush, 0, count);
                GeometryUtility.ContinueTexGenFromSurfaceToSurface(brush, 0, count + count);
                for (int j = 0, i = 1; i < count; j = i, i++)
                {
                    GeometryUtility.ContinueTexGenFromSurfaceToSurface(brush, j, i);
                    GeometryUtility.ContinueTexGenFromSurfaceToSurface(brush, i, i + count);
                    GeometryUtility.ContinueTexGenFromSurfaceToSurface(brush, i, i + count + count);
                }
            }
            else
            {
                for (int j = 0, i = 1; i < count; j = i, i++)
                {
                    GeometryUtility.ContinueTexGenFromSurfaceToSurface(brush, j, i);
                }
            }

            return(true);
        }
示例#7
0
        internal static bool CreateControlMeshFromPlanes(out ControlMesh controlMesh,
                                                         out Shape shape,
                                                         UnityEngine.Plane[]    planes,
                                                         Vector3[]                              tangents        = null,
                                                         Vector3[]                              binormals       = null,
                                                         Material[]                             materials       = null,
                                                         Matrix4x4[]                    textureMatrices         = null,
                                                         TextureMatrixSpace textureMatrixSpace                  = TextureMatrixSpace.WorldSpace,
                                                         uint[]                                 smoothingGroups = null,
                                                         TexGenFlags[]                  texGenFlags             = null)
        {
            controlMesh = null;
            shape       = null;
            if (planes == null)
            {
                Debug.LogError("The planes array is not allowed to be null");
                return(false);
            }
            if (planes.Length < 4)
            {
                Debug.LogError("The planes array must have at least 4 planes");
                return(false);
            }
            if (materials == null)
            {
                materials = new Material[planes.Length];
                for (int i = 0; i < materials.Length; i++)
                {
                    materials[i] = CSGSettings.DefaultMaterial;
                }
            }
            if (planes.Length != materials.Length ||
                (textureMatrices != null && planes.Length != textureMatrices.Length) ||
                (tangents != null && tangents.Length != textureMatrices.Length) ||
                (binormals != null && binormals.Length != textureMatrices.Length) ||
                (smoothingGroups != null && smoothingGroups.Length != materials.Length))
            {
                Debug.LogError("All non null arrays need to be of equal length");
                return(false);
            }

            shape             = new Shape();
            shape.Materials   = materials;
            shape.TexGenFlags = new TexGenFlags[planes.Length];
            shape.Surfaces    = new Surface[planes.Length];
            shape.TexGens     = new TexGen[planes.Length];
            for (int i = 0; i < planes.Length; i++)
            {
                shape.Surfaces[i].Plane = new CSGPlane(planes[i].normal, -planes[i].distance);
                Vector3 tangent, binormal;
                if (tangents != null && binormals != null)
                {
                    tangent  = tangents[i];
                    binormal = binormals[i];
                }
                else
                {
                    GeometryUtility.CalculateTangents(planes[i].normal, out tangent, out binormal);
                }

                shape.Surfaces[i].Tangent     = -tangent;
                shape.Surfaces[i].BiNormal    = -binormal;
                shape.Surfaces[i].TexGenIndex = i;
                shape.TexGens[i] = new TexGen(-1);
                if (smoothingGroups != null)
                {
                    shape.TexGens[i].SmoothingGroup = smoothingGroups[i];
                }
                if (texGenFlags != null)
                {
                    shape.TexGenFlags[i] = texGenFlags[i];
                }
            }

            controlMesh = ControlMeshUtility.CreateFromShape(shape);
            if (controlMesh == null || !ControlMeshUtility.Validate(controlMesh, shape))
            {
                return(false);
            }

            if (textureMatrices != null)
            {
                for (var i = 0; i < planes.Length; i++)
                {
                    SurfaceUtility.AlignTextureSpaces(textureMatrices[i], textureMatrixSpace == TextureMatrixSpace.PlaneSpace, ref shape.TexGens[i], ref shape.TexGenFlags[i], ref shape.Surfaces[i]);
                }
            }
            ShapeUtility.CreateCutter(shape, controlMesh);
            return(true);
        }
示例#8
0
        internal static void CreateCubeControlMesh(out ControlMesh controlMesh, out Shape shape, Vector3 size)
        {
            size                *= 0.5f;
            controlMesh          = new ControlMesh();
            controlMesh.Vertices = new Vector3[]
            {
                new Vector3(-size.x, -size.y, -size.z),
                new Vector3(-size.x, size.y, -size.z),
                new Vector3(size.x, size.y, -size.z),
                new Vector3(size.x, -size.y, -size.z),

                new Vector3(-size.x, -size.y, size.z),
                new Vector3(-size.x, size.y, size.z),
                new Vector3(size.x, size.y, size.z),
                new Vector3(size.x, -size.y, size.z)
            };

            controlMesh.Edges = new HalfEdge[]
            {
                new HalfEdge(0, 21, 0, true),                   //  0
                new HalfEdge(0, 9, 1, true),                    //  1
                new HalfEdge(0, 13, 2, true),                   //  2
                new HalfEdge(0, 17, 3, true),                   //  3

                new HalfEdge(1, 23, 7, true),                   //  4
                new HalfEdge(1, 19, 6, true),                   //  5
                new HalfEdge(1, 15, 5, true),                   //  6
                new HalfEdge(1, 11, 4, true),                   //  7

                new HalfEdge(2, 14, 1, true),                   //  8
                new HalfEdge(2, 1, 0, true),                    //  9
                new HalfEdge(2, 20, 4, true),                   // 10
                new HalfEdge(2, 7, 5, true),                    // 11

                new HalfEdge(3, 18, 2, true),                   // 12
                new HalfEdge(3, 2, 1, true),                    // 13
                new HalfEdge(3, 8, 5, true),                    // 14
                new HalfEdge(3, 6, 6, true),                    // 15

                new HalfEdge(4, 22, 3, true),                   // 16
                new HalfEdge(4, 3, 2, true),                    // 17
                new HalfEdge(4, 12, 6, true),                   // 18
                new HalfEdge(4, 5, 7, true),                    // 19

                new HalfEdge(5, 10, 0, true),                   // 20
                new HalfEdge(5, 0, 3, true),                    // 21
                new HalfEdge(5, 16, 7, true),                   // 22
                new HalfEdge(5, 4, 4, true)                     // 23
            };

            controlMesh.Polygons = new Polygon[]
            {
                // left/right
                new Polygon(new int[] { 0, 1, 2, 3 }, 0),                       // 0
                new Polygon(new int[] { 7, 4, 5, 6 }, 1),                       // 1

                // front/back
                new Polygon(new int[] { 9, 10, 11, 8 }, 2),                     // 2
                new Polygon(new int[] { 13, 14, 15, 12 }, 3),                   // 3

                // top/down
                new Polygon(new int[] { 16, 17, 18, 19 }, 4),                   // 4
                new Polygon(new int[] { 20, 21, 22, 23 }, 5)                    // 5
            };

            shape = new Shape();

            shape.Surfaces = new Surface[6];
            shape.Surfaces[0].TexGenIndex = 0;
            shape.Surfaces[1].TexGenIndex = 1;
            shape.Surfaces[2].TexGenIndex = 2;
            shape.Surfaces[3].TexGenIndex = 3;
            shape.Surfaces[4].TexGenIndex = 4;
            shape.Surfaces[5].TexGenIndex = 5;

            shape.Surfaces[0].Plane = GeometryUtility.CalcPolygonPlane(controlMesh, 0);
            shape.Surfaces[1].Plane = GeometryUtility.CalcPolygonPlane(controlMesh, 1);
            shape.Surfaces[2].Plane = GeometryUtility.CalcPolygonPlane(controlMesh, 2);
            shape.Surfaces[3].Plane = GeometryUtility.CalcPolygonPlane(controlMesh, 3);
            shape.Surfaces[4].Plane = GeometryUtility.CalcPolygonPlane(controlMesh, 4);
            shape.Surfaces[5].Plane = GeometryUtility.CalcPolygonPlane(controlMesh, 5);

            GeometryUtility.CalculateTangents(shape.Surfaces[0].Plane.normal, out shape.Surfaces[0].Tangent, out shape.Surfaces[0].BiNormal);
            GeometryUtility.CalculateTangents(shape.Surfaces[1].Plane.normal, out shape.Surfaces[1].Tangent, out shape.Surfaces[1].BiNormal);
            GeometryUtility.CalculateTangents(shape.Surfaces[2].Plane.normal, out shape.Surfaces[2].Tangent, out shape.Surfaces[2].BiNormal);
            GeometryUtility.CalculateTangents(shape.Surfaces[3].Plane.normal, out shape.Surfaces[3].Tangent, out shape.Surfaces[3].BiNormal);
            GeometryUtility.CalculateTangents(shape.Surfaces[4].Plane.normal, out shape.Surfaces[4].Tangent, out shape.Surfaces[4].BiNormal);
            GeometryUtility.CalculateTangents(shape.Surfaces[5].Plane.normal, out shape.Surfaces[5].Tangent, out shape.Surfaces[5].BiNormal);

            shape.TexGens          = new TexGen[6];
            shape.TexGens[0].Scale = MathConstants.oneVector3;
            shape.TexGens[1].Scale = MathConstants.oneVector3;
            shape.TexGens[2].Scale = MathConstants.oneVector3;
            shape.TexGens[3].Scale = MathConstants.oneVector3;
            shape.TexGens[4].Scale = MathConstants.oneVector3;
            shape.TexGens[5].Scale = MathConstants.oneVector3;


            shape.TexGens[0].Color = Color.white;
            shape.TexGens[1].Color = Color.white;
            shape.TexGens[2].Color = Color.white;
            shape.TexGens[3].Color = Color.white;
            shape.TexGens[4].Color = Color.white;
            shape.TexGens[5].Color = Color.white;


            shape.TexGenFlags    = new TexGenFlags[6];
            shape.TexGenFlags[0] = TexGenFlags.None;
            shape.TexGenFlags[1] = TexGenFlags.None;
            shape.TexGenFlags[2] = TexGenFlags.None;
            shape.TexGenFlags[3] = TexGenFlags.None;
            shape.TexGenFlags[4] = TexGenFlags.None;
            shape.TexGenFlags[5] = TexGenFlags.None;

            shape.Materials    = new Material[6];
            shape.Materials[0] = CSGSettings.DefaultMaterial;
            shape.Materials[1] = CSGSettings.DefaultMaterial;
            shape.Materials[2] = CSGSettings.DefaultMaterial;
            shape.Materials[3] = CSGSettings.DefaultMaterial;
            shape.Materials[4] = CSGSettings.DefaultMaterial;
            shape.Materials[5] = CSGSettings.DefaultMaterial;

            //controlMesh.Validate();
            ShapeUtility.CreateCutter(shape, controlMesh);
            ShapeUtility.EnsureInitialized(shape);
            controlMesh.IsValid = ControlMeshUtility.Validate(controlMesh, shape);
        }
示例#9
0
        public static Vector3 SnapDeltaToRayGrid(Ray worldRay, Vector3 worldDeltaMovement, Vector3[] worldPoints, bool snapToSelf = false)
        {
            UpdateGridOrientation();
            if (gridOrientation == null || worldPoints == null || worldPoints.Length == 0)
            {
                return(worldDeltaMovement);
            }

            var snapVector  = gridOrientation.gridSnapVector;
            var scaleVector = gridOrientation.gridSnapScale;

            var localDeltaMovement = VectorToGridSpace(worldDeltaMovement);
            var localLineDir       = VectorToGridSpace(worldRay.direction);
            var localLineOrg       = PointToGridSpace(worldRay.origin);

            scaleVector.x *= ((Mathf.Abs(localLineDir.y) >= 1 - MathConstants.EqualityEpsilon) || (Mathf.Abs(localLineDir.z) >= 1 - MathConstants.EqualityEpsilon)) ? 0 : 1;
            scaleVector.y *= ((Mathf.Abs(localLineDir.x) >= 1 - MathConstants.EqualityEpsilon) || (Mathf.Abs(localLineDir.z) >= 1 - MathConstants.EqualityEpsilon)) ? 0 : 1;
            scaleVector.z *= ((Mathf.Abs(localLineDir.x) >= 1 - MathConstants.EqualityEpsilon) || (Mathf.Abs(localLineDir.y) >= 1 - MathConstants.EqualityEpsilon)) ? 0 : 1;

            var snappedDeltaMovement = localDeltaMovement;

            if (Mathf.Abs(scaleVector.x) < MathConstants.EqualityEpsilon)
            {
                snappedDeltaMovement.x = 0;
            }
            if (Mathf.Abs(scaleVector.y) < MathConstants.EqualityEpsilon)
            {
                snappedDeltaMovement.y = 0;
            }
            if (Mathf.Abs(scaleVector.z) < MathConstants.EqualityEpsilon)
            {
                snappedDeltaMovement.z = 0;
            }

            Vector3[] localPoints;
            if (worldPoints.Length > 1)
            {
                var bounds = new AABB();
                bounds.Reset();
                for (int i = 0; i < worldPoints.Length; i++)
                {
                    var localPoint = GeometryUtility.ProjectPointOnInfiniteLine(PointToGridSpace(worldPoints[i]), localLineOrg, localLineDir);
                    bounds.Extend(localPoint);
                }
                localPoints = bounds.GetCorners();
            }
            else
            {
                localPoints = new Vector3[] { GeometryUtility.ProjectPointOnInfiniteLine(PointToGridSpace(worldPoints[0]), localLineOrg, localLineDir) };
            }

            for (int i = 0; i < localPoints.Length; i++)
            {
                var oldPoint = localPoints[i];
                var newPoint = GeometryUtility.ProjectPointOnInfiniteLine(oldPoint + localDeltaMovement, localLineOrg, localLineDir);

                var snappedNewPoint = SnapRoundPosition(newPoint, snapVector);

                snappedNewPoint = GridUtility.CleanPosition(GeometryUtility.ProjectPointOnInfiniteLine(snappedNewPoint, localLineOrg, localLineDir));

                var foundDeltaMovement = (snappedNewPoint - oldPoint);

                foundDeltaMovement.x *= scaleVector.x;
                foundDeltaMovement.y *= scaleVector.y;
                foundDeltaMovement.z *= scaleVector.z;

                if (i == 0 || Math.Abs(foundDeltaMovement.x) < Mathf.Abs(snappedDeltaMovement.x))
                {
                    snappedDeltaMovement.x = foundDeltaMovement.x;
                }
                if (i == 0 || Math.Abs(foundDeltaMovement.y) < Mathf.Abs(snappedDeltaMovement.y))
                {
                    snappedDeltaMovement.y = foundDeltaMovement.y;
                }
                if (i == 0 || Math.Abs(foundDeltaMovement.z) < Mathf.Abs(snappedDeltaMovement.z))
                {
                    snappedDeltaMovement.z = foundDeltaMovement.z;
                }
            }

            if (snapToSelf)
            {
                var snapDelta = (snappedDeltaMovement - localDeltaMovement);
                if (Mathf.Abs(snapDelta.x) > Mathf.Abs(localDeltaMovement.x))
                {
                    snappedDeltaMovement.x = 0;
                }
                if (Mathf.Abs(snapDelta.y) > Mathf.Abs(localDeltaMovement.y))
                {
                    snappedDeltaMovement.y = 0;
                }
                if (Mathf.Abs(snapDelta.z) > Mathf.Abs(localDeltaMovement.z))
                {
                    snappedDeltaMovement.z = 0;
                }
            }

            worldDeltaMovement = VectorFromGridSpace(snappedDeltaMovement);
            return(worldDeltaMovement);
        }
        /*
         * public static bool ContinueTexGenFromSurfaceToSurface(CSGBrush srcBrush, int srcSurfaceIndex, CSGBrush dstBrush, int dstSurfaceIndex)
         * {
         *  if (srcSurfaceIndex < 0 || srcSurfaceIndex >= srcBrush.Shape.Materials.Length ||
         *      srcBrush == null)
         *      return false;
         *
         *  var src_brush_cache = CSGModelManager.GetBrushCache(srcBrush);
         *  if (src_brush_cache == null ||
         *      src_brush_cache.childData == null ||
         *      src_brush_cache.childData.modelTransform == null)
         *      return false;
         *
         *  var dst_brush_cache = CSGModelManager.GetBrushCache(dstBrush);
         *  if (dst_brush_cache == null ||
         *      dst_brush_cache.childData == null ||
         *      dst_brush_cache.childData.modelTransform == null)
         *      return false;
         *
         *  var dstPlane	= dstBrush.Shape.Surfaces[dstSurfaceIndex].Plane;
         *  var srcPlane	= srcBrush.Shape.Surfaces[srcSurfaceIndex].Plane;
         *
         *  // convert planes into worldspace
         *  dstPlane = GeometryUtility.InverseTransformPlane(dstBrush.transform.worldToLocalMatrix, dstPlane);
         *  srcPlane = GeometryUtility.InverseTransformPlane(srcBrush.transform.worldToLocalMatrix, srcPlane);
         *
         *  var dstNormal	= dstPlane.normal;
         *  var srcNormal	= srcPlane.normal;
         *
         *  var srcTexGenIndex = srcBrush.Shape.Surfaces[srcSurfaceIndex].TexGenIndex;
         *  var dstTexGenIndex = dstBrush.Shape.Surfaces[dstSurfaceIndex].TexGenIndex;
         *
         *  var scrShape = srcBrush.Shape;
         *
         *  dstBrush.Shape.Materials[dstSurfaceIndex] = scrShape.Materials[srcSurfaceIndex];
         *  Vector3 srcPoint1, srcPoint2;
         *  Vector3 dstPoint1, dstPoint2;
         *  var edgeDirection = Vector3.Cross(dstNormal, srcNormal);
         *  var det = edgeDirection.sqrMagnitude;
         *  if (det < Constants.AlignmentTestEpsilon)
         *  {
         *      // Find 2 points on intersection of 2 planes
         *      srcPoint1 = srcPlane.pointOnPlane;
         *      srcPoint2 = GeometryUtility.ProjectPointOnPlane(srcPlane, srcPoint1 + MathConstants.oneVector3);
         *
         *      dstPoint1 = GeometryUtility.ProjectPointOnPlane(dstPlane, srcPoint1);
         *      dstPoint2 = GeometryUtility.ProjectPointOnPlane(dstPlane, srcPoint2);
         *  } else
         *  {
         *      // Find 2 points on intersection of 2 planes
         *      srcPoint1 = ((Vector3.Cross(edgeDirection, srcNormal) * -dstPlane.d) +
         *                      (Vector3.Cross(dstNormal, edgeDirection) * -srcPlane.d)) / det;
         *      srcPoint2 = srcPoint1 + edgeDirection;
         *      dstPoint1 = srcPoint1;
         *      dstPoint2 = srcPoint2;
         *  }
         *
         *  Vector3 srcLocalPoint1 = srcBrush.transform.InverseTransformPoint(srcPoint1);
         *  Vector3 srcLocalPoint2 = srcBrush.transform.InverseTransformPoint(srcPoint2);
         *
         *  Vector3 dstLocalPoint1 = dstBrush.transform.InverseTransformPoint(dstPoint1);
         *  Vector3 dstLocalPoint2 = dstBrush.transform.InverseTransformPoint(dstPoint2);
         *
         *  var srcShape	= srcBrush.Shape;
         *  var srcTexGens	= srcShape.TexGens;
         *  var srcSurfaces	= srcShape.Surfaces;
         *  var dstShape	= dstBrush.Shape;
         *  var dstTexGens	= dstShape.TexGens;
         *  var dstSurfaces	= dstShape.Surfaces;
         *
         *
         *  // Reset destination shape to simplify calculations
         *  dstTexGens[dstTexGenIndex].Scale			= scrShape.TexGens[srcTexGenIndex].Scale;
         *  dstTexGens[dstTexGenIndex].Translation		= MathConstants.zeroVector2;
         *  dstTexGens[dstTexGenIndex].RotationAngle	= 0;
         *
         *  if (!CSGModelManager.AlignTextureSpacesInLocalSpace(ref srcTexGens[srcTexGenIndex], ref srcSurfaces[srcSurfaceIndex],
         *                                                      srcLocalPoint1, srcLocalPoint2,
         *                                                      ref dstTexGens[dstTexGenIndex], ref dstSurfaces[dstSurfaceIndex],
         *                                                      dstLocalPoint1, dstLocalPoint2))
         *      return false;
         *  return true;
         * }
         */

        public static bool ContinueTexGenFromSurfaceToSurface(CSGBrush brush, int srcSurfaceIndex, int dstSurfaceIndex)
        {
            if (srcSurfaceIndex < 0 || srcSurfaceIndex >= brush.Shape.TexGens.Length ||
                !brush)
            {
                return(false);
            }

            var shape       = brush.Shape;
            var texGens     = shape.TexGens;
            var texGenFlags = shape.TexGenFlags;
            var surfaces    = shape.Surfaces;

            var srcTexGenIndex = surfaces[srcSurfaceIndex].TexGenIndex;
            var dstTexGenIndex = surfaces[dstSurfaceIndex].TexGenIndex;

//          var src_is_world_space = (texGenFlags[srcTexGenIndex] & TexGenFlags.WorldSpaceTexture) != TexGenFlags.None;
//          var dst_is_world_space = (texGenFlags[dstTexGenIndex] & TexGenFlags.WorldSpaceTexture) != TexGenFlags.None;

//          if (src_is_world_space) SurfaceUtility.SetTextureLock(brush, srcSurfaceIndex, true);
//          if (dst_is_world_space) SurfaceUtility.SetTextureLock(brush, dstSurfaceIndex, true);

            var dstLocalPlane = surfaces[dstSurfaceIndex].Plane;
            var srcLocalPlane = surfaces[srcSurfaceIndex].Plane;

            CSGModel     parentModel;
            CSGOperation parentOp;

            InternalCSGModelManager.FindParentOperationAndModel(brush.transform, out parentOp, out parentModel);

            var localFromWorld = brush.transform.worldToLocalMatrix;
            var worldFromModel = parentModel.transform.localToWorldMatrix;
            var modelFromWorld = parentModel.transform.worldToLocalMatrix;
            var localFromModel = localFromWorld * worldFromModel;
            //var localToWorldMatrix = brush.transform.localToWorldMatrix;

            // convert planes into worldspace
            var dstWorldPlane = InverseTransformPlane(localFromWorld, dstLocalPlane);
            var srcWorldPlane = InverseTransformPlane(localFromWorld, srcLocalPlane);

            var dstWorldNormal = dstWorldPlane.normal;
            var srcWorldNormal = srcWorldPlane.normal;


            shape.TexGens[dstSurfaceIndex].RenderMaterial = shape.TexGens[srcSurfaceIndex].RenderMaterial;
            Vector3 srcWorldPoint1, srcWorldPoint2;
            Vector3 dstWorldPoint1, dstWorldPoint2;
            var     edgeDirection = Vector3.Cross(dstWorldNormal, srcWorldNormal);
            var     det           = edgeDirection.sqrMagnitude;

            if (det < MathConstants.AlignmentTestEpsilon)
            {
                // Find 2 points on intersection of 2 planes
                srcWorldPoint1 = srcWorldPlane.pointOnPlane;
                srcWorldPoint2 = GeometryUtility.ProjectPointOnPlane(srcWorldPlane, srcWorldPoint1 + MathConstants.oneVector3);

                dstWorldPoint1 = GeometryUtility.ProjectPointOnPlane(dstWorldPlane, srcWorldPoint1);
                dstWorldPoint2 = GeometryUtility.ProjectPointOnPlane(dstWorldPlane, srcWorldPoint2);
            }
            else
            {
                // Find 2 points on intersection of 2 planes
                srcWorldPoint1 = ((Vector3.Cross(edgeDirection, srcWorldNormal) * -dstWorldPlane.d) +
                                  (Vector3.Cross(dstWorldNormal, edgeDirection) * -srcWorldPlane.d)) / det;
                srcWorldPoint2 = srcWorldPoint1 + edgeDirection;
                dstWorldPoint1 = srcWorldPoint1;
                dstWorldPoint2 = srcWorldPoint2;
            }

            var srcModelPoint1 = modelFromWorld.MultiplyPoint(srcWorldPoint1);
            var srcModelPoint2 = modelFromWorld.MultiplyPoint(srcWorldPoint2);

            var dstModelPoint1 = modelFromWorld.MultiplyPoint(dstWorldPoint1);
            var dstModelPoint2 = modelFromWorld.MultiplyPoint(dstWorldPoint2);

            var result = SurfaceUtility.AlignTextureSpaces(localFromModel, texGens[srcTexGenIndex], texGenFlags[srcTexGenIndex], ref surfaces[srcSurfaceIndex], srcModelPoint1, srcModelPoint2,
                                                           localFromModel, ref texGens[dstTexGenIndex], texGenFlags[dstTexGenIndex], ref surfaces[dstSurfaceIndex], dstModelPoint1, dstModelPoint2, false, Vector3.one);

//          if (src_is_world_space) SurfaceUtility.SetTextureLock(brush, srcSurfaceIndex, false);
//          if (dst_is_world_space) SurfaceUtility.SetTextureLock(brush, dstSurfaceIndex, false);
            return(result);
        }
示例#11
0
        public void UpdatePoints(ControlMesh controlMesh, Vector3[] vertices = null)
        {
            if (controlMesh == null ||
                controlMesh.Vertices == null ||
                controlMesh.Edges == null ||
                controlMesh.Polygons == null ||
                PolygonPointIndices == null)
            {
                return;
            }

            if (vertices == null)
            {
                vertices = controlMesh.Vertices;
            }

            if (!BrushTransform)
            {
                return;
            }


            var pointCount = vertices.Length;

            if (WorldPoints.Length != pointCount)
            {
                AllocatePoints(pointCount);
            }

            var edgeCount = controlMesh.Edges.Length;

            if (Edges.Length != edgeCount)
            {
                AllocateEdges(edgeCount);
            }

            var polygonCount = controlMesh.Polygons.Length;

            if (PolygonControlId.Length != polygonCount)
            {
                AllocatePolygons(polygonCount);
            }


            var localToWorldMatrix = BrushTransform.localToWorldMatrix;

            for (var p = 0; p < pointCount; p++)
            {
                var worldPoint = localToWorldMatrix.MultiplyPoint(vertices[p]);
                WorldPoints[p] = worldPoint;
            }


            var brushTotalLength = 0.0f;

            BrushCenter = MathConstants.zeroVector3;
            for (var p = 0; p < polygonCount; p++)
            {
                var localCenterPoint = MathConstants.zeroVector3;
                var totalLength      = 0.0f;
                var polygon          = controlMesh.Polygons[p];
                if (polygon == null)
                {
                    continue;
                }

                var edgeIndices = polygon.EdgeIndices;
                if (edgeIndices == null ||
                    edgeIndices.Length == 0)
                {
                    continue;
                }

                var halfEdgeIndex0 = edgeIndices[edgeIndices.Length - 1];
                if (halfEdgeIndex0 < 0 || halfEdgeIndex0 >= controlMesh.Edges.Length)
                {
                    continue;
                }

                var vertexIndex0 = controlMesh.Edges[halfEdgeIndex0].VertexIndex;
                if (vertexIndex0 < 0 || vertexIndex0 >= vertices.Length)
                {
                    continue;
                }

                var vertex0 = vertices[vertexIndex0];

                if (PolygonPointIndices[p] == null ||
                    PolygonPointIndices[p].Length != edgeIndices.Length)
                {
                    PolygonPointIndices[p] = new int[edgeIndices.Length];
                }

                var newPointIndices = PolygonPointIndices[p];
                for (var i = 0; i < edgeIndices.Length; i++)
                {
                    var halfEdgeIndex1 = edgeIndices[i];
                    if (halfEdgeIndex1 < 0 ||
                        halfEdgeIndex1 >= controlMesh.Edges.Length)
                    {
                        continue;
                    }

                    var vertexIndex1 = controlMesh.Edges[halfEdgeIndex1].VertexIndex;
                    if (vertexIndex1 < 0 ||
                        vertexIndex1 >= vertices.Length)
                    {
                        continue;
                    }

                    var vertex1 = vertices[vertexIndex1];
                    newPointIndices[i] = vertexIndex1;

                    var length = (vertex1 - vertex0).sqrMagnitude;
                    localCenterPoint += (vertex1 + vertex0) * 0.5f * length;
                    totalLength      += length;
                    brushTotalLength += length;

                    vertex0 = vertex1;
                }

                var worldCenterPoint = Mathf.Abs(totalLength) < MathConstants.EqualityEpsilon ?
                                       localToWorldMatrix.MultiplyPoint(vertex0) :
                                       localToWorldMatrix.MultiplyPoint(localCenterPoint / totalLength);
                BrushCenter           += localCenterPoint;
                PolygonCenterPoints[p] = worldCenterPoint;
                PolygonCenterPlanes[p] = GeometryUtility.CalcPolygonPlane(controlMesh, (short)p);
            }
            if (Mathf.Abs(brushTotalLength) >= MathConstants.EqualityEpsilon)
            {
                BrushCenter /= brushTotalLength;
            }
            BrushCenter = localToWorldMatrix.MultiplyPoint(BrushCenter);
        }
        static void OnGUIContents(GeneratorCylinder generator, bool isSceneGUI)
        {
            GUILayout.BeginHorizontal(CSG_GUIStyleUtility.ContentEmpty);
            {
                if (isSceneGUI)
                {
                    CylinderSettingsGUI(generator, isSceneGUI);
                }
            }
            GUILayout.EndHorizontal();

            GUILayout.Space(5);

            GUILayout.BeginVertical(CSG_GUIStyleUtility.ContentEmpty);
            {
                var distanceUnit = RealtimeCSG.CSGSettings.DistanceUnit;
                var nextUnit     = Units.CycleToNextUnit(distanceUnit);
                var unitText     = Units.GetUnitGUIContent(distanceUnit);

                GUILayout.BeginHorizontal(CSG_GUIStyleUtility.ContentEmpty);
                {
                    GUILayout.Label(HeightContent, width65);

                    if (isSceneGUI)
                    {
                        TooltipUtility.SetToolTip(HeightTooltip);
                    }

                    var height = generator.HaveHeight ? generator.Height : GeometryUtility.CleanLength(generator.DefaultHeight);
                    EditorGUI.BeginChangeCheck();
                    {
                        if (!isSceneGUI)
                        {
                            height = Units.DistanceUnitToUnity(distanceUnit, EditorGUILayout.DoubleField(Units.UnityToDistanceUnit(distanceUnit, height)));
                        }
                        else
                        {
                            height = Units.DistanceUnitToUnity(distanceUnit, EditorGUILayout.DoubleField(Units.UnityToDistanceUnit(distanceUnit, height), width65));
                        }
                    }

                    if (EditorGUI.EndChangeCheck())
                    {
                        if (generator.HaveHeight)
                        {
                            generator.Height = height;
                        }
                        else
                        {
                            generator.DefaultHeight = height;
                        }
                    }

                    if (GUILayout.Button(unitText, EditorStyles.miniLabel, width25))
                    {
                        distanceUnit = nextUnit;
                        RealtimeCSG.CSGSettings.DistanceUnit = distanceUnit;
                        RealtimeCSG.CSGSettings.UpdateSnapSettings();
                        RealtimeCSG.CSGSettings.Save();
                        CSG_EditorGUIUtility.RepaintAll();
                    }
                }
                GUILayout.EndHorizontal();

                TooltipUtility.SetToolTip(HeightTooltip);

                GUILayout.BeginHorizontal(CSG_GUIStyleUtility.ContentEmpty);
                {
                    EditorGUI.BeginDisabledGroup(!generator.CanCommit);
                    {
                        GUILayout.Label(RadiusContent, width65);

                        if (isSceneGUI)
                        {
                            TooltipUtility.SetToolTip(RadiusTooltip);
                        }

                        var radius = generator.RadiusA;
                        EditorGUI.BeginChangeCheck();
                        {
                            if (!isSceneGUI)
                            {
                                radius = Units.DistanceUnitToUnity(distanceUnit, EditorGUILayout.DoubleField(Units.UnityToDistanceUnit(distanceUnit, radius)));
                            }
                            else
                            {
                                radius = Units.DistanceUnitToUnity(distanceUnit, EditorGUILayout.DoubleField(Units.UnityToDistanceUnit(distanceUnit, radius), width65));
                            }
                        }

                        if (EditorGUI.EndChangeCheck())
                        {
                            generator.RadiusA = radius;
                        }

                        if (GUILayout.Button(unitText, EditorStyles.miniLabel, width25))
                        {
                            distanceUnit = nextUnit;
                            RealtimeCSG.CSGSettings.DistanceUnit = distanceUnit;
                            RealtimeCSG.CSGSettings.UpdateSnapSettings();
                            RealtimeCSG.CSGSettings.Save();
                            CSG_EditorGUIUtility.RepaintAll();
                        }
                    }
                    EditorGUI.EndDisabledGroup();
                }
                GUILayout.EndHorizontal();

                if (!isSceneGUI)
                {
                    TooltipUtility.SetToolTip(RadiusTooltip);
                }
            }

            GUILayout.EndVertical();
            {
                generator.CircleSides = IntSettingsControl
                                        (
                    generator.CircleSides,
                    3,
                    RealtimeCSG.CSGSettings.MaxCircleSides,
                    SidesContent,
                    isSceneGUI
                                        );

                TooltipUtility.SetToolTip(SidesTooltip);
            }
            generator.CircleOffset = FloatSettingsControl
                                     (
                generator.CircleOffset,
                0,
                360,
                OffsetContent,
                isSceneGUI
                                     );

            TooltipUtility.SetToolTip(OffsetTooltip);


            if (!isSceneGUI)
            {
                GUILayout.Space(5);

                CylinderSettingsGUI(generator, isSceneGUI);
            }
        }
示例#13
0
        public Vector3[] GetVertices(CSGPlane buildPlane, Vector3 worldPosition, Vector3 gridTangent, Vector3 gridBinormal, out bool isValid)
        {
            if (vertices.Length < 1)
            {
                isValid = false;
                return(vertices);
            }
            if (sphereSplits < 1)
            {
                sphereSplits = 1;
            }

            var realSplits = (sphereSplits + 1) * 4;


            //var tangent = GeometryUtility.CalculateTangent(buildPlane.normal);

            var vertex1 = (vertices.Length > 1) ? vertices[1] : worldPosition;

            var delta = (vertex1 - vertices[0]);

            sphereRadius = delta.magnitude;

            if (sphereRadius <= MathConstants.DistanceEpsilon)
            {
                isValid = false;
                return(new Vector3[0]);
            }


            var matrix       = GeometryUtility.Rotate2DToPlaneMatrix(buildPlane);
            var realVertices = new Vector3[realSplits];

            float angle_offset = GeometryUtility.SignedAngle(gridTangent, delta / sphereRadius, buildPlane.normal);

            angle_offset -= 90;

            angle_offset += sphereOffset;
            angle_offset *= Mathf.Deg2Rad;

            Vector3 p1 = MathConstants.zeroVector3;

            for (int i = 0; i < realSplits; i++)
            {
                var angle = ((i * Mathf.PI * 2.0f) / (float)realSplits) + angle_offset;

                p1.x = (Mathf.Sin(angle) * sphereRadius);
                p1.z = (Mathf.Cos(angle) * sphereRadius);

                realVertices[i] = p1;
            }

            for (int i = 0; i < realSplits; i++)
            {
                var point = realVertices[i];
                realVertices[i] = GeometryUtility.ProjectPointOnPlane(buildPlane, vertices[0] + matrix.MultiplyPoint(point));
            }

            isValid = true;
            return(realVertices);
        }
示例#14
0
        public static Quaternion FindDragOrientation(SceneView sceneView, Vector3 normal, PrefabSourceAlignment sourceSurfaceAlignment, PrefabDestinationAlignment destinationSurfaceAlignment)
        {
            Quaternion srcRotation;

            switch (sourceSurfaceAlignment)
            {
            default:
            case PrefabSourceAlignment.AlignedFront: srcRotation = Quaternion.LookRotation(MathConstants.forwardVector3); break;

            case PrefabSourceAlignment.AlignedBack: srcRotation = Quaternion.LookRotation(MathConstants.backVector3); break;

            case PrefabSourceAlignment.AlignedLeft: srcRotation = Quaternion.LookRotation(MathConstants.rightVector3); break;

            case PrefabSourceAlignment.AlignedRight: srcRotation = Quaternion.LookRotation(MathConstants.leftVector3); break;

            case PrefabSourceAlignment.AlignedTop: srcRotation = Quaternion.LookRotation(MathConstants.upVector3, MathConstants.forwardVector3); break;

            case PrefabSourceAlignment.AlignedBottom: srcRotation = Quaternion.LookRotation(MathConstants.downVector3, MathConstants.backVector3); break;
            }

            switch (destinationSurfaceAlignment)
            {
            default:
            case PrefabDestinationAlignment.AlignToSurface:
            {
                var tangent = MathConstants.upVector3;                         // assume up is up in the world
                var absX    = Mathf.Abs(normal.x);
                var absY    = Mathf.Abs(normal.y);
                var absZ    = Mathf.Abs(normal.z);

                // if our surface is a floor / ceiling then assume up is the axis
                // aligned vector that is most aligned with the camera's up vector
                if (absX <= absY && absX <= absZ && absY > absZ)
                {
                    tangent = GeometryUtility.SnapToClosestAxis(sceneView.camera ? sceneView.camera.transform.up : MathConstants.upVector3);
                }

                return(Quaternion.LookRotation(normal, tangent) * srcRotation);
            }

            case PrefabDestinationAlignment.AlignSurfaceUp:
            {
                normal.y = 0;
                normal.Normalize();
                if (normal.sqrMagnitude == 0)
                {
                    normal = GeometryUtility.SnapToClosestAxis(sceneView.camera ? sceneView.camera.transform.forward : MathConstants.forwardVector3);
                }

                var tangent = MathConstants.upVector3;                         // assume up is up in the world
                var absX    = Mathf.Abs(normal.x);
                var absY    = Mathf.Abs(normal.y);
                var absZ    = Mathf.Abs(normal.z);

                // if our surface is a floor / ceiling then assume up is the axis
                // aligned vector that is most aligned with the camera's up vector
                if (absX <= absY && absX <= absZ && absY > absZ)
                {
                    tangent = GeometryUtility.SnapToClosestAxis(sceneView.camera ? sceneView.camera.transform.up : MathConstants.upVector3);
                }

                return(Quaternion.LookRotation(normal, tangent) * srcRotation);
            }

            case PrefabDestinationAlignment.Default:
            {
                return(Quaternion.identity);
            }
            }
        }
示例#15
0
        static void FreeDrawSettingsGUI(GeneratorFreeDraw generator, bool isSceneGUI)
        {
            var distanceUnit = RealtimeCSG.CSGSettings.DistanceUnit;
            var nextUnit     = Units.CycleToNextUnit(distanceUnit);
            var unitText     = Units.GetUnitGUIContent(distanceUnit);

            GUILayout.BeginVertical(CSG_GUIStyleUtility.ContentEmpty);
            {
                {
                    GUILayout.BeginHorizontal(CSG_GUIStyleUtility.ContentEmpty);
                    {
                        GUILayout.Label(HeightContent, width65);
                        var height = generator.HaveHeight ? generator.Height : GeometryUtility.CleanLength(generator.DefaultHeight);
                        EditorGUI.BeginChangeCheck();
                        {
                            height = Units.DistanceUnitToUnity(distanceUnit, EditorGUILayout.DoubleField(Units.UnityToDistanceUnit(distanceUnit, height)));
                        }
                        if (EditorGUI.EndChangeCheck())
                        {
                            if (generator.HaveHeight)
                            {
                                generator.Height = height;
                            }
                            else
                            {
                                generator.DefaultHeight = height;
                            }
                        }
                        if (GUILayout.Button(unitText, EditorStyles.miniLabel, width20))
                        {
                            distanceUnit = nextUnit;
                            RealtimeCSG.CSGSettings.DistanceUnit = distanceUnit;
                            RealtimeCSG.CSGSettings.UpdateSnapSettings();
                            RealtimeCSG.CSGSettings.Save();
                            SceneView.RepaintAll();
                        }
                    }
                    GUILayout.EndHorizontal();
                    TooltipUtility.SetToolTip(HeightTooltip);
                }
#if EVALUATION
                EditorGUI.BeginDisabledGroup(true);
#endif
                {
                    GUILayout.BeginHorizontal(CSG_GUIStyleUtility.ContentEmpty);
                    {
                        GUILayout.Label(CurveSidesContent, width65);
                        var subdivisions = generator.CurveSides;
                        EditorGUI.BeginChangeCheck();
                        {
                            subdivisions = (uint)Mathf.Clamp(EditorGUILayout.IntField((int)subdivisions), 0, 32);
                        }
                        if (EditorGUI.EndChangeCheck() && generator.CurveSides != subdivisions)
                        {
                            generator.CurveSides = subdivisions;
                        }
                    }
                    GUILayout.EndHorizontal();
                    TooltipUtility.SetToolTip(CurveSidesTooltip);
                }
                {
                    GUILayout.BeginHorizontal(CSG_GUIStyleUtility.ContentEmpty);
                    {
                        EditorGUI.BeginDisabledGroup(!generator.HaveSelectedEdgesOrVertices);
                        {
                            var tangentState = generator.SelectedTangentState;
                            EditorGUI.BeginChangeCheck();
                            {
                                GUILayout.Label(EdgeTypeContent, width65);
                                EditorGUI.showMixedValue = !tangentState.HasValue;
                                tangentState             = (HandleConstraints)EditorGUILayout.EnumPopup(tangentState.HasValue ? tangentState.Value : HandleConstraints.Straight);
                                EditorGUI.showMixedValue = false;
                            }
                            if (EditorGUI.EndChangeCheck())
                            {
                                generator.SelectedTangentState = tangentState;
                            }
                        }
                        EditorGUI.EndDisabledGroup();
                    }
                    GUILayout.EndHorizontal();
                    TooltipUtility.SetToolTip(EdgeTypeTooltip);
                }
                EditorGUILayout.Space();
#if EVALUATION
                EditorGUI.EndDisabledGroup();
#endif

                EditorGUI.BeginDisabledGroup(!generator.HaveSelectedEdges);
                {
                    if (GUILayout.Button(SplitSelectedContent))
                    {
                        generator.SplitSelectedEdge();
                    }
                    TooltipUtility.SetToolTip(SplitSelectedTooltip);
                }
                EditorGUI.EndDisabledGroup();

                /*
                 * GUILayout.BeginHorizontal(GUIStyleUtility.ContentEmpty);
                 * {
                 *      if (isSceneGUI)
                 *              GUILayout.Label(AlphaContent, width75);
                 *      else
                 *              EditorGUILayout.PrefixLabel(AlphaContent);
                 *      var alpha = generator.Alpha;
                 *      EditorGUI.BeginChangeCheck();
                 *      {
                 *              alpha = EditorGUILayout.Slider(alpha, -1.0f, 3.0f);
                 *      }
                 *      if (EditorGUI.EndChangeCheck() && generator.Alpha != alpha)
                 *      {
                 *              generator.Alpha = alpha;
                 *      }
                 * }
                 * GUILayout.EndHorizontal();
                 */
            }
            GUILayout.EndVertical();
        }
示例#16
0
        protected void HandleHeightHandles(Rect sceneRect, bool showHeightValue)
        {
            for (int p = 0; p < extrusionPoints.Length; p++)
            {
                var type = Event.current.GetTypeForControl(extrusionPoints[p].ID);
                switch (type)
                {
                case EventType.Repaint:
                {
                    if (SceneTools.IsDraggingObjectInScene)
                    {
                        break;
                    }

                    bool isSelected = extrusionPoints[p].ID == GUIUtility.keyboardControl;
                    var  temp       = Handles.color;
                    var  origMatrix = Handles.matrix;

                    Handles.matrix = MathConstants.identityMatrix;
                    var rotation = Camera.current.transform.rotation;


                    var state = SelectState.None;
                    if (isSelected)
                    {
                        state |= SelectState.Selected;
                        state |= SelectState.Hovering;
                    }
                    else
                    if (HandleUtility.nearestControl == extrusionPoints[p].ID)
                    {
                        state |= SelectState.Hovering;
                    }


                    if (polygons != null && outlineVertices.Length >= 3)
                    {
                        var wireframeColor    = ColorSettings.WireframeOutline;
                        var topWireframeColor = ColorSettings.WireframeOutline;

                        if (!shapeIsValid)
                        {
                            wireframeColor = Color.red;
                        }

                        var surfaceColor = ColorSettings.ShapeDrawingFill;
                        if (GUIUtility.hotControl == extrusionPoints[p].ID)
                        {
                            topWireframeColor = ColorSettings.BoundsEdgeHover;
                            surfaceColor      = ColorSettings.PolygonInnerStateColor[(int)(SelectState.Selected | SelectState.Hovering)];
                            surfaceColor.a   *= 0.5f;
                        }
                        else
                        if (GUIUtility.hotControl == 0 && HandleUtility.nearestControl == extrusionPoints[p].ID)
                        {
                            topWireframeColor = ColorSettings.BoundsEdgeHover;
                            surfaceColor      = ColorSettings.PolygonInnerStateColor[(int)(SelectState.Selected)];
                            surfaceColor.a   *= 0.5f;
                        }


                        var poly2dToWorldMatrix = Matrix4x4.TRS(extrusionPoints[p].Position, Quaternion.FromToRotation(MathConstants.upVector3, buildPlane.normal), MathConstants.oneVector3);
                        for (int i = 0; i < polygons.Length; i++)
                        {
                            PaintUtility.DrawPolygon(poly2dToWorldMatrix, polygons[i].Vertices, surfaceColor);
                        }

                        poly2dToWorldMatrix = Matrix4x4.TRS(extrusionPoints[p].Position, Quaternion.identity, MathConstants.oneVector3);
                        for (int i = 1; i < outlineVertices.Length; i++)
                        {
                            PaintUtility.DrawLine(poly2dToWorldMatrix, outlineVertices[i - 1], outlineVertices[i], ToolConstants.oldLineScale, topWireframeColor);
                            PaintUtility.DrawDottedLine(poly2dToWorldMatrix, outlineVertices[i - 1], outlineVertices[i], topWireframeColor, 4.0f);
                        }
                        PaintUtility.DrawLine(poly2dToWorldMatrix, outlineVertices[outlineVertices.Length - 1], outlineVertices[0], ToolConstants.oldLineScale, topWireframeColor);
                        PaintUtility.DrawDottedLine(poly2dToWorldMatrix, outlineVertices[outlineVertices.Length - 1], outlineVertices[0], topWireframeColor, 4.0f);

                        if (p > 0)
                        {
                            var prevOffset = extrusionPoints[p - 1].Position;
                            var prevPoly2dToWorldMatrix = Matrix4x4.TRS(prevOffset, Quaternion.identity, MathConstants.oneVector3);
                            for (int i = 0; i < outlineVertices.Length; i++)
                            {
                                var from = prevPoly2dToWorldMatrix.MultiplyPoint(outlineVertices[i]);
                                var to   = poly2dToWorldMatrix.MultiplyPoint(outlineVertices[i]);
                                PaintUtility.DrawLine(from, to, ToolConstants.oldLineScale, wireframeColor);
                                PaintUtility.DrawDottedLine(from, to, wireframeColor, 4.0f);
                            }
                        }
                    }

                    var color = ColorSettings.PolygonInnerStateColor[(int)state];
                    if (!shapeIsValid)
                    {
                        color = Color.red;
                    }

                    var handleSize       = GUIStyleUtility.GetHandleSize(extrusionPoints[p].Position);
                    var scaledHandleSize = handleSize * ToolConstants.handleScale;
                    if (p > 0)
                    {
                        PaintUtility.DrawDottedLine(extrusionPoints[p - 1].Position, extrusionPoints[p].Position, color, 4.0f);
                    }

                    Handles.color = color;
                    PaintUtility.SquareDotCap(extrusionPoints[p].ID, extrusionPoints[p].Position, rotation, scaledHandleSize);

                    var direction = haveForcedDirection ? forcedDirection : buildPlane.normal;

                    var distance = new CSGPlane(direction, extrusionPoints[p].Position).Distance(extrusionPoints[1 - p].Position);
                    if (distance <= MathConstants.DistanceEpsilon)
                    {
                        PaintUtility.DrawArrowCap(extrusionPoints[p].Position, direction, HandleUtility.GetHandleSize(extrusionPoints[p].Position));
                    }
                    if (distance > -MathConstants.DistanceEpsilon)
                    {
                        PaintUtility.DrawArrowCap(extrusionPoints[p].Position, -direction, HandleUtility.GetHandleSize(extrusionPoints[p].Position));
                    }

                    Handles.matrix = origMatrix;
                    Handles.color  = temp;

                    if (p > 0 && showHeightValue)
                    {
                        var length = GetSegmentLength(extrusionPoints[p].Position, extrusionPoints[p - 1].Position, direction);
                        PaintHeightMessage(extrusionPoints[p - 1].Position, extrusionPoints[p].Position, gridTangent, length);
                    }
                    break;
                }

                case EventType.layout:
                {
                    if ((Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan))
                    {
                        break;
                    }

                    var poly2dToWorldMatrix = Matrix4x4.TRS(extrusionPoints[p].Position, Quaternion.FromToRotation(MathConstants.upVector3, buildPlane.normal), MathConstants.oneVector3);
                    var forceOverHandle     = IsMouseOverShapePolygons(poly2dToWorldMatrix);
                    HandleUtility.AddControl(extrusionPoints[p].ID, forceOverHandle ? 3.0f : float.PositiveInfinity);

                    var origMatrix = Handles.matrix;
                    Handles.matrix = MathConstants.identityMatrix;
                    float handleSize       = GUIStyleUtility.GetHandleSize(extrusionPoints[p].Position);
                    float scaledHandleSize = handleSize * ToolConstants.handleScale * handle_extension;
                    float distanceToCircle = HandleUtility.DistanceToCircle(extrusionPoints[p].Position, scaledHandleSize);

                    HandleUtility.AddControl(extrusionPoints[p].ID, distanceToCircle);

                    var direction = haveForcedDirection ? forcedDirection : buildPlane.normal;

                    var distance = new CSGPlane(direction, extrusionPoints[p].Position).Distance(extrusionPoints[1 - p].Position);
                    if (distance <= MathConstants.DistanceEpsilon)
                    {
                        PaintUtility.AddArrowCapControl(extrusionPoints[p].ID, extrusionPoints[p].Position, direction, HandleUtility.GetHandleSize(extrusionPoints[p].Position));
                    }
                    if (distance > -MathConstants.DistanceEpsilon)
                    {
                        PaintUtility.AddArrowCapControl(extrusionPoints[p].ID, extrusionPoints[p].Position, -direction, HandleUtility.GetHandleSize(extrusionPoints[p].Position));
                    }

                    if (generatedGameObjects != null && generatedGameObjects.Length > 0)
                    {
                        for (int g = generatedGameObjects.Length - 1; g >= 0; g--)
                        {
                            if (generatedGameObjects[g])
                            {
                                continue;
                            }
                            ArrayUtility.RemoveAt(ref generatedGameObjects, g);
                        }

                        if (generatedGameObjects == null || generatedGameObjects.Length == 0)
                        {
                            Cancel();
                        }
                    }

                    Handles.matrix = origMatrix;
                    break;
                }

                case EventType.MouseDown:
                {
                    if (!sceneRect.Contains(Event.current.mousePosition))
                    {
                        break;
                    }
                    if ((Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan) ||
                        Event.current.modifiers != EventModifiers.None)
                    {
                        break;
                    }
                    if (GUIUtility.hotControl == 0 &&
                        HandleUtility.nearestControl == extrusionPoints[p].ID && Event.current.button == 0)
                    {
                        if (editMode != EditMode.ExtrudeShape &&
                            !StartExtrudeMode())
                        {
                            Cancel();
                        }
                        else
                        {
                            UpdateBaseShape(registerUndo: false);
                            dragPositionStart = extrusionPoints[p].Position;
                            GrabHeightHandle(p);
                            BeginExtrusion();
                            Event.current.Use();
                        }
                    }
                    break;
                }

                case EventType.MouseDrag:
                case EventType.MouseMove:
                {
                    if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
                    {
                        break;
                    }
                    if (GUIUtility.hotControl == extrusionPoints[p].ID)                            // && Event.current.button == 0)
                    {
                        Undo.RecordObject(this, "Extrude shape");
                        heightPosition += Event.current.delta;
                        Vector3 worldPosition = GetHeightHandlePosition(extrusionPoints[p].Position) - heightHandleOffset;
                        if (float.IsInfinity(worldPosition.x) || float.IsNaN(worldPosition.x) ||
                            float.IsInfinity(worldPosition.y) || float.IsNaN(worldPosition.y) ||
                            float.IsInfinity(worldPosition.z) || float.IsNaN(worldPosition.z))
                        {
                            worldPosition = extrusionPoints[p].Position;
                        }

                        ResetVisuals();
                        if (raySnapFunction != null)
                        {
                            CSGBrush snappedOnBrush = null;
                            worldPosition      = raySnapFunction(worldPosition, new Ray(brushPosition, movePolygonDirection), ref visualSnappedEdges, out snappedOnBrush);
                            visualSnappedBrush = snappedOnBrush;
                        }

                        visualSnappedGrid = Grid.FindAllGridEdgesThatTouchPoint(worldPosition);

                        extrusionPoints[p].Position = GeometryUtility.ProjectPointOnInfiniteLine(worldPosition, brushPosition, movePolygonDirection);

                        if (p == 0)
                        {
                            MoveShape(extrusionPoints[0].Position - dragPositionStart);
                            UpdateBaseShape();
                        }

                        UpdateBrushPosition();
                        UpdateExtrudedShape();

                        GUI.changed = true;
                        Event.current.Use();
                        break;
                    }
                    break;
                }

                case EventType.MouseUp:
                {
                    forceDragHandle = false;
                    if (GUIUtility.hotControl == extrusionPoints[p].ID &&
                        Event.current.button == 0 &&
                        (Tools.viewTool == ViewTool.None || Tools.viewTool == ViewTool.Pan))
                    {
                        EndExtrusion();
                        if (firstClick)
                        {
                            firstClick = false;
                            break;
                        }

                        GUIUtility.hotControl             = 0;
                        GUIUtility.keyboardControl        = 0;
                        EditorGUIUtility.editingTextField = false;
                        Event.current.Use();

                        ResetVisuals();
                        CleanupGrid();

                        if (!HaveExtrusion)
                        {
                            RevertToEditVertices();
                        }
                        break;
                    }
                    break;
                }
                }
            }

            var shapeType = Event.current.GetTypeForControl(shapeId);

            HandleKeyboard(shapeType);
        }
        public void SetBounds(AABB newBounds, bool autoAdjust = true)
        {
            var boundsSize = newBounds.Size;

            stairsWidth  = GeometryUtility.CleanLength(boundsSize.x);
            stairsHeight = GeometryUtility.CleanLength(boundsSize.y);
            stairsDepth  = GeometryUtility.CleanLength(boundsSize.z);

            if (float.IsInfinity(stairsWidth) || float.IsNaN(stairsWidth))
            {
                stairsWidth = 1.0f;
            }
            if (float.IsInfinity(stairsDepth) || float.IsNaN(stairsDepth))
            {
                stairsDepth = stepDepth;
            }
            if (float.IsInfinity(stairsHeight) || float.IsNaN(stairsHeight))
            {
                stairsHeight = stepHeight;
            }
            stairsWidth  = Mathf.Max(0, stairsWidth);
            stairsDepth  = Mathf.Max(0, stairsDepth);
            stairsHeight = Mathf.Max(0, stairsHeight);

            if (autoAdjust)
            {
                if (!bounds.IsEmpty())
                {
                    float offsetY = (newBounds.MaxY - bounds.MaxY) + (bounds.MinY - newBounds.MinY);
                    float offsetZ = (newBounds.MaxZ - bounds.MaxZ) + (bounds.MinZ - newBounds.MinZ);

                    if (offsetY != 0)                     // scaling in height direction
                    {
                        if (offsetY > 0)                  // growing
                        {
                            if (extraDepth > 0)
                            {
                                extraDepth = stairsDepth - ((Mathf.Max(0, stairsHeight - extraHeight) / stepHeight) * stepDepth);
                            }
                            else
                            {
                                extraDepth  -= offsetY;
                                extraHeight += offsetY;
                            }
                        }
                        else                           // shrinking
                        {
                            extraHeight += offsetY;
                            extraDepth   = stairsDepth - ((Mathf.Max(0, stairsHeight - extraHeight) / stepHeight) * stepDepth);
                        }
                    }

                    if (offsetZ != 0)                     // scaling in depth direction
                    {
                        if (offsetZ > 0)                  // growing
                        {
                            if (extraHeight > 0)
                            {
                                extraHeight = stairsHeight - ((Mathf.Max(0, stairsDepth - extraDepth) / stepDepth) * stepHeight);
                            }
                            else
                            {
                                extraDepth += offsetZ; if (extraDepth < 0)
                                {
                                    extraDepth = 0;
                                }
                                extraHeight -= offsetZ;
                            }
                        }
                        else                           // shrinking
                        {
                            if (extraDepth > 0)
                            {
                                extraDepth = Mathf.Max(0, extraDepth + offsetZ);
                            }
                            extraHeight = stairsHeight - ((Mathf.Max(0, stairsDepth - extraDepth) / stepDepth) * stepHeight);
                        }
                        extraDepth = stairsDepth - ((Mathf.Max(0, stairsHeight - extraHeight) / stepHeight) * stepDepth);
                    }

                    if (extraDepth < 0)
                    {
                        extraDepth = 0;
                    }
                    if (extraHeight < 0)
                    {
                        extraHeight = 0;
                    }
                }
                else
                {
                    extraDepth  = Mathf.Max(0, stairsDepth - (totalSteps * stepDepth));
                    extraHeight = 0;
                }
                CalcTotalSteps();

                if ((totalSteps * stepDepth) > stairsDepth)
                {
                    var newTotalSteps = Mathf.Max(1, Mathf.FloorToInt((stairsDepth - extraDepth) / stepDepth));
                    extraHeight += (totalSteps - newTotalSteps) * stepHeight;
                    totalSteps   = newTotalSteps;
                }
            }

            bounds = newBounds;
        }
示例#18
0
        public static Vector3 SnapDeltaToGrid(Vector3 worldDeltaMovement, Vector3[] worldPoints, bool snapToGridPlane = true, bool snapToSelf = false)
        {
            UpdateGridOrientation();
            if (gridOrientation == null || worldPoints == null || worldPoints.Length == 0)
            {
                return(worldDeltaMovement);
            }

            var worldPlane  = gridOrientation.gridWorkPlane;
            var scaleVector = gridOrientation.gridSnapScale;
            var snapVector  = gridOrientation.gridSnapVector;

            var gridLocalDeltaMovement = VectorToGridSpace(worldDeltaMovement);
            var gridLocalPlane         = PlaneToGridSpace(worldPlane);

            if (snapToGridPlane)
            {
                scaleVector.x *= (Mathf.Abs(gridLocalPlane.a) >= 1 - MathConstants.EqualityEpsilon) ? 0 : 1;
                scaleVector.y *= (Mathf.Abs(gridLocalPlane.b) >= 1 - MathConstants.EqualityEpsilon) ? 0 : 1;
                scaleVector.z *= (Mathf.Abs(gridLocalPlane.c) >= 1 - MathConstants.EqualityEpsilon) ? 0 : 1;
            }
            var snappedDeltaMovement = gridLocalDeltaMovement;

            if (Mathf.Abs(scaleVector.x) < MathConstants.EqualityEpsilon)
            {
                snappedDeltaMovement.x = 0;
            }
            if (Mathf.Abs(scaleVector.y) < MathConstants.EqualityEpsilon)
            {
                snappedDeltaMovement.y = 0;
            }
            if (Mathf.Abs(scaleVector.z) < MathConstants.EqualityEpsilon)
            {
                snappedDeltaMovement.z = 0;
            }

            Vector3[] gridLocalPoints;
            if (worldPoints.Length > 1)
            {
                var bounds = new AABB();
                bounds.Reset();
                for (int i = 0; i < worldPoints.Length; i++)
                {
                    Vector3 localPoint = PointToGridSpace(worldPoints[i]);
                    if (snapToGridPlane)
                    {
                        localPoint = GeometryUtility.ProjectPointOnPlane(gridLocalPlane, localPoint);
                    }
                    if (float.IsNaN(localPoint.x) || float.IsNaN(localPoint.y) || float.IsNaN(localPoint.z) ||
                        float.IsInfinity(localPoint.x) || float.IsInfinity(localPoint.y) || float.IsInfinity(localPoint.z))
                    {
                        continue;
                    }
                    bounds.Extend(localPoint);
                }
                gridLocalPoints = bounds.GetCorners();
            }
            else
            {
                var     localGridSpacePoint = PointToGridSpace(worldPoints[0]);
                Vector3 projectedPoint      = localGridSpacePoint;
                if (snapToGridPlane)
                {
                    projectedPoint = GeometryUtility.ProjectPointOnPlane(gridLocalPlane, localGridSpacePoint);
                }

                if (float.IsNaN(projectedPoint.x) || float.IsNaN(projectedPoint.y) || float.IsNaN(projectedPoint.z) ||
                    float.IsInfinity(projectedPoint.x) || float.IsInfinity(projectedPoint.y) || float.IsInfinity(projectedPoint.z))
                {
                    gridLocalPoints = new Vector3[0] {
                    }
                }
                ;
                else
                {
                    gridLocalPoints = new Vector3[] { projectedPoint }
                };
            }

            for (int i = 0; i < gridLocalPoints.Length; i++)
            {
                var oldPoint = gridLocalPoints[i];
                var newPoint = gridLocalPoints[i] + gridLocalDeltaMovement;
                if (snapToGridPlane)
                {
                    newPoint = GeometryUtility.ProjectPointOnPlane(gridLocalPlane, newPoint);
                }
                newPoint = GridUtility.CleanPosition(newPoint);

                var snappedNewPoint = SnapRoundPosition(newPoint, snapVector);

                if (snapToGridPlane)
                {
                    snappedNewPoint = GeometryUtility.ProjectPointOnPlane(gridLocalPlane, snappedNewPoint);
                }
                snappedNewPoint = GridUtility.CleanPosition(snappedNewPoint);

                var foundDeltaMovement = (snappedNewPoint - oldPoint);

                foundDeltaMovement.x *= scaleVector.x;
                foundDeltaMovement.y *= scaleVector.y;
                foundDeltaMovement.z *= scaleVector.z;

                if (i == 0 || Math.Abs(foundDeltaMovement.x) < Mathf.Abs(snappedDeltaMovement.x))
                {
                    snappedDeltaMovement.x = foundDeltaMovement.x;
                }
                if (i == 0 || Math.Abs(foundDeltaMovement.y) < Mathf.Abs(snappedDeltaMovement.y))
                {
                    snappedDeltaMovement.y = foundDeltaMovement.y;
                }
                if (i == 0 || Math.Abs(foundDeltaMovement.z) < Mathf.Abs(snappedDeltaMovement.z))
                {
                    snappedDeltaMovement.z = foundDeltaMovement.z;
                }
            }

            if (snapToSelf)
            {
                var snapDelta = (snappedDeltaMovement - gridLocalDeltaMovement);
                if (Mathf.Abs(snapDelta.x) > Mathf.Abs(gridLocalDeltaMovement.x))
                {
                    snappedDeltaMovement.x = 0;
                }
                if (Mathf.Abs(snapDelta.y) > Mathf.Abs(gridLocalDeltaMovement.y))
                {
                    snappedDeltaMovement.y = 0;
                }
                if (Mathf.Abs(snapDelta.z) > Mathf.Abs(gridLocalDeltaMovement.z))
                {
                    snappedDeltaMovement.z = 0;
                }
            }

            worldDeltaMovement = VectorFromGridSpace(snappedDeltaMovement);
            return(worldDeltaMovement);
        }
 public static void CalculateTangents(Vector3 normal, out Vector3 tangent, out Vector3 binormal)
 {
     tangent  = GeometryUtility.CalculateTangent(normal);
     tangent  = Vector3.Cross(normal, tangent).normalized;
     binormal = Vector3.Cross(normal, tangent).normalized;
 }
        protected override void HandleCreateShapeEvents(Rect sceneRect)
        {
            bool     pointOnEdge      = false;
            bool     havePlane        = false;
            bool     vertexOnGeometry = false;
            CSGBrush vertexOnBrush    = null;

            CSGPlane hoverBuildPlane = buildPlane;
            var      camera          = Camera.current;

            if (camera != null &&
                camera.pixelRect.Contains(Event.current.mousePosition))
            {
                if (!hoverDefaultPlane.HasValue ||
                    settings.vertices.Length == 0)
                {
                    bool forceGrid = RealtimeCSG.CSGGrid.ForceGrid;
                    RealtimeCSG.CSGGrid.ForceGrid = false;
                    hoverDefaultPlane             = RealtimeCSG.CSGGrid.CurrentGridPlane;
                    RealtimeCSG.CSGGrid.ForceGrid = forceGrid;
                    firstSnappedEdges             = null;
                    firstSnappedBrush             = null;
                    firstSnappedPlanes            = null;
                    base.geometryModel            = null;
                }
                if (editMode == EditMode.CreatePlane)
                {
                    LegacyBrushIntersection intersection;
                    if (!IgnoreDepthForRayCasts(camera) && !havePlane &&
                        SceneQueryUtility.FindWorldIntersection(Event.current.mousePosition, out intersection))
                    {
                        worldPosition   = intersection.worldIntersection;
                        hoverBuildPlane = intersection.worldPlane;
                        vertexOnBrush   = intersection.brush;

                        vertexOnGeometry = true;
                    }
                    else
                    {
                        hoverBuildPlane = hoverDefaultPlane.Value;
                        vertexOnBrush   = null;

                        var mouseRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
                        worldPosition    = hoverBuildPlane.RayIntersection(mouseRay);
                        vertexOnGeometry = false;
                    }
                    ResetVisuals();
                    if (snapFunction != null)
                    {
                        CSGBrush snappedOnBrush;
                        worldPosition = snapFunction(worldPosition, hoverBuildPlane, ref visualSnappedEdges, out snappedOnBrush, generatedBrushes, ignoreAllBrushes: true);
                        if (snappedOnBrush != null)
                        {
                            pointOnEdge = (visualSnappedEdges != null &&
                                           visualSnappedEdges.Count > 0);
                            vertexOnBrush    = snappedOnBrush;
                            vertexOnGeometry = true;
                        }
                    }

                    if (settings.vertices.Length == 1)
                    {
                        if (hoverBuildPlane.normal != MathConstants.zeroVector3)
                        {
                            editMode  = EditMode.CreateShape;
                            havePlane = true;
                        }
                    }
                }
                else
                {
                    var mouseRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
                    if (settings.vertices.Length == 2)
                    {
                        var startPoint = settings.vertices[1];

                        var forward = camera.transform.forward;
                        if (Vector3.Dot(forward, gridBinormal) < Vector3.Dot(forward, gridTangent))
                        {
                            hoverBuildPlane = new CSGPlane(gridBinormal, startPoint);
                        }
                        else
                        {
                            hoverBuildPlane = new CSGPlane(gridTangent, startPoint);
                        }
                        worldPosition = hoverBuildPlane.RayIntersection(mouseRay);

                        // the third point is always straight up from the second point
                        //worldPosition = startPoint + (Vector3.Dot(worldPosition - startPoint, gridNormal) * gridNormal);

                        RealtimeCSG.CSGGrid.SetForcedGrid(hoverBuildPlane);
                        ResetVisuals();
                        if (raySnapFunction != null)
                        {
                            Ray      ray = new Ray(startPoint, gridNormal);
                            CSGBrush snappedOnBrush;
                            worldPosition = raySnapFunction(worldPosition, ray, ref visualSnappedEdges, out snappedOnBrush);
                            if (snappedOnBrush != null)
                            {
                                pointOnEdge = (visualSnappedEdges != null &&
                                               visualSnappedEdges.Count > 0);
                                vertexOnBrush = snappedOnBrush;
                            }
                        }

                        worldPosition = GeometryUtility.ProjectPointOnInfiniteLine(worldPosition, startPoint, gridNormal);
                    }
                    else
                    {
                        worldPosition = hoverBuildPlane.RayIntersection(mouseRay);

                        RealtimeCSG.CSGGrid.SetForcedGrid(hoverBuildPlane);
                        ResetVisuals();
                        if (snapFunction != null)
                        {
                            CSGBrush snappedOnBrush;
                            worldPosition = snapFunction(worldPosition, hoverBuildPlane, ref visualSnappedEdges, out snappedOnBrush, generatedBrushes, ignoreAllBrushes: true);
                            if (snappedOnBrush != null)
                            {
                                pointOnEdge = (visualSnappedEdges != null &&
                                               visualSnappedEdges.Count > 0);
                                vertexOnBrush = snappedOnBrush;
                            }
                        }
                    }
                }

                if (geometryModel == null && vertexOnBrush != null)
                {
                    if (vertexOnBrush.ChildData != null && vertexOnBrush.ChildData.Model)
                    {
                        geometryModel = vertexOnBrush.ChildData.Model;
                    }
                }

                if (worldPosition != prevWorldPosition)
                {
                    prevWorldPosition = worldPosition;
                    if (settings.vertices.Length > 0)
                    {
                        if ((settings.vertices[0] - worldPosition).sqrMagnitude > MathConstants.EqualityEpsilon)
                        {
                            UpdateSizes();
                            UpdateBaseShape(true);
                        }
                    }
                    if (Event.current.type != EventType.Repaint)
                    {
                        CSG_EditorGUIUtility.RepaintAll();
                    }
                }

                visualSnappedGrid  = RealtimeCSG.CSGGrid.FindAllGridEdgesThatTouchPoint(worldPosition);
                visualSnappedBrush = vertexOnBrush;
            }
            RealtimeCSG.CSGGrid.SetForcedGrid(hoverBuildPlane);



            if (!SceneDragToolManager.IsDraggingObjectInScene &&
                Event.current.type == EventType.Repaint)
            {
                PaintSnapVisualisation();
                PaintShape(base.shapeId);
            }


            var type = Event.current.GetTypeForControl(base.shapeId);

            switch (type)
            {
            case EventType.Layout:
            {
                return;
            }

            case EventType.ValidateCommand:
            case EventType.KeyDown:
            {
                if (GUIUtility.hotControl == base.shapeId)
                {
                    if (Keys.PerformActionKey.IsKeyPressed() ||
                        Keys.DeleteSelectionKey.IsKeyPressed() ||
                        Keys.CancelActionKey.IsKeyPressed())
                    {
                        Event.current.Use();
                    }
                }
                return;
            }

            case EventType.KeyUp:
            {
                if (GUIUtility.hotControl == base.shapeId)
                {
                    if (Keys.CylinderBuilderMode.IsKeyPressed() ||
                        Keys.PerformActionKey.IsKeyPressed())
                    {
                        HotKeyReleased();
                        Event.current.Use();
                        return;
                    }
                    if (Keys.DeleteSelectionKey.IsKeyPressed() ||
                        Keys.CancelActionKey.IsKeyPressed())
                    {
                        Cancel();
                        Event.current.Use();
                        return;
                    }
                }
                return;
            }

            case EventType.MouseDown:
            {
                if (!sceneRect.Contains(Event.current.mousePosition))
                {
                    break;
                }
                if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
                {
                    return;
                }
                if ((GUIUtility.hotControl != 0 && GUIUtility.hotControl != shapeEditId && GUIUtility.hotControl != base.shapeId) ||
                    Event.current.button != 0)
                {
                    return;
                }

                Event.current.Use();
                if (settings.vertices.Length == 0)
                {
                    if ((GUIUtility.hotControl == 0 ||
                         GUIUtility.hotControl == base.shapeEditId) && base.shapeId != -1)
                    {
                        base.CalculateWorldSpaceTangents();
                        GUIUtility.hotControl             = base.shapeId;
                        GUIUtility.keyboardControl        = base.shapeId;
                        EditorGUIUtility.editingTextField = false;
                    }
                }

                if (GUIUtility.hotControl == base.shapeId &&
                    settings.vertices.Length < kMaxPoints)
                {
                    if (!float.IsNaN(worldPosition.x) && !float.IsInfinity(worldPosition.x) &&
                        !float.IsNaN(worldPosition.y) && !float.IsInfinity(worldPosition.y) &&
                        !float.IsNaN(worldPosition.z) && !float.IsInfinity(worldPosition.z))
                    {
                        if (settings.vertices.Length < 2 &&
                            hoverBuildPlane.normal.sqrMagnitude != 0)
                        {
                            buildPlane = hoverBuildPlane;
                        }
                        CalculateWorldSpaceTangents();

                        if (settings.vertices.Length == 0)
                        {
                            if (pointOnEdge)
                            {
                                firstSnappedEdges  = visualSnappedEdges.ToArray();
                                firstSnappedBrush  = visualSnappedBrush;
                                firstSnappedPlanes = null;
                            }
                            else
                            {
                                firstSnappedBrush  = null;
                                firstSnappedEdges  = null;
                                firstSnappedPlanes = null;
                            }
                            planeOnGeometry = vertexOnGeometry;
                        }
                        else
                        {
                            if (firstSnappedEdges != null)
                            {
                                if (firstSnappedPlanes == null)
                                {
                                    CreateSnappedPlanes();
                                }

                                bool outside = true;
                                for (int i = 0; i < firstSnappedPlanes.Length; i++)
                                {
                                    if (firstSnappedPlanes[i].Distance(worldPosition) <= MathConstants.DistanceEpsilon)
                                    {
                                        outside = false;
                                        break;
                                    }
                                }

                                planeOnGeometry = !outside;
                            }

                            if (vertexOnGeometry)
                            {
                                var plane    = hoverDefaultPlane.Value;
                                var distance = plane.Distance(worldPosition);
                                plane.d          += distance;
                                hoverDefaultPlane = plane;

                                for (int i = 0; i < settings.vertices.Length; i++)
                                {
                                    if (!settings.onGeometryVertices[i])
                                    {
                                        settings.SetPoint(i, GeometryUtility.ProjectPointOnPlane(plane, settings.vertices[i]));
                                        settings.onGeometryVertices[i] = true;
                                    }
                                }
                            }
                        }
                        ArrayUtility.Add(ref settings.onGeometryVertices, vertexOnGeometry);
                        settings.AddPoint(worldPosition);

                        UpdateSizes();
                        CSG_EditorGUIUtility.RepaintAll();
                        if (settings.vertices.Length == kMaxPoints)
                        {
                            HotKeyReleased();
                        }
                    }
                }
                return;
            }

            case EventType.MouseDrag:
            {
                if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
                {
                    break;
                }
                if (GUIUtility.hotControl == base.shapeId && Event.current.button == 0)
                {
                    Event.current.Use();
                }
                return;
            }

            case EventType.MouseUp:
            {
                if (GUIUtility.hotControl != base.shapeId)
                {
                    return;
                }
                if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
                {
                    return;
                }
                if (Event.current.button == 0)
                {
                    Event.current.Use();

                    ResetVisuals();
                    if (settings.vertices.Length == kMaxPoints)
                    {
                        GUIUtility.hotControl             = 0;
                        GUIUtility.keyboardControl        = 0;
                        EditorGUIUtility.editingTextField = false;

                        editMode = EditMode.CreateShape;
                        HotKeyReleased();
                    }
                }
                return;
            }
            }
        }
示例#21
0
        static void OnGUIContents(CylinderGenerator generator, bool isSceneGUI)
        {
            //GUILayout.BeginVertical(GUIStyleUtility.ContentEmpty);
            //{
            //bool enabled = generator.HaveBrushes;
            GUILayout.BeginHorizontal(GUIStyleUtility.ContentEmpty);
            {
                /*
                 * EditorGUI.BeginDisabledGroup(!enabled);
                 * {
                 *      if (isSceneGUI)
                 *              GUILayout.BeginVertical(GUI.skin.box, width100);
                 *      else
                 *              GUILayout.BeginVertical(GUIStyle.none);
                 *      {
                 *              bool mixedValues = !enabled;
                 *              CSGOperationType operation = generator.CurrentCSGOperationType;
                 *              EditorGUI.BeginChangeCheck();
                 *              operation = GUIStyleUtility.ChooseOperation(operation, mixedValues);
                 *              if (EditorGUI.EndChangeCheck())
                 *              {
                 *                      generator.CurrentCSGOperationType = operation;
                 *              }
                 *      }
                 *      GUILayout.EndVertical();
                 * }
                 * EditorGUI.EndDisabledGroup();
                 */
                if (isSceneGUI)
                {
                    CylinderSettingsGUI(generator, isSceneGUI);
                }
            }
            GUILayout.EndHorizontal();

            GUILayout.Space(5);

            GUILayout.BeginVertical(GUIStyleUtility.ContentEmpty);
            {
                var distanceUnit = RealtimeCSG.CSGSettings.DistanceUnit;
                var nextUnit     = Units.CycleToNextUnit(distanceUnit);
                var unitText     = Units.GetUnitGUIContent(distanceUnit);
                GUILayout.BeginHorizontal(GUIStyleUtility.ContentEmpty);
                {
                    GUILayout.Label(HeightContent, width65);
                    if (isSceneGUI)
                    {
                        TooltipUtility.SetToolTip(HeightTooltip);
                    }
                    var height = generator.HaveHeight ? generator.Height : GeometryUtility.CleanLength(generator.DefaultHeight);
                    EditorGUI.BeginChangeCheck();
                    {
                        if (!isSceneGUI)
                        {
                            height = Units.DistanceUnitToUnity(distanceUnit, EditorGUILayout.DoubleField(Units.UnityToDistanceUnit(distanceUnit, height)));
                        }
                        else
                        {
                            height = Units.DistanceUnitToUnity(distanceUnit, EditorGUILayout.DoubleField(Units.UnityToDistanceUnit(distanceUnit, height), width65));
                        }
                    }
                    if (EditorGUI.EndChangeCheck())
                    {
                        if (generator.HaveHeight)
                        {
                            generator.Height = height;
                        }
                        else
                        {
                            generator.DefaultHeight = height;
                        }
                    }
                    if (GUILayout.Button(unitText, EditorStyles.miniLabel, width20))
                    {
                        distanceUnit = nextUnit;
                        RealtimeCSG.CSGSettings.DistanceUnit = distanceUnit;
                        RealtimeCSG.CSGSettings.UpdateSnapSettings();
                        RealtimeCSG.CSGSettings.Save();
                        SceneView.RepaintAll();
                    }
                }
                //if (!isSceneGUI)
                {
                    GUILayout.EndHorizontal();
                    TooltipUtility.SetToolTip(HeightTooltip);
                    GUILayout.BeginHorizontal(GUIStyleUtility.ContentEmpty);
                }
                //else
                //{
                //	GUILayout.Space(12);
                //}
                {
                    EditorGUI.BeginDisabledGroup(!generator.CanCommit);
                    {
                        GUILayout.Label(RadiusContent, width65);
                        if (isSceneGUI)
                        {
                            TooltipUtility.SetToolTip(RadiusTooltip);
                        }
                        var radius = generator.RadiusA;
                        EditorGUI.BeginChangeCheck();
                        {
                            if (!isSceneGUI)
                            {
                                radius = Units.DistanceUnitToUnity(distanceUnit, EditorGUILayout.DoubleField(Units.UnityToDistanceUnit(distanceUnit, radius)));
                            }
                            else
                            {
                                radius = Units.DistanceUnitToUnity(distanceUnit, EditorGUILayout.DoubleField(Units.UnityToDistanceUnit(distanceUnit, radius), width65));
                            }
                        }
                        if (EditorGUI.EndChangeCheck())
                        {
                            generator.RadiusA = radius;
                        }
                        if (GUILayout.Button(unitText, EditorStyles.miniLabel, width20))
                        {
                            distanceUnit = nextUnit;
                            RealtimeCSG.CSGSettings.DistanceUnit = distanceUnit;
                            RealtimeCSG.CSGSettings.UpdateSnapSettings();
                            RealtimeCSG.CSGSettings.Save();
                            SceneView.RepaintAll();
                        }
                    }
                    EditorGUI.EndDisabledGroup();
                }
                GUILayout.EndHorizontal();
                if (!isSceneGUI)
                {
                    TooltipUtility.SetToolTip(RadiusTooltip);
                }
            }
            GUILayout.EndVertical();

            {
                generator.CircleSides = IntSettingsSlider(generator.CircleSides, 3, 144, SidesContent, isSceneGUI);
                TooltipUtility.SetToolTip(SidesTooltip);
            }
            {
                generator.CircleOffset = SettingsSlider(generator.CircleOffset, 0, 360, OffsetContent, isSceneGUI);
                TooltipUtility.SetToolTip(OffsetTooltip);
            }



            if (!isSceneGUI)
            {
                GUILayout.Space(5);

                CylinderSettingsGUI(generator, isSceneGUI);

                //GUILayout.Space(10);
            }                     /*else
                                   * {
                                   *    GUILayout.Space(10);
                                   * }*/
                                  /*
                                   * EditorGUI.BeginDisabledGroup(!generator.CanCommit);
                                   * {
                                   *      GUILayout.BeginHorizontal(GUIStyleUtility.ContentEmpty);
                                   *      {
                                   *              if (GUILayout.Button(CommitContent)) { generator.DoCommit(); }
                                   *              TooltipUtility.SetToolTip(CommitTooltip);
                                   *              if (GUILayout.Button(CancelContent)) { generator.DoCancel(); }
                                   *              TooltipUtility.SetToolTip(CancelTooltip);
                                   *      }
                                   *      GUILayout.EndHorizontal();
                                   * }
                                   * EditorGUI.EndDisabledGroup();
                                   */
            //}
            //GUILayout.EndVertical();
        }