private void DrawLine(ICurvedPlane curvedPlane, float bottom, float top, float deg)
        {
            Vector3 forward = Quaternion.Euler(0, curvedPlane.Rotation + deg, 0) *
                              Vector3.forward * curvedPlane.Cylinder.Radius;

            Vector3 p1 = curvedPlane.Cylinder.transform.TransformPoint((Vector3.up * bottom) + forward);
            Vector3 p2 = curvedPlane.Cylinder.transform.TransformPoint((Vector3.up * top) + forward);

#if UNITY_2020_2_OR_NEWER
            Handles.DrawLine(p1, p2, EditorConstants.LINE_THICKNESS);
#else
            Handles.DrawLine(p1, p2);
#endif
        }
        private void DrawArc(ICurvedPlane curvedPlane, float y)
        {
            Vector3 center  = curvedPlane.Cylinder.transform.TransformPoint(new Vector3(0, y, 0));
            Vector3 forward = curvedPlane.Cylinder.transform.TransformDirection(
                Quaternion.Euler(0, curvedPlane.Rotation - curvedPlane.ArcDegrees / 2, 0) *
                Vector3.forward);

            Handles.DrawWireArc(center,
                                curvedPlane.Cylinder.transform.up,
                                forward,
                                curvedPlane.ArcDegrees,
                                curvedPlane.Cylinder.Radius * curvedPlane.Cylinder.transform.lossyScale.z
#if UNITY_2020_2_OR_NEWER
                                , EditorConstants.LINE_THICKNESS
#endif
                                );
        }
        public void OnSceneGUI()
        {
            ICurvedPlane curvedPlane = _curvedPlaneProperty.objectReferenceValue as ICurvedPlane;

            if (curvedPlane == null)
            {
                curvedPlane = target as ICurvedPlane;
            }

            if (curvedPlane.Cylinder == null ||
                curvedPlane.ArcDegrees <= 0f)
            {
                return;
            }

            Handles.color = EditorConstants.PRIMARY_COLOR;

            // Handle infinite height using scene camera Y
            float top, bottom;

            if (curvedPlane.Top <= curvedPlane.Bottom)
            {
                if (SceneView.lastActiveSceneView != null &&
                    SceneView.lastActiveSceneView.camera != null)
                {
                    Vector3 cameraPos =
                        curvedPlane.Cylinder.transform.InverseTransformPoint(
                            SceneView.lastActiveSceneView.camera.transform.position);
                    bottom = cameraPos.y - 10;
                    top    = cameraPos.y + 10;
                }
                else
                {
                    bottom = -30;
                    top    = 30;
                }
            }
            else
            {
                bottom = curvedPlane.Bottom;
                top    = curvedPlane.Top;
            }

            float height             = top - bottom;
            float width              = curvedPlane.ArcDegrees * Mathf.Deg2Rad * curvedPlane.Cylinder.Radius;
            int   verticalSegments   = Mathf.Max(2, Mathf.CeilToInt(SEGMENTS_PER_UNIT * height));
            int   horizontalSegments = Mathf.Max(2, Mathf.FloorToInt(SEGMENTS_PER_UNIT * width));

            for (int v = 0; v <= verticalSegments; ++v)
            {
                float y = Mathf.Lerp(bottom, top, (float)v / verticalSegments);
                DrawArc(curvedPlane, y);
            }

            for (int h = 0; h <= horizontalSegments; ++h)
            {
                float x = Mathf.Lerp(-curvedPlane.ArcDegrees / 2,
                                     curvedPlane.ArcDegrees / 2,
                                     (float)h / horizontalSegments);
                DrawLine(curvedPlane, bottom, top, x);
            }
        }