public override void OnEdit(IChiselHandles handles)
        {
            var normal       = Vector3.up;
            var topDirection = Vector3.forward;
            var lowDirection = Vector3.forward;

            var originalOuterDiameter = settings.outerDiameter;
            var originalInnerDiameter = settings.innerDiameter;
            var originalStartAngle    = settings.startAngle;
            var originalStepHeight    = settings.stepHeight;
            var originalRotation      = settings.rotation;
            var originalHeight        = settings.height;
            var originalOrigin        = settings.origin;
            var cylinderTop           = new BrushMeshFactory.ChiselCircleDefinition {
                diameterX = 1, diameterZ = 1, height = originalOrigin.y + originalHeight
            };
            var cylinderLow = new BrushMeshFactory.ChiselCircleDefinition {
                diameterX = 1, diameterZ = 1, height = originalOrigin.y
            };
            var originalTopPoint = normal * cylinderTop.height;
            var originalLowPoint = normal * cylinderLow.height;
            var originalMidPoint = (originalTopPoint + originalLowPoint) * 0.5f;

            var outerDiameter = originalOuterDiameter;
            var innerDiameter = originalInnerDiameter;
            var topPoint      = originalTopPoint;
            var lowPoint      = originalLowPoint;
            var midPoint      = originalMidPoint;
            var startAngle    = originalStartAngle;
            var rotation      = originalRotation;

            {
                var currRotation = startAngle + rotation;
                handles.DoRotatableLineHandle(ref startAngle, lowPoint, outerDiameter * 0.5f, normal, lowDirection, Vector3.Cross(normal, lowDirection));
                handles.DoRotatableLineHandle(ref currRotation, topPoint, outerDiameter * 0.5f, normal, topDirection, Vector3.Cross(normal, topDirection));
                if (handles.modified)
                {
                    rotation = currRotation - startAngle;
                }


                // TODO: properly show things as backfaced
                // TODO: temporarily show inner or outer diameter as disabled when resizing one or the other
                // TODO: FIXME: why aren't there any arrows?
                handles.DoDirectionHandle(ref topPoint, normal, snappingStep: originalStepHeight);
                topPoint.y = math.max(lowPoint.y + originalStepHeight, topPoint.y);
                handles.DoDirectionHandle(ref lowPoint, -normal, snappingStep: originalStepHeight);
                lowPoint.y = math.min(topPoint.y - originalStepHeight, lowPoint.y);

                float minOuterDiameter = innerDiameter + ChiselSpiralStairs.kMinStairsDepth;
                {
                    var outerRadius = outerDiameter * 0.5f;
                    handles.DoRadiusHandle(ref outerRadius, Vector3.up, topPoint, renderDisc: false);
                    handles.DoRadiusHandle(ref outerRadius, Vector3.up, lowPoint, renderDisc: false);
                    outerDiameter = math.max(minOuterDiameter, outerRadius * 2.0f);
                }

                float maxInnerDiameter = outerDiameter - ChiselSpiralStairs.kMinStairsDepth;
                {
                    var innerRadius = innerDiameter * 0.5f;
                    handles.DoRadiusHandle(ref innerRadius, Vector3.up, midPoint, renderDisc: false);
                    innerDiameter = math.min(maxInnerDiameter, innerRadius * 2.0f);
                }



                // TODO: somehow put this into a separate renderer
                cylinderTop.diameterZ = cylinderTop.diameterX = cylinderLow.diameterZ = cylinderLow.diameterX = originalInnerDiameter;
                BrushMeshFactory.GetConicalFrustumVertices(cylinderLow, cylinderTop, 0, settings.innerSegments, ref s_InnerVertices);

                cylinderTop.diameterZ = cylinderTop.diameterX = cylinderLow.diameterZ = cylinderLow.diameterX = originalOuterDiameter;
                BrushMeshFactory.GetConicalFrustumVertices(cylinderLow, cylinderTop, 0, settings.outerSegments, ref s_OuterVertices);

                var originalColor = handles.color;
                var color         = handles.color;
                var outlineColor  = Color.black;
                outlineColor.a = color.a;

                handles.color = outlineColor;
                {
                    var sides = settings.outerSegments;
                    for (int i = 0, j = sides - 1; i < sides; j = i, i++)
                    {
                        var t0 = s_OuterVertices[i];
                        var t1 = s_OuterVertices[j];
                        var b0 = s_OuterVertices[i + sides];
                        var b1 = s_OuterVertices[j + sides];

                        handles.DrawLine(t0, b0, thickness: 1.0f);
                        handles.DrawLine(t0, t1, thickness: 1.0f);
                        handles.DrawLine(b0, b1, thickness: 1.0f);
                    }
                }
                {
                    var sides = settings.innerSegments;
                    for (int i = 0, j = sides - 1; i < sides; j = i, i++)
                    {
                        var t0 = s_InnerVertices[i];
                        var t1 = s_InnerVertices[j];
                        var b0 = s_InnerVertices[i + sides];
                        var b1 = s_InnerVertices[j + sides];

                        handles.DrawLine(t0, b0, thickness: 1.0f);
                        handles.DrawLine(t0, t1, thickness: 1.0f);
                        handles.DrawLine(b0, b1, thickness: 1.0f);
                    }
                }

                handles.color = originalColor;
                {
                    var sides = settings.outerSegments;
                    for (int i = 0, j = sides - 1; i < sides; j = i, i++)
                    {
                        var t0 = s_OuterVertices[i];
                        var t1 = s_OuterVertices[j];
                        var b0 = s_OuterVertices[i + sides];
                        var b1 = s_OuterVertices[j + sides];

                        handles.DrawLine(t0, b0, thickness: 1.0f);
                        handles.DrawLine(t0, t1, thickness: 1.0f);
                        handles.DrawLine(b0, b1, thickness: 1.0f);
                    }
                }
                {
                    var sides = settings.innerSegments;
                    for (int i = 0, j = sides - 1; i < sides; j = i, i++)
                    {
                        var t0 = s_InnerVertices[i];
                        var t1 = s_InnerVertices[j];
                        var b0 = s_InnerVertices[i + sides];
                        var b1 = s_InnerVertices[j + sides];


                        handles.DrawLine(t0, b0, thickness: 1.0f);
                        handles.DrawLine(t0, t1, thickness: 1.0f);
                        handles.DrawLine(b0, b1, thickness: 1.0f);

                        var m0 = (t0 + b0) * 0.5f;
                        var m1 = (t1 + b1) * 0.5f;
                        handles.DrawLine(m0, m1, thickness: 2.0f);
                    }
                }
            }
            if (handles.modified)
            {
                settings.outerDiameter = outerDiameter;
                settings.innerDiameter = innerDiameter;
                settings.startAngle    = startAngle;
                settings.rotation      = rotation;

                if (topPoint != originalTopPoint)
                {
                    settings.height = topPoint.y - lowPoint.y;
                }

                if (lowPoint != originalLowPoint)
                {
                    settings.height = topPoint.y - lowPoint.y;
                    var newOrigin = originalOrigin;
                    newOrigin.y    += lowPoint.y - originalLowPoint.y;
                    settings.origin = newOrigin;
                }
            }
        }
        public void OnEdit(IChiselHandles handles)
        {
            var baseColor    = handles.color;
            var noZTestcolor = handles.GetStateColor(baseColor, false, true);
            var zTestcolor   = handles.GetStateColor(baseColor, false, false);

            path.UpgradeIfNecessary();

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

                handles.color = baseColor;
                handles.DoShapeHandle(ref shape, currMatrix);

                if (i == 0)
                {
                    if (handles.DoDirectionHandle(ref pathPoint.position, -(pathPoint.rotation * Vector3.forward)))
                    {
                        path.segments[i] = pathPoint;
                        path             = new ChiselPath(path);
                    }
                }
                else
                if (i == path.segments.Length - 1)
                {
                    if (handles.DoDirectionHandle(ref pathPoint.position, (pathPoint.rotation * Vector3.forward)))
                    {
                        path.segments[i] = pathPoint;
                        path             = new ChiselPath(path);
                    }
                }


                // 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);
                        handles.color = noZTestcolor;
                        handles.DrawLine(pointA, pointB, lineMode: LineMode.NoZTest, thickness: kCapLineThickness, dashSize: kLineDash);

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

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

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

                    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];
                if (handles.DoPathPointHandle(ref pathPoint))
                {
                    var originalSegments = path.segments;
                    var newPath          = new ChiselPath(new ChiselPathPoint[originalSegments.Length]);
                    System.Array.Copy(originalSegments, newPath.segments, originalSegments.Length);
                    newPath.segments[i] = pathPoint;
                    path = newPath;
                }
            }

            // TODO: draw curved path
        }
Beispiel #3
0
            public void Update(IChiselHandles handles, ChiselCylinderDefinition definition)
            {
                var tempBottomDiameterX = definition.BottomDiameterX;
                var tempBottomDiameterZ = definition.isEllipsoid ? definition.BottomDiameterZ : definition.BottomDiameterX;

                float tempTopDiameterX, tempTopDiameterZ;

                if (definition.type == CylinderShapeType.Cone)
                {
                    tempTopDiameterX = 0;
                    tempTopDiameterZ = 0;
                }
                else
                if (definition.type == CylinderShapeType.Cylinder)
                {
                    tempTopDiameterX = tempBottomDiameterX;
                    tempTopDiameterZ = tempBottomDiameterZ;
                }
                else
                {
                    tempTopDiameterX = definition.TopDiameterX;
                    tempTopDiameterZ = definition.isEllipsoid ? definition.TopDiameterZ : definition.TopDiameterX;
                }

                topY    = (definition.height + definition.bottomOffset);
                bottomY = definition.bottomOffset;
                var rotate = Quaternion.AngleAxis(definition.rotation, Vector3.up);

                topXVector    = rotate * Vector3.right * tempTopDiameterX * 0.5f;
                topZVector    = rotate * Vector3.forward * tempTopDiameterZ * 0.5f;
                bottomXVector = rotate * Vector3.right * tempBottomDiameterX * 0.5f;
                bottomZVector = rotate * Vector3.forward * tempBottomDiameterZ * 0.5f;
                normal        = Vector3.up;
                if (topY < bottomY)
                {
                    normal = -Vector3.up;
                }
                else
                {
                    normal = Vector3.up;
                }
                topPoint    = normal * topY;
                bottomPoint = normal * bottomY;


                // Render vertical horizon of cylinder
                // TODO: make this work with math instead of "finding" it
                Vector3     bottomPointA, topPointA;
                Vector3     bottomPointB, topPointB;
                var         camera          = UnityEngine.Camera.current;
                var         cameraTransform = camera.transform;
                var         cameraPosition  = handles.inverseMatrix.MultiplyPoint(cameraTransform.position);
                const float degreeStep      = 5;
                var         pointA          = fullTopCircleHandle.GetPointAtDegree(360 - degreeStep);
                var         pointB          = fullBottomCircleHandle.GetPointAtDegree(360 - degreeStep);
                var         camOrtho        = camera.orthographic;
                var         camForward      = handles.inverseMatrix.MultiplyVector(cameraTransform.forward).normalized;
                var         camDir          = camOrtho ? camForward : (pointA - cameraPosition).normalized;


                var delta   = (pointA - pointB).normalized;
                var normal3 = -Vector3.Cross(delta, Vector3.Cross((pointB - bottomPoint).normalized, delta)).normalized;
                var prevDot = Vector3.Dot(normal3, camDir) < 0;

                bool renderHorizon = false;

                //*
                bottomPointA = Vector3.zero;
                topPointA    = Vector3.zero;
                bottomPointB = Vector3.zero;
                topPointB    = Vector3.zero;
                var lineCount = 0;

                for (float degree = 0; degree < 360; degree += degreeStep)
                {
                    pointA = fullTopCircleHandle.GetPointAtDegree(degree);
                    pointB = fullBottomCircleHandle.GetPointAtDegree(degree);

                    delta   = (pointA - pointB).normalized;
                    normal3 = -Vector3.Cross(delta, Vector3.Cross((pointB - bottomPoint).normalized, delta)).normalized;

                    camDir = camOrtho ? camForward : (pointB - cameraPosition).normalized;
                    var currDot = Vector3.Dot(normal3, camDir) < 0;

                    if (prevDot != currDot)
                    {
                        lineCount++;
                        if (lineCount == 1)
                        {
                            topPointA    = pointA;
                            bottomPointA = pointB;
                        }
                        else
                        //if (lineCount == 2)
                        {
                            topPointB     = pointA;
                            bottomPointB  = pointB;
                            renderHorizon = true;
                            break;
                        }
                    }
                    prevDot = currDot;
                }

    #if false
                {
                    var pointC = (Vector3.right * (definition.topDiameterX * 0.5f)) + (Vector3.up * (definition.height + definition.bottomOffset));
                    var pointD = (Vector3.right * (definition.bottomDiameterX * 0.5f)) + (Vector3.up * definition.bottomOffset);
                    //var deltar      = (pointC - pointD).normalized;
                    //var normala     = -Vector3.Cross(Vector3.forward, deltar).normalized;


                    var DT  = (cameraPosition - topPoint);
                    var DB  = (cameraPosition - bottomPoint);
                    var DmT = DT.magnitude;
                    var DmB = DB.magnitude;
                    //var Dv = D / Dm;

                    var RmT = definition.topDiameterX * 0.5f;
                    var RmB = definition.bottomDiameterX * 0.5f;

                    var cosAT = RmT / DmT;
                    var cosAB = RmB / DmB;
                    var AT    = Mathf.Acos(cosAT) * Mathf.Rad2Deg;
                    var AB    = Mathf.Acos(cosAB) * Mathf.Rad2Deg;
                    var RvT   = (Quaternion.AngleAxis(AT, Vector3.up) * DT).normalized;
                    var RvB   = (Quaternion.AngleAxis(AB, Vector3.up) * DB).normalized;
                    //var R = Rv * Rm;

                    var angleT = Vector3.SignedAngle(Vector3.right, RvT, Vector3.up);
                    var angleB = Vector3.SignedAngle(Vector3.right, RvB, Vector3.up);

                    var arotationT = Quaternion.AngleAxis(angleT, Vector3.up);
                    var arotationB = Quaternion.AngleAxis(angleB, Vector3.up);
                    var ptA        = arotationT * pointC;
                    var ptB        = arotationB * pointD;
                    var prevCol    = handles.color;
                    handles.color = UnityEngine.Color.red;
                    handles.DrawLine(bottomPoint, bottomPoint + Vector3.right);
                    //handles.DrawLine(bottomPoint, bottomPoint + Vector3.forward);
                    //handles.DrawLine(bottomPoint, bottomPoint + normala);
                    //handles.DrawLine(bottomPoint, bottomPoint + deltar);
                    //handles.DrawLine(bottomPoint, bottomPoint + R);
                    handles.DrawLine(bottomPoint, bottomPoint + RvT);
                    handles.DrawLine(bottomPoint, bottomPoint + RvB);
                    //handles.DrawLine(bottomPoint, bottomPoint + desired);
                    handles.DrawLine(ptA, ptB);
                    handles.color = prevCol;
                }
    #endif


                /*/
                 * if (camera.orthographic)
                 * {
                 *  {
                 *      var radius = definition.bottomDiameterX * 0.5f;
                 *      var center = bottomPoint;
                 *      bottomPointA = center + (cameraTransform.right * radius);
                 *      bottomPointB = center - (cameraTransform.right * radius);
                 *  }
                 *  {
                 *      var radius = definition.topDiameterX * 0.5f;
                 *      var center = topPoint;
                 *      topPointA = center + (cameraTransform.right * radius);
                 *      topPointB = center - (cameraTransform.right * radius);
                 *  }
                 * } else
                 * {
                 *  var handleMatrix = handles.matrix;
                 *  renderHorizon = GeometryMath.FindCircleHorizon(handleMatrix, definition.bottomDiameterX, bottomPoint, -normal, out bottomPointB, out bottomPointA);
                 *  renderHorizon = GeometryMath.FindCircleHorizon(handleMatrix, definition.topDiameterX,    topPoint,     normal, out topPointA,    out topPointB) && renderHorizon;
                 *
                 *  if (renderHorizon && definition.bottomDiameterX != definition.topDiameterX)
                 *  {
                 *      renderHorizon = !(GeometryMath.PointInCameraCircle(handleMatrix, bottomPointA, definition.topDiameterX,    topPoint,     normal) ||
                 *                        GeometryMath.PointInCameraCircle(handleMatrix, topPointA,    definition.bottomDiameterX, bottomPoint, -normal) ||
                 *                        GeometryMath.PointInCameraCircle(handleMatrix, bottomPointB, definition.topDiameterX,    topPoint,     normal) ||
                 *                        GeometryMath.PointInCameraCircle(handleMatrix, topPointB,    definition.bottomDiameterX, bottomPoint, -normal));
                 *  }
                 * }
                 * //*/

                if (!renderHorizon)
                {
                    bottomPointA = Vector3.zero;
                    topPointA    = Vector3.zero;
                    bottomPointB = Vector3.zero;
                    topPointB    = Vector3.zero;
                }

                verticalHandle1.From = bottomPointA;
                verticalHandle1.To   = topPointA;
                verticalHandle2.From = bottomPointB;
                verticalHandle2.To   = topPointB;

                fullTopCircleHandle.Center    = topPoint;
                fullBottomCircleHandle.Center = bottomPoint;

                fullTopCircleHandle.DiameterX    = tempTopDiameterX;
                fullTopCircleHandle.DiameterZ    = tempTopDiameterZ;
                fullBottomCircleHandle.DiameterX = tempBottomDiameterX;
                fullBottomCircleHandle.DiameterZ = tempBottomDiameterZ;

                topHandle.Origin    = topPoint;
                bottomHandle.Origin = bottomPoint;


                fullTopCircleHandle.Normal    = normal;
                fullBottomCircleHandle.Normal = -normal;

                topHandle.Normal    = normal;
                bottomHandle.Normal = -normal;


                if (definition.isEllipsoid)
                {
                    if (bottomRadiusHandles == null || bottomRadiusHandles.Length != 4)
                    {
                        bottomRadiusHandles = new IChiselEllipsoidHandle[]
                        {
                            handles.CreateEllipsoidHandle(Vector3.zero, -normal, 0, 0, startAngle: +45f, angles: 90),        // left
                            handles.CreateEllipsoidHandle(Vector3.zero, -normal, 0, 0, startAngle: +45f + 180f, angles: 90), // right
                            handles.CreateEllipsoidHandle(Vector3.zero, -normal, 0, 0, startAngle: -45f, angles: 90),        // forward
                            handles.CreateEllipsoidHandle(Vector3.zero, -normal, 0, 0, startAngle: -45f + 180f, angles: 90), // back
                        };
                    }

                    if (topRadiusHandles == null || topRadiusHandles.Length != 4)
                    {
                        topRadiusHandles = new IChiselEllipsoidHandle[]
                        {
                            handles.CreateEllipsoidHandle(Vector3.zero, normal, 0, 0, startAngle: +45f, angles: 90),          // left
                            handles.CreateEllipsoidHandle(Vector3.zero, normal, 0, 0, startAngle: +45f + 180f, angles: 90),   // right
                            handles.CreateEllipsoidHandle(Vector3.zero, normal, 0, 0, startAngle: -45f, angles: 90),          // forward
                            handles.CreateEllipsoidHandle(Vector3.zero, normal, 0, 0, startAngle: -45f + 180f, angles: 90),   // back
                        };
                    }

                    for (int i = 0; i < bottomRadiusHandles.Length; i++)
                    {
                        bottomRadiusHandles[i].Center    = bottomPoint;
                        bottomRadiusHandles[i].Normal    = -normal;
                        bottomRadiusHandles[i].DiameterX = tempBottomDiameterX;
                        bottomRadiusHandles[i].DiameterZ = tempBottomDiameterZ;
                        bottomRadiusHandles[i].Rotation  = definition.rotation;
                    }

                    for (int i = 0; i < topRadiusHandles.Length; i++)
                    {
                        topRadiusHandles[i].Center    = topPoint;
                        topRadiusHandles[i].Normal    = normal;
                        topRadiusHandles[i].DiameterX = tempTopDiameterX;
                        topRadiusHandles[i].DiameterZ = tempTopDiameterZ;
                        topRadiusHandles[i].Rotation  = definition.rotation;
                    }

                    if (bottomHandles == null || bottomHandles.Length != 4)
                    {
                        bottomHandles = new IChiselHandle[] { bottomHandle, bottomRadiusHandles[0], bottomRadiusHandles[1], bottomRadiusHandles[2], bottomRadiusHandles[3] }
                    }
                    ;
                    if (definition.type != CylinderShapeType.Cone)
                    {
                        if (topHandles == null || topHandles.Length != 5)
                        {
                            topHandles = new IChiselHandle[] { topHandle, topRadiusHandles[0], topRadiusHandles[1], topRadiusHandles[2], topRadiusHandles[3] }
                        }
                        ;
                    }
                    else
                    {
                        if (topHandles == null || topHandles.Length != 1)
                        {
                            topHandles = new IChiselHandle[] { topHandle }
                        }
                        ;
                    }
                }
                else
                {
                    if (bottomRadiusHandles == null || bottomRadiusHandles.Length != 1)
                    {
                        bottomRadiusHandles = new IChiselEllipsoidHandle[] { fullBottomCircleHandle }
                    }
                    ;
                    if (topRadiusHandles == null || topRadiusHandles.Length != 1)
                    {
                        topRadiusHandles = new IChiselEllipsoidHandle[] { fullTopCircleHandle }
                    }
                    ;

                    if (bottomHandles == null || bottomHandles.Length != 2)
                    {
                        bottomHandles = new IChiselHandle[] { bottomHandle, bottomRadiusHandles[0] }
                    }
                    ;
                    if (definition.type != CylinderShapeType.Cone)
                    {
                        if (topHandles == null || topHandles.Length != 2)
                        {
                            topHandles = new IChiselHandle[] { topHandle, topRadiusHandles[0] }
                        }
                        ;
                    }
                    else
                    {
                        if (topHandles == null || topHandles.Length != 1)
                        {
                            topHandles = new IChiselHandle[] { topHandle }
                        }
                        ;
                    }
                }
            }
        }
Beispiel #4
0
        public void OnEdit(IChiselHandles handles)
        {
            var baseColor     = handles.color;
            var upVector      = Vector3.up;
            var rightVector   = Vector3.right;
            var forwardVector = Vector3.forward;

            Vector3[] vertices = null;
            if (BrushMeshFactory.GenerateStadiumVertices(this, ref vertices))
            {
                handles.color = handles.GetStateColor(baseColor, false, false);
                DrawOutline(handles, this, vertices, lineMode: LineMode.ZTest);

                handles.color = handles.GetStateColor(baseColor, false, true);
                DrawOutline(handles, this, vertices, lineMode: LineMode.NoZTest);
                handles.color = baseColor;
            }

            var height   = this.height;
            var length   = this.length;
            var diameter = this.diameter;
            var sides    = this.sides;

            var firstTopSide    = this.firstTopSide;
            var lastTopSide     = this.lastTopSide;
            var firstBottomSide = this.firstBottomSide;
            var lastBottomSide  = this.lastBottomSide;

            var haveRoundedTop    = this.haveRoundedTop;
            var haveRoundedBottom = this.haveRoundedBottom;
            var haveCenter        = this.haveCenter;
            var topLength         = this.topLength;
            var bottomLength      = this.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);

            {
                {
                    var isTopBackfaced = handles.IsSufaceBackFaced(topPoint, upVector);

                    handles.backfaced = isTopBackfaced;
                    handles.DoDirectionHandle(ref topPoint, upVector);
                    var topHasFocus = handles.lastHandleHadFocus;
                    handles.backfaced = false;
                    //if (this.haveRoundedTop)
                    {
                        var thickness = topHasFocus ? kCapLineThicknessSelected : kCapLineThickness;

                        handles.color = handles.GetStateColor(handles.color, topHasFocus, true);
                        handles.DrawLineLoop(vertices, sides, sides, lineMode: LineMode.NoZTest, thickness: thickness);
                        if (haveRoundedTop)
                        {
                            handles.DrawLine(vertices[sides + firstTopSide], vertices[sides + lastTopSide], lineMode: LineMode.NoZTest, thickness: kVertLineThickness);
                        }
                        if (haveRoundedBottom && haveCenter)
                        {
                            handles.DrawLine(vertices[sides + firstBottomSide], vertices[sides + lastBottomSide], lineMode: LineMode.NoZTest, thickness: kVertLineThickness);
                        }

                        handles.color = handles.GetStateColor(handles.color, topHasFocus, false);
                        handles.DrawLineLoop(vertices, sides, sides, lineMode: LineMode.ZTest, thickness: thickness);
                        if (haveRoundedTop)
                        {
                            handles.DrawLine(vertices[sides + firstTopSide], vertices[sides + lastTopSide], lineMode: LineMode.ZTest, thickness: kVertLineThickness);
                        }
                        if (haveRoundedBottom && haveCenter)
                        {
                            handles.DrawLine(vertices[sides + firstBottomSide], vertices[sides + lastBottomSide], lineMode: LineMode.ZTest, thickness: kVertLineThickness);
                        }
                    }
                }

                {
                    var isBottomBackfaced = handles.IsSufaceBackFaced(bottomPoint, -upVector);

                    handles.backfaced = isBottomBackfaced;
                    handles.DoDirectionHandle(ref bottomPoint, -upVector);
                    var bottomHasFocus = handles.lastHandleHadFocus;
                    handles.backfaced = false;
                    //if (this.haveRoundedBottom)
                    {
                        var thickness = bottomHasFocus ? kCapLineThicknessSelected : kCapLineThickness;

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

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

                {
                    var isTopBackfaced = handles.IsSufaceBackFaced(frontPoint, forwardVector);

                    handles.backfaced = isTopBackfaced;
                    handles.DoDirectionHandle(ref frontPoint, forwardVector);
                    handles.backfaced = false;
                }

                {
                    var isBottomBackfaced = handles.IsSufaceBackFaced(backPoint, -forwardVector);

                    handles.backfaced = isBottomBackfaced;
                    handles.DoDirectionHandle(ref backPoint, -forwardVector);
                    handles.backfaced = false;
                }

                {
                    var isTopBackfaced = handles.IsSufaceBackFaced(leftPoint, rightVector);

                    handles.backfaced = isTopBackfaced;
                    handles.DoDirectionHandle(ref leftPoint, rightVector);
                    handles.backfaced = false;
                }

                {
                    var isBottomBackfaced = handles.IsSufaceBackFaced(rightPoint, -rightVector);

                    handles.backfaced = isBottomBackfaced;
                    handles.DoDirectionHandle(ref rightPoint, -rightVector);
                    handles.backfaced = false;
                }
            }
            if (handles.modified)
            {
                this.height   = topPoint.y - bottomPoint.y;
                this.length   = Mathf.Max(0, frontPoint.z - backPoint.z);
                this.diameter = leftPoint.x - rightPoint.x;
                // TODO: handle sizing in some directions (needs to modify transformation?)
            }
        }
        public void OnEdit(IChiselHandles handles)
        {
            var baseColor = handles.color;
            var normal    = Vector3.forward;

            var controlPoints = shape.controlPoints;

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

            BrushMeshFactory.GetPathVertices(this.shape, this.curveSegments, shapeVertices, shapeSegmentIndices);


            var horzSegments         = this.revolveSegments;
            var horzDegreePerSegment = this.totalAngle / horzSegments;
            var horzOffset           = this.startAngle;

            var noZTestcolor = handles.GetStateColor(baseColor, false, true);
            var zTestcolor   = handles.GetStateColor(baseColor, false, false);

            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);

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

                    handles.color = zTestcolor;
                    handles.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);

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

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

            {
                // TODO: make this work non grid aligned so we can place it upwards
                handles.DoShapeHandle(ref shape);
                handles.DrawLine(normal * 10, normal * -10, dashSize: 4.0f);
            }
        }