static Vector3[] vertices = null; // TODO: store this per instance? or just allocate every frame?

        protected override void OnScene(CSGHemisphere generator)
        {
            var baseColor    = UnityEditor.Handles.yAxisColor;
            var isDisabled   = UnitySceneExtensions.SceneHandles.disabled;
            var focusControl = UnitySceneExtensions.SceneHandleUtility.focusControl;
            var normal       = Vector3.up;

            if (!BrushMeshAssetFactory.GenerateHemisphereVertices(generator.definition, ref vertices))
            {
                return;
            }


            UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, false, false, isDisabled);
            DrawOutline(generator.definition, vertices, lineMode: LineMode.ZTest);

            UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, false, true, isDisabled);
            DrawOutline(generator.definition, vertices, lineMode: LineMode.NoZTest);


            var topPoint = normal * generator.DiameterXYZ.y;
            var radius2D = new Vector2(generator.definition.diameterXYZ.x, generator.definition.diameterXYZ.z) * 0.5f;

            if (generator.DiameterXYZ.y < 0)
            {
                normal = -normal;
            }

            EditorGUI.BeginChangeCheck();
            {
                UnityEditor.Handles.color = baseColor;
                // TODO: make it possible to (optionally) size differently in x & z
                radius2D.x = UnitySceneExtensions.SceneHandles.RadiusHandle(normal, Vector3.zero, radius2D.x);

                var topId = GUIUtility.GetControlID(s_TopHash, FocusType.Passive);
                {
                    var isTopBackfaced = false;          // TODO: how to do this?
                    var topHasFocus    = (focusControl == topId);

                    UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, topHasFocus, isTopBackfaced, isDisabled);
                    topPoint = UnitySceneExtensions.SceneHandles.DirectionHandle(topId, topPoint, normal);
                }
            }
            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(target, "Modified " + generator.NodeTypeName);
                var diameter = generator.DiameterXYZ;
                diameter.y            = topPoint.y;
                diameter.x            = radius2D.x * 2.0f;
                diameter.z            = radius2D.x * 2.0f;
                generator.DiameterXYZ = diameter;
            }
        }
Exemplo n.º 2
0
        protected override void OnScene(CSGTorus generator)
        {
            var baseColor    = UnityEditor.Handles.yAxisColor;
            var isDisabled   = UnitySceneExtensions.SceneHandles.disabled;
            var focusControl = UnitySceneExtensions.SceneHandleUtility.focusControl;
            var normal       = Vector3.up;

            Vector3[] vertices = null;
            if (!BrushMeshAssetFactory.GenerateTorusVertices(generator.definition, ref vertices))
            {
                return;
            }

            UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, false, false, isDisabled);
            DrawOutline(generator.definition, vertices, lineMode: LineMode.ZTest);

            UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, false, true, isDisabled);
            DrawOutline(generator.definition, vertices, lineMode: LineMode.NoZTest);


            var outerRadius = generator.definition.outerDiameter * 0.5f;
            var innerRadius = generator.definition.innerDiameter * 0.5f;
            var topPoint    = normal * (generator.definition.tubeHeight * 0.5f);
            var bottomPoint = normal * (-generator.definition.tubeHeight * 0.5f);

            EditorGUI.BeginChangeCheck();
            {
                UnityEditor.Handles.color = baseColor;
                outerRadius = UnitySceneExtensions.SceneHandles.RadiusHandle(normal, Vector3.zero, outerRadius);
                innerRadius = UnitySceneExtensions.SceneHandles.RadiusHandle(normal, Vector3.zero, innerRadius);
                bottomPoint = UnitySceneExtensions.SceneHandles.DirectionHandle(bottomPoint, -normal);
                topPoint    = UnitySceneExtensions.SceneHandles.DirectionHandle(topPoint, normal);
            }
            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(target, "Modified " + generator.NodeTypeName);
                generator.definition.outerDiameter = outerRadius * 2.0f;
                generator.definition.innerDiameter = innerRadius * 2.0f;
                generator.definition.tubeHeight    = (topPoint.y - bottomPoint.y);
                // TODO: handle sizing down
                generator.OnValidate();
            }
        }
        protected override void OnScene(CSGRevolvedShape generator)
        {
            var baseColor    = UnityEditor.Handles.yAxisColor;
            var isDisabled   = UnitySceneExtensions.SceneHandles.disabled;
            var focusControl = UnitySceneExtensions.SceneHandleUtility.focusControl;
            var normal       = Vector3.forward;

            var shape         = generator.Shape;
            var controlPoints = shape.controlPoints;

            /*
             * for (int p0 = controlPoints.Length - 1, p1 = 0; p1 < controlPoints.Length; p0 = p1, p1++)
             * {
             *  var point0 = controlPoints[p0].position;
             *  var point1 = controlPoints[p1].position;
             *
             * }
             */

            var shapeVertices       = new List <Vector2>();
            var shapeSegmentIndices = new List <int>();

            BrushMeshAssetFactory.GetPathVertices(generator.definition.shape, generator.definition.curveSegments, shapeVertices, shapeSegmentIndices);


            var horzSegments         = generator.definition.revolveSegments;
            var horzDegreePerSegment = generator.definition.totalAngle / horzSegments;
            var horzOffset           = generator.definition.startAngle;

            var noZTestcolor = CSGCylinderEditor.GetColorForState(baseColor, false, true, isDisabled);
            var zTestcolor   = CSGCylinderEditor.GetColorForState(baseColor, false, false, isDisabled);

            for (int h = 1, pr = 0; h < horzSegments + 1; pr = h, h++)
            {
                var hDegree0  = (pr * horzDegreePerSegment) + horzOffset;
                var hDegree1  = (h * horzDegreePerSegment) + horzOffset;
                var rotation0 = Quaternion.AngleAxis(hDegree0, normal);
                var rotation1 = Quaternion.AngleAxis(hDegree1, normal);
                for (int p0 = controlPoints.Length - 1, p1 = 0; p1 < controlPoints.Length; p0 = p1, p1++)
                {
                    var point0 = controlPoints[p0].position;
                    //var point1	= controlPoints[p1].position;
                    var vertexA = rotation0 * new Vector3(point0.x, 0, point0.y);
                    var vertexB = rotation1 * new Vector3(point0.x, 0, point0.y);
                    //var vertexC	= rotation0 * new Vector3(point1.x, 0, point1.y);

                    UnityEditor.Handles.color = noZTestcolor;
                    CSGOutlineRenderer.DrawLine(vertexA, vertexB, lineMode: LineMode.NoZTest, thickness: kHorzLineThickness);//, dashSize: kLineDash);

                    UnityEditor.Handles.color = zTestcolor;
                    CSGOutlineRenderer.DrawLine(vertexA, vertexB, lineMode: LineMode.ZTest, thickness: kHorzLineThickness);  //, dashSize: kLineDash);
                }

                for (int v0 = shapeVertices.Count - 1, v1 = 0; v1 < shapeVertices.Count; v0 = v1, v1++)
                {
                    var point0  = shapeVertices[v0];
                    var point1  = shapeVertices[v1];
                    var vertexA = rotation0 * new Vector3(point0.x, 0, point0.y);
                    var vertexB = rotation0 * new Vector3(point1.x, 0, point1.y);

                    UnityEditor.Handles.color = noZTestcolor;
                    CSGOutlineRenderer.DrawLine(vertexA, vertexB, lineMode: LineMode.NoZTest, thickness: kHorzLineThickness, dashSize: kLineDash);

                    UnityEditor.Handles.color = zTestcolor;
                    CSGOutlineRenderer.DrawLine(vertexA, vertexB, lineMode: LineMode.ZTest, thickness: kHorzLineThickness, dashSize: kLineDash);
                }
            }

            EditorGUI.BeginChangeCheck();
            {
                // TODO: make this work non grid aligned so we can place it upwards
                UnityEditor.Handles.color = baseColor;
                shape = UnitySceneExtensions.SceneHandles.Curve2DHandle(Matrix4x4.TRS(Vector3.zero, Quaternion.AngleAxis(90, Vector3.right), Vector3.one), shape);

                UnityEditor.Handles.DrawDottedLine(normal * 10, normal * -10, 4.0f);
            }
            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(target, "Modified " + generator.NodeTypeName);
                generator.Shape = shape;
            }
        }
Exemplo n.º 4
0
        static Vector3[] vertices = null; // TODO: store this per instance? or just allocate every frame?

        protected override void OnScene(CSGCapsule generator)
        {
            var baseColor    = UnityEditor.Handles.yAxisColor;
            var isDisabled   = UnitySceneExtensions.SceneHandles.disabled;
            var focusControl = UnitySceneExtensions.SceneHandleUtility.focusControl;
            var normal       = Vector3.up;

            if (!BrushMeshAssetFactory.GenerateCapsuleVertices(ref generator.definition, ref vertices))
            {
                return;
            }

            UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, false, false, isDisabled);
            DrawOutline(generator.definition, vertices, lineMode: LineMode.ZTest);

            UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, false, true, isDisabled);
            DrawOutline(generator.definition, vertices, lineMode: LineMode.NoZTest);


            var topPoint    = normal * (generator.definition.offsetY + generator.Height);
            var bottomPoint = normal * (generator.definition.offsetY);
            var middlePoint = normal * (generator.definition.offsetY + (generator.Height * 0.5f));
            var radius2D    = new Vector2(generator.definition.diameterX, generator.definition.diameterZ) * 0.5f;

            if (generator.Height < 0)
            {
                normal = -normal;
            }

            EditorGUI.BeginChangeCheck();
            {
                UnityEditor.Handles.color = baseColor;
                // TODO: make it possible to (optionally) size differently in x & z
                radius2D.x = UnitySceneExtensions.SceneHandles.RadiusHandle(normal, middlePoint, radius2D.x);

                var topId = GUIUtility.GetControlID(s_TopHash, FocusType.Passive);
                {
                    var isTopBackfaced = CSGCylinderEditor.IsSufaceBackFaced(topPoint, normal);
                    var topHasFocus    = (focusControl == topId);

                    UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, topHasFocus, isTopBackfaced, isDisabled);
                    topPoint = UnitySceneExtensions.SceneHandles.DirectionHandle(topId, topPoint, normal);
                    if (!generator.HaveRoundedTop)
                    {
                        //var roundedTopPoint	= normal * generator.definition.topOffset;
                        var thickness = topHasFocus ? kCapLineThicknessSelected : kCapLineThickness;

                        UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, topHasFocus, true, isDisabled);
                        CSGOutlineRenderer.DrawLineLoop(vertices, generator.definition.topVertexOffset, generator.definition.sides, lineMode: LineMode.NoZTest, thickness: thickness);

                        UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, topHasFocus, false, isDisabled);
                        CSGOutlineRenderer.DrawLineLoop(vertices, generator.definition.topVertexOffset, generator.definition.sides, lineMode: LineMode.ZTest, thickness: thickness);
                    }
                }

                var bottomId = GUIUtility.GetControlID(s_BottomHash, FocusType.Passive);
                {
                    var isBottomBackfaced = CSGCylinderEditor.IsSufaceBackFaced(bottomPoint, -normal);
                    var bottomHasFocus    = (focusControl == bottomId);

                    UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, bottomHasFocus, isBottomBackfaced, isDisabled);
                    bottomPoint = UnitySceneExtensions.SceneHandles.DirectionHandle(bottomId, bottomPoint, -normal);
                    if (!generator.HaveRoundedBottom)
                    {
                        //var roundedBottomPoint	= normal * generator.definition.bottomOffset;
                        var thickness = bottomHasFocus ? kCapLineThicknessSelected : kCapLineThickness;

                        UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, bottomHasFocus, true, isDisabled);
                        CSGOutlineRenderer.DrawLineLoop(vertices, generator.definition.bottomVertexOffset, generator.definition.sides, lineMode: LineMode.NoZTest, thickness: thickness);

                        UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, bottomHasFocus, false, isDisabled);
                        CSGOutlineRenderer.DrawLineLoop(vertices, generator.definition.bottomVertexOffset, generator.definition.sides, lineMode: LineMode.ZTest, thickness: thickness);
                    }
                }
            }
            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(target, "Modified " + generator.NodeTypeName);
                generator.definition.diameterX = radius2D.x * 2.0f;
                generator.definition.height    = topPoint.y - bottomPoint.y;
                generator.definition.diameterZ = radius2D.x * 2.0f;
                generator.definition.offsetY   = bottomPoint.y;
                generator.OnValidate();
                // TODO: handle sizing down (needs to modify transformation?)
            }
        }
Exemplo n.º 5
0
        protected override void OnScene(CSGStadium generator)
        {
            var baseColor     = UnityEditor.Handles.yAxisColor;
            var isDisabled    = UnitySceneExtensions.SceneHandles.disabled;
            var focusControl  = UnitySceneExtensions.SceneHandleUtility.focusControl;
            var upVector      = Vector3.up;
            var rightVector   = Vector3.right;
            var forwardVector = Vector3.forward;

            Vector3[] vertices = null;
            if (!BrushMeshAssetFactory.GenerateStadiumVertices(generator.definition, ref vertices))
            {
                return;
            }


            UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, false, false, isDisabled);
            DrawOutline(generator.definition, vertices, lineMode: LineMode.ZTest);

            UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, false, true, isDisabled);
            DrawOutline(generator.definition, vertices, lineMode: LineMode.NoZTest);

            var height   = generator.definition.height;
            var length   = generator.definition.length;
            var diameter = generator.definition.diameter;
            var sides    = generator.definition.sides;

            var firstTopSide    = generator.definition.firstTopSide;
            var lastTopSide     = generator.definition.lastTopSide;
            var firstBottomSide = generator.definition.firstBottomSide;
            var lastBottomSide  = generator.definition.lastBottomSide;

            var haveRoundedTop    = generator.definition.haveRoundedTop;
            var haveRoundedBottom = generator.definition.haveRoundedBottom;
            var haveCenter        = generator.definition.haveCenter;
            var topLength         = generator.definition.topLength;
            var bottomLength      = generator.definition.bottomLength;


            var midY       = height * 0.5f;
            var halfLength = length * 0.5f;
            var midZ       = ((halfLength - (haveRoundedTop ? topLength : 0)) - (halfLength - (haveRoundedBottom ? bottomLength : 0))) * -0.5f;
            //	haveCenter ? ((vertices[firstTopSide].z + vertices[firstBottomSide].z) * 0.5f) : 0;

            var topPoint    = new Vector3(0, height, midZ);
            var bottomPoint = new Vector3(0, 0, midZ);
            var frontPoint  = new Vector3(0, midY, halfLength);
            var backPoint   = new Vector3(0, midY, -halfLength);
            var leftPoint   = new Vector3(diameter * 0.5f, midY, midZ);
            var rightPoint  = new Vector3(diameter * -0.5f, midY, midZ);

            EditorGUI.BeginChangeCheck();
            {
                var topId = GUIUtility.GetControlID(s_TopHash, FocusType.Passive);
                {
                    var isTopBackfaced = CSGCylinderEditor.IsSufaceBackFaced(topPoint, upVector);
                    var topHasFocus    = (focusControl == topId);

                    UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, topHasFocus, isTopBackfaced, isDisabled);
                    topPoint = UnitySceneExtensions.SceneHandles.DirectionHandle(topId, topPoint, upVector);
                    //if (generator.definition.haveRoundedTop)
                    {
                        var thickness = topHasFocus ? kCapLineThicknessSelected : kCapLineThickness;

                        UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, topHasFocus, true, isDisabled);
                        CSGOutlineRenderer.DrawLineLoop(vertices, sides, sides, lineMode: LineMode.NoZTest, thickness: thickness);
                        if (haveRoundedTop)
                        {
                            CSGOutlineRenderer.DrawLine(vertices[sides + firstTopSide], vertices[sides + lastTopSide], lineMode: LineMode.NoZTest, thickness: kVertLineThickness);
                        }
                        if (haveRoundedBottom && haveCenter)
                        {
                            CSGOutlineRenderer.DrawLine(vertices[sides + firstBottomSide], vertices[sides + lastBottomSide], lineMode: LineMode.NoZTest, thickness: kVertLineThickness);
                        }

                        UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, topHasFocus, false, isDisabled);
                        CSGOutlineRenderer.DrawLineLoop(vertices, sides, sides, lineMode: LineMode.ZTest, thickness: thickness);
                        if (haveRoundedTop)
                        {
                            CSGOutlineRenderer.DrawLine(vertices[sides + firstTopSide], vertices[sides + lastTopSide], lineMode: LineMode.ZTest, thickness: kVertLineThickness);
                        }
                        if (haveRoundedBottom && haveCenter)
                        {
                            CSGOutlineRenderer.DrawLine(vertices[sides + firstBottomSide], vertices[sides + lastBottomSide], lineMode: LineMode.ZTest, thickness: kVertLineThickness);
                        }
                    }
                }

                var bottomId = GUIUtility.GetControlID(s_BottomHash, FocusType.Passive);
                {
                    var isBottomBackfaced = CSGCylinderEditor.IsSufaceBackFaced(bottomPoint, -upVector);
                    var bottomHasFocus    = (focusControl == bottomId);

                    UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, bottomHasFocus, isBottomBackfaced, isDisabled);
                    bottomPoint = UnitySceneExtensions.SceneHandles.DirectionHandle(bottomId, bottomPoint, -upVector);
                    //if (haveRoundedBottom)
                    {
                        var thickness = bottomHasFocus ? kCapLineThicknessSelected : kCapLineThickness;

                        UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, bottomHasFocus, true, isDisabled);
                        CSGOutlineRenderer.DrawLineLoop(vertices, 0, sides, lineMode: LineMode.NoZTest, thickness: thickness);
                        if (haveRoundedTop)
                        {
                            CSGOutlineRenderer.DrawLine(vertices[firstTopSide], vertices[lastTopSide], lineMode: LineMode.NoZTest, thickness: kVertLineThickness);
                        }
                        if (haveRoundedBottom && haveCenter)
                        {
                            CSGOutlineRenderer.DrawLine(vertices[firstBottomSide], vertices[lastBottomSide], lineMode: LineMode.NoZTest, thickness: kVertLineThickness);
                        }

                        UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, bottomHasFocus, false, isDisabled);
                        CSGOutlineRenderer.DrawLineLoop(vertices, 0, sides, lineMode: LineMode.ZTest, thickness: thickness);
                        if (haveRoundedTop)
                        {
                            CSGOutlineRenderer.DrawLine(vertices[firstTopSide], vertices[lastTopSide], lineMode: LineMode.ZTest, thickness: kVertLineThickness);
                        }
                        if (haveRoundedBottom && haveCenter)
                        {
                            CSGOutlineRenderer.DrawLine(vertices[firstBottomSide], vertices[lastBottomSide], lineMode: LineMode.ZTest, thickness: kVertLineThickness);
                        }
                    }
                }

                var frontId = GUIUtility.GetControlID(s_TopHash, FocusType.Passive);
                {
                    var isTopBackfaced = CSGCylinderEditor.IsSufaceBackFaced(frontPoint, forwardVector);
                    var frontHasFocus  = (focusControl == frontId);

                    UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, frontHasFocus, isTopBackfaced, isDisabled);
                    frontPoint = UnitySceneExtensions.SceneHandles.DirectionHandle(frontId, frontPoint, forwardVector);
                }

                var backId = GUIUtility.GetControlID(s_BottomHash, FocusType.Passive);
                {
                    var isBottomBackfaced = CSGCylinderEditor.IsSufaceBackFaced(backPoint, -forwardVector);
                    var backHasFocus      = (focusControl == backId);

                    UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, backHasFocus, isBottomBackfaced, isDisabled);
                    backPoint = UnitySceneExtensions.SceneHandles.DirectionHandle(backId, backPoint, -forwardVector);
                }

                var leftId = GUIUtility.GetControlID(s_TopHash, FocusType.Passive);
                {
                    var isTopBackfaced = CSGCylinderEditor.IsSufaceBackFaced(leftPoint, rightVector);
                    var leftHasFocus   = (focusControl == leftId);

                    UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, leftHasFocus, isTopBackfaced, isDisabled);
                    leftPoint = UnitySceneExtensions.SceneHandles.DirectionHandle(leftId, leftPoint, rightVector);
                }

                var rightId = GUIUtility.GetControlID(s_BottomHash, FocusType.Passive);
                {
                    var isBottomBackfaced = CSGCylinderEditor.IsSufaceBackFaced(rightPoint, -rightVector);
                    var rightHasFocus     = (focusControl == rightId);

                    UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, rightHasFocus, isBottomBackfaced, isDisabled);
                    rightPoint = UnitySceneExtensions.SceneHandles.DirectionHandle(rightId, rightPoint, -rightVector);
                }
            }
            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(target, "Modified " + generator.NodeTypeName);
                generator.definition.height   = topPoint.y - bottomPoint.y;
                generator.definition.length   = Mathf.Max(0, frontPoint.z - backPoint.z);
                generator.definition.diameter = leftPoint.x - rightPoint.x;
                generator.OnValidate();
                // TODO: handle sizing in some directions (needs to modify transformation?)
            }
        }
        protected override void OnScene(CSGExtrudedShape generator)
        {
            var baseColor    = UnityEditor.Handles.yAxisColor;
            var isDisabled   = UnitySceneExtensions.SceneHandles.disabled;
            var focusControl = UnitySceneExtensions.SceneHandleUtility.focusControl;
            var normal       = Vector3.forward;

            var noZTestcolor = CSGCylinderEditor.GetColorForState(baseColor, false, true, isDisabled);
            var zTestcolor   = CSGCylinderEditor.GetColorForState(baseColor, false, false, isDisabled);

            /*
             * var shapeVertices2D		= new List<Vector2>();
             * var shapeSegmentIndices = new List<int>();
             * BrushFactory.GetPathVertices(generator.Shape, generator.curveSegments, shapeVertices2D, shapeSegmentIndices);
             *
             * var shapeVertices3D		= new Vector3[shapeVertices2D.Count];
             * for (int v = 0; v < shapeVertices2D.Count; v++)
             *  shapeVertices3D[v] = new Vector3(shapeVertices2D[v].x, shapeVertices2D[v].y, 0);
             */
            var shape      = generator.Shape;
            var path       = generator.Path;
            var prevMatrix = UnityEditor.Handles.matrix;

            for (int i = 0; i < path.segments.Length; i++)
            {
                var pathPoint  = path.segments[i];
                var currMatrix = pathPoint.ToMatrix();

                UnityEditor.Handles.color = baseColor;
                EditorGUI.BeginChangeCheck();
                {
                    shape = UnitySceneExtensions.SceneHandles.Curve2DHandle(currMatrix, shape);//, renderLines: false);
                }
                if (EditorGUI.EndChangeCheck())
                {
                    Undo.RecordObject(target, "Modified " + generator.NodeTypeName);
                    generator.Shape = shape;
                }

                //UnityEditor.Handles.color = noZTestcolor;
                //CSGOutlineRenderer.DrawLineLoop(prevMatrix * currMatrix, shapeVertices3D, 0, shapeVertices3D.Length, lineMode: LineMode.NoZTest, thickness: kCapLineThickness);

                //UnityEditor.Handles.color = zTestcolor;
                //CSGOutlineRenderer.DrawLineLoop(prevMatrix * currMatrix, shapeVertices3D, 0, shapeVertices3D.Length, lineMode: LineMode.ZTest,   thickness: kCapLineThickness);


                // Draw lines between different segments
                if (i + 1 < path.segments.Length)
                {
                    var nextPoint     = path.segments[i + 1];
                    var nextMatrix    = nextPoint.ToMatrix();
                    var controlPoints = shape.controlPoints;


                    for (int c = 0; c < controlPoints.Length; c++)
                    {
                        var controlPoint = controlPoints[c].position;
                        var pointA       = currMatrix.MultiplyPoint(controlPoint);
                        var pointB       = nextMatrix.MultiplyPoint(controlPoint);
                        UnityEditor.Handles.color = noZTestcolor;
                        CSGOutlineRenderer.DrawLine(pointA, pointB, lineMode: LineMode.NoZTest, thickness: kCapLineThickness, dashSize: kLineDash);

                        UnityEditor.Handles.color = zTestcolor;
                        CSGOutlineRenderer.DrawLine(pointA, pointB, lineMode: LineMode.ZTest, thickness: kCapLineThickness, dashSize: kLineDash);
                    }

                    {
                        var pointA = currMatrix.MultiplyPoint(Vector3.zero);
                        var pointB = nextMatrix.MultiplyPoint(Vector3.zero);
                        UnityEditor.Handles.color = zTestcolor;
                        CSGOutlineRenderer.DrawLine(pointA, pointB, lineMode: LineMode.NoZTest, thickness: kCapLineThickness, dashSize: kLineDash);

                        UnityEditor.Handles.color = zTestcolor;
                        CSGOutlineRenderer.DrawLine(pointA, pointB, lineMode: LineMode.ZTest, thickness: kCapLineThickness, dashSize: kLineDash);
                    }

                    UnityEditor.Handles.color = baseColor;
                }

                // TODO: cannot rotate so far that one path plane intersects with shape on another plane
                //			... or just fail when it's wrong?
            }

            for (int i = 0; i < path.segments.Length; i++)
            {
                var pathPoint = path.segments[i];
                EditorGUI.BeginChangeCheck();
                {
                    switch (Tools.current)
                    {
                    case Tool.Move:
                    {
                        pathPoint.position = UnitySceneExtensions.SceneHandles.PositionHandle(pathPoint.position, pathPoint.rotation);
                        break;
                    }

                    case Tool.Rotate:
                    {
                        if (Event.current.type == EventType.Repaint)
                        {
                            UnitySceneExtensions.SceneHandles.OutlinedDotHandleCap(0, pathPoint.position, pathPoint.rotation, UnityEditor.HandleUtility.GetHandleSize(pathPoint.position) * 0.05f, Event.current.type);
                        }
                        pathPoint.rotation = UnityEditor.Handles.RotationHandle(pathPoint.rotation, pathPoint.position);
                        break;
                    }

                    case Tool.Scale:
                    {
                        var scale2D = pathPoint.scale;
                        // TODO: create a 2D planar/bounds scale handle
                        var scale3D = UnityEditor.Handles.ScaleHandle(new Vector3(scale2D.x, 1, scale2D.y), pathPoint.position, pathPoint.rotation, UnityEditor.HandleUtility.GetHandleSize(pathPoint.position));
                        pathPoint.scale = new Vector2(scale3D.x, scale3D.z);
                    }
                    break;
                    }
                }
                if (EditorGUI.EndChangeCheck())
                {
                    Undo.RecordObject(target, "Changed path of CSGShape");
                    var originalSegments = generator.Path.segments;
                    path = new Path(new PathPoint[originalSegments.Length]);
                    Array.Copy(originalSegments, path.segments, originalSegments.Length);
                    path.segments[i] = pathPoint;
                    generator.Path   = path;
                }
            }


            // TODO: draw curved path
        }