From a10eea6e4ce647061813519d5b0ea496f29495b9 Mon Sep 17 00:00:00 2001
From: leonard Wu <364452445@qq.com>
Date: 星期四, 09 八月 2018 09:47:08 +0800
Subject: [PATCH] 同步最新svn内容

---
 Assets/Plugins/PostProcessing/Editor/Models/ColorGradingModelEditor.cs | 1344 +++++++++++++++++++++++++++++-----------------------------
 1 files changed, 672 insertions(+), 672 deletions(-)

diff --git a/Assets/Plugins/PostProcessing/Editor/Models/ColorGradingModelEditor.cs b/Assets/Plugins/PostProcessing/Editor/Models/ColorGradingModelEditor.cs
index 8d73982..91a3e5b 100644
--- a/Assets/Plugins/PostProcessing/Editor/Models/ColorGradingModelEditor.cs
+++ b/Assets/Plugins/PostProcessing/Editor/Models/ColorGradingModelEditor.cs
@@ -1,672 +1,672 @@
-using UnityEngine;
-using UnityEngine.PostProcessing;
-using System;
-using System.Collections.Generic;
-using System.Linq.Expressions;
-
-namespace UnityEditor.PostProcessing
-{
-    using Settings = ColorGradingModel.Settings;
-    using Tonemapper = ColorGradingModel.Tonemapper;
-	using ColorWheelMode = ColorGradingModel.ColorWheelMode;
-
-    [PostProcessingModelEditor(typeof(ColorGradingModel))]
-    public class ColorGradingModelEditor : PostProcessingModelEditor
-    {
-        static GUIContent[] s_Tonemappers =
-        {
-            new GUIContent("None"),
-            new GUIContent("Filmic (ACES)"),
-            new GUIContent("Neutral")
-        };
-
-        struct TonemappingSettings
-        {
-            public SerializedProperty tonemapper;
-            public SerializedProperty neutralBlackIn;
-            public SerializedProperty neutralWhiteIn;
-            public SerializedProperty neutralBlackOut;
-            public SerializedProperty neutralWhiteOut;
-            public SerializedProperty neutralWhiteLevel;
-            public SerializedProperty neutralWhiteClip;
-        }
-
-        struct BasicSettings
-        {
-            public SerializedProperty exposure;
-            public SerializedProperty temperature;
-            public SerializedProperty tint;
-            public SerializedProperty hueShift;
-            public SerializedProperty saturation;
-            public SerializedProperty contrast;
-        }
-
-        struct ChannelMixerSettings
-        {
-            public SerializedProperty[] channels;
-            public SerializedProperty currentEditingChannel;
-        }
-
-        struct ColorWheelsSettings
-        {
-	        public SerializedProperty mode;
-            public SerializedProperty log;
-            public SerializedProperty linear;
-        }
-
-        static GUIContent[] s_Curves =
-        {
-            new GUIContent("YRGB"),
-            new GUIContent("Hue VS Hue"),
-            new GUIContent("Hue VS Sat"),
-            new GUIContent("Sat VS Sat"),
-            new GUIContent("Lum VS Sat")
-        };
-
-        struct CurvesSettings
-        {
-            public SerializedProperty master;
-            public SerializedProperty red;
-            public SerializedProperty green;
-            public SerializedProperty blue;
-
-            public SerializedProperty hueVShue;
-            public SerializedProperty hueVSsat;
-            public SerializedProperty satVSsat;
-            public SerializedProperty lumVSsat;
-
-            public SerializedProperty currentEditingCurve;
-            public SerializedProperty curveY;
-            public SerializedProperty curveR;
-            public SerializedProperty curveG;
-            public SerializedProperty curveB;
-        }
-
-        TonemappingSettings m_Tonemapping;
-        BasicSettings m_Basic;
-        ChannelMixerSettings m_ChannelMixer;
-        ColorWheelsSettings m_ColorWheels;
-        CurvesSettings m_Curves;
-
-        CurveEditor m_CurveEditor;
-        Dictionary<SerializedProperty, Color> m_CurveDict;
-
-		// Neutral tonemapping curve helper
-        const int k_CurveResolution = 24;
-        const float k_NeutralRangeX = 2f;
-        const float k_NeutralRangeY = 1f;
-        Vector3[] m_RectVertices = new Vector3[4];
-        Vector3[] m_LineVertices = new Vector3[2];
-        Vector3[] m_CurveVertices = new Vector3[k_CurveResolution];
-	    Rect m_NeutralCurveRect;
-
-        public override void OnEnable()
-        {
-            // Tonemapping settings
-            m_Tonemapping = new TonemappingSettings
-            {
-                tonemapper = FindSetting((Settings x) => x.tonemapping.tonemapper),
-                neutralBlackIn = FindSetting((Settings x) => x.tonemapping.neutralBlackIn),
-                neutralWhiteIn = FindSetting((Settings x) => x.tonemapping.neutralWhiteIn),
-                neutralBlackOut = FindSetting((Settings x) => x.tonemapping.neutralBlackOut),
-                neutralWhiteOut = FindSetting((Settings x) => x.tonemapping.neutralWhiteOut),
-                neutralWhiteLevel = FindSetting((Settings x) => x.tonemapping.neutralWhiteLevel),
-                neutralWhiteClip = FindSetting((Settings x) => x.tonemapping.neutralWhiteClip)
-            };
-
-            // Basic settings
-            m_Basic = new BasicSettings
-            {
-                exposure = FindSetting((Settings x) => x.basic.postExposure),
-                temperature = FindSetting((Settings x) => x.basic.temperature),
-                tint = FindSetting((Settings x) => x.basic.tint),
-                hueShift = FindSetting((Settings x) => x.basic.hueShift),
-                saturation = FindSetting((Settings x) => x.basic.saturation),
-                contrast = FindSetting((Settings x) => x.basic.contrast)
-            };
-
-            // Channel mixer
-            m_ChannelMixer = new ChannelMixerSettings
-            {
-                channels = new[]
-                {
-                    FindSetting((Settings x) => x.channelMixer.red),
-                    FindSetting((Settings x) => x.channelMixer.green),
-                    FindSetting((Settings x) => x.channelMixer.blue)
-                },
-                currentEditingChannel = FindSetting((Settings x) => x.channelMixer.currentEditingChannel)
-            };
-
-            // Color wheels
-            m_ColorWheels = new ColorWheelsSettings
-            {
-				mode = FindSetting((Settings x) => x.colorWheels.mode),
-                log = FindSetting((Settings x) => x.colorWheels.log),
-                linear = FindSetting((Settings x) => x.colorWheels.linear)
-            };
-
-            // Curves
-            m_Curves = new CurvesSettings
-            {
-                master = FindSetting((Settings x) => x.curves.master.curve),
-                red = FindSetting((Settings x) => x.curves.red.curve),
-                green = FindSetting((Settings x) => x.curves.green.curve),
-                blue = FindSetting((Settings x) => x.curves.blue.curve),
-
-                hueVShue = FindSetting((Settings x) => x.curves.hueVShue.curve),
-                hueVSsat = FindSetting((Settings x) => x.curves.hueVSsat.curve),
-                satVSsat = FindSetting((Settings x) => x.curves.satVSsat.curve),
-                lumVSsat = FindSetting((Settings x) => x.curves.lumVSsat.curve),
-
-                currentEditingCurve = FindSetting((Settings x) => x.curves.e_CurrentEditingCurve),
-                curveY = FindSetting((Settings x) => x.curves.e_CurveY),
-                curveR = FindSetting((Settings x) => x.curves.e_CurveR),
-                curveG = FindSetting((Settings x) => x.curves.e_CurveG),
-                curveB = FindSetting((Settings x) => x.curves.e_CurveB)
-            };
-
-            // Prepare the curve editor and extract curve display settings
-            m_CurveDict = new Dictionary<SerializedProperty, Color>();
-
-            var settings = CurveEditor.Settings.defaultSettings;
-
-            m_CurveEditor = new CurveEditor(settings);
-            AddCurve(m_Curves.master,   new Color(1f, 1f, 1f), 2, false);
-            AddCurve(m_Curves.red,      new Color(1f, 0f, 0f), 2, false);
-            AddCurve(m_Curves.green,    new Color(0f, 1f, 0f), 2, false);
-            AddCurve(m_Curves.blue,     new Color(0f, 0.5f, 1f), 2, false);
-            AddCurve(m_Curves.hueVShue, new Color(1f, 1f, 1f), 0, true);
-            AddCurve(m_Curves.hueVSsat, new Color(1f, 1f, 1f), 0, true);
-            AddCurve(m_Curves.satVSsat, new Color(1f, 1f, 1f), 0, false);
-            AddCurve(m_Curves.lumVSsat, new Color(1f, 1f, 1f), 0, false);
-        }
-
-        void AddCurve(SerializedProperty prop, Color color, uint minPointCount, bool loop)
-        {
-            var state = CurveEditor.CurveState.defaultState;
-            state.color = color;
-            state.visible = false;
-            state.minPointCount = minPointCount;
-            state.onlyShowHandlesOnSelection = true;
-            state.zeroKeyConstantValue = 0.5f;
-            state.loopInBounds = loop;
-            m_CurveEditor.Add(prop, state);
-            m_CurveDict.Add(prop, color);
-        }
-
-        public override void OnDisable()
-        {
-            m_CurveEditor.RemoveAll();
-        }
-
-        public override void OnInspectorGUI()
-        {
-            DoGUIFor("Tonemapping", DoTonemappingGUI);
-            EditorGUILayout.Space();
-            DoGUIFor("Basic", DoBasicGUI);
-            EditorGUILayout.Space();
-            DoGUIFor("Channel Mixer", DoChannelMixerGUI);
-            EditorGUILayout.Space();
-            DoGUIFor("Trackballs", DoColorWheelsGUI);
-            EditorGUILayout.Space();
-            DoGUIFor("Grading Curves", DoCurvesGUI);
-        }
-
-        void DoGUIFor(string title, Action func)
-        {
-            EditorGUILayout.LabelField(title, EditorStyles.boldLabel);
-            EditorGUI.indentLevel++;
-            func();
-            EditorGUI.indentLevel--;
-        }
-
-        void DoTonemappingGUI()
-        {
-            int tid = EditorGUILayout.Popup(EditorGUIHelper.GetContent("Tonemapper"), m_Tonemapping.tonemapper.intValue, s_Tonemappers);
-
-            if (tid == (int)Tonemapper.Neutral)
-            {
-	            DrawNeutralTonemappingCurve();
-
-                EditorGUILayout.PropertyField(m_Tonemapping.neutralBlackIn, EditorGUIHelper.GetContent("Black In"));
-                EditorGUILayout.PropertyField(m_Tonemapping.neutralWhiteIn, EditorGUIHelper.GetContent("White In"));
-                EditorGUILayout.PropertyField(m_Tonemapping.neutralBlackOut, EditorGUIHelper.GetContent("Black Out"));
-                EditorGUILayout.PropertyField(m_Tonemapping.neutralWhiteOut, EditorGUIHelper.GetContent("White Out"));
-                EditorGUILayout.PropertyField(m_Tonemapping.neutralWhiteLevel, EditorGUIHelper.GetContent("White Level"));
-                EditorGUILayout.PropertyField(m_Tonemapping.neutralWhiteClip, EditorGUIHelper.GetContent("White Clip"));
-            }
-
-            m_Tonemapping.tonemapper.intValue = tid;
-        }
-
-	    void DrawNeutralTonemappingCurve()
-	    {
-            using (new GUILayout.HorizontalScope())
-            {
-                GUILayout.Space(EditorGUI.indentLevel * 15f);
-                m_NeutralCurveRect = GUILayoutUtility.GetRect(128, 80);
-            }
-
-			// Background
-			m_RectVertices[0] = PointInRect(             0f,              0f);
-            m_RectVertices[1] = PointInRect(k_NeutralRangeX,              0f);
-            m_RectVertices[2] = PointInRect(k_NeutralRangeX, k_NeutralRangeY);
-            m_RectVertices[3] = PointInRect(             0f, k_NeutralRangeY);
-
-            Handles.DrawSolidRectangleWithOutline(
-                m_RectVertices,
-                Color.white * 0.1f,
-                Color.white * 0.4f
-                );
-
-            // Horizontal lines
-            for (var i = 1; i < k_NeutralRangeY; i++)
-                DrawLine(0, i, k_NeutralRangeX, i, 0.4f);
-
-            // Vertical lines
-            for (var i = 1; i < k_NeutralRangeX; i++)
-                DrawLine(i, 0, i, k_NeutralRangeY, 0.4f);
-
-			// Label
-            Handles.Label(
-                PointInRect(0, k_NeutralRangeY) + Vector3.right,
-                "Neutral Tonemapper", EditorStyles.miniLabel
-                );
-
-			// Precompute some values
-            var tonemap = ((ColorGradingModel)target).settings.tonemapping;
-
-		    const float scaleFactor = 20f;
-            const float scaleFactorHalf = scaleFactor * 0.5f;
-
-            float inBlack = tonemap.neutralBlackIn * scaleFactor + 1f;
-            float outBlack = tonemap.neutralBlackOut * scaleFactorHalf + 1f;
-            float inWhite = tonemap.neutralWhiteIn / scaleFactor;
-            float outWhite = 1f - tonemap.neutralWhiteOut / scaleFactor;
-            float blackRatio = inBlack / outBlack;
-            float whiteRatio = inWhite / outWhite;
-
-            const float a = 0.2f;
-            float b = Mathf.Max(0f, Mathf.LerpUnclamped(0.57f, 0.37f, blackRatio));
-            float c = Mathf.LerpUnclamped(0.01f, 0.24f, whiteRatio);
-            float d = Mathf.Max(0f, Mathf.LerpUnclamped(0.02f, 0.20f, blackRatio));
-            const float e = 0.02f;
-            const float f = 0.30f;
-		    float whiteLevel = tonemap.neutralWhiteLevel;
-		    float whiteClip = tonemap.neutralWhiteClip / scaleFactorHalf;
-
-			// Tonemapping curve
-            var vcount = 0;
-            while (vcount < k_CurveResolution)
-            {
-                float x = k_NeutralRangeX * vcount / (k_CurveResolution - 1);
-                float y = NeutralTonemap(x, a, b, c, d, e, f, whiteLevel, whiteClip);
-
-                if (y < k_NeutralRangeY)
-                {
-                    m_CurveVertices[vcount++] = PointInRect(x, y);
-                }
-                else
-                {
-                    if (vcount > 1)
-                    {
-                        // Extend the last segment to the top edge of the rect.
-                        var v1 = m_CurveVertices[vcount - 2];
-                        var v2 = m_CurveVertices[vcount - 1];
-                        var clip = (m_NeutralCurveRect.y - v1.y) / (v2.y - v1.y);
-                        m_CurveVertices[vcount - 1] = v1 + (v2 - v1) * clip;
-                    }
-                    break;
-                }
-            }
-
-            if (vcount > 1)
-            {
-                Handles.color = Color.white * 0.9f;
-                Handles.DrawAAPolyLine(2.0f, vcount, m_CurveVertices);
-            }
-	    }
-
-		void DrawLine(float x1, float y1, float x2, float y2, float grayscale)
-        {
-            m_LineVertices[0] = PointInRect(x1, y1);
-            m_LineVertices[1] = PointInRect(x2, y2);
-            Handles.color = Color.white * grayscale;
-            Handles.DrawAAPolyLine(2f, m_LineVertices);
-        }
-
-		Vector3 PointInRect(float x, float y)
-        {
-            x = Mathf.Lerp(m_NeutralCurveRect.x, m_NeutralCurveRect.xMax, x / k_NeutralRangeX);
-            y = Mathf.Lerp(m_NeutralCurveRect.yMax, m_NeutralCurveRect.y, y / k_NeutralRangeY);
-            return new Vector3(x, y, 0);
-        }
-
-		float NeutralCurve(float x, float a, float b, float c, float d, float e, float f)
-		{
-			return ((x * (a * x + c * b) + d * e) / (x * (a * x + b) + d * f)) - e / f;
-		}
-
-	    float NeutralTonemap(float x, float a, float b, float c, float d, float e, float f, float whiteLevel, float whiteClip)
-	    {
-			x = Mathf.Max(0f, x);
-
-			// Tonemap
-			float whiteScale = 1f / NeutralCurve(whiteLevel, a, b, c, d, e, f);
-			x = NeutralCurve(x * whiteScale, a, b, c, d, e, f);
-			x *= whiteScale;
-
-			// Post-curve white point adjustment
-			x /= whiteClip;
-
-			return x;
-	    }
-
-        void DoBasicGUI()
-        {
-            EditorGUILayout.PropertyField(m_Basic.exposure, EditorGUIHelper.GetContent("Post Exposure (EV)"));
-            EditorGUILayout.PropertyField(m_Basic.temperature);
-            EditorGUILayout.PropertyField(m_Basic.tint);
-            EditorGUILayout.PropertyField(m_Basic.hueShift);
-            EditorGUILayout.PropertyField(m_Basic.saturation);
-            EditorGUILayout.PropertyField(m_Basic.contrast);
-        }
-
-        void DoChannelMixerGUI()
-        {
-            int currentChannel = m_ChannelMixer.currentEditingChannel.intValue;
-
-            EditorGUI.BeginChangeCheck();
-            {
-                using (new EditorGUILayout.HorizontalScope())
-                {
-                    EditorGUILayout.PrefixLabel("Channel");
-                    if (GUILayout.Toggle(currentChannel == 0, EditorGUIHelper.GetContent("Red|Red output channel."), EditorStyles.miniButtonLeft)) currentChannel = 0;
-                    if (GUILayout.Toggle(currentChannel == 1, EditorGUIHelper.GetContent("Green|Green output channel."), EditorStyles.miniButtonMid)) currentChannel = 1;
-                    if (GUILayout.Toggle(currentChannel == 2, EditorGUIHelper.GetContent("Blue|Blue output channel."), EditorStyles.miniButtonRight)) currentChannel = 2;
-                }
-            }
-            if (EditorGUI.EndChangeCheck())
-            {
-                GUI.FocusControl(null);
-            }
-
-            var serializedChannel = m_ChannelMixer.channels[currentChannel];
-            m_ChannelMixer.currentEditingChannel.intValue = currentChannel;
-
-            var v = serializedChannel.vector3Value;
-            v.x = EditorGUILayout.Slider(EditorGUIHelper.GetContent("Red|Modify influence of the red channel within the overall mix."), v.x, -2f, 2f);
-            v.y = EditorGUILayout.Slider(EditorGUIHelper.GetContent("Green|Modify influence of the green channel within the overall mix."), v.y, -2f, 2f);
-            v.z = EditorGUILayout.Slider(EditorGUIHelper.GetContent("Blue|Modify influence of the blue channel within the overall mix."), v.z, -2f, 2f);
-            serializedChannel.vector3Value = v;
-        }
-
-        void DoColorWheelsGUI()
-        {
-	        int wheelMode = m_ColorWheels.mode.intValue;
-
-	        using (new EditorGUILayout.HorizontalScope())
-	        {
-		        GUILayout.Space(15);
-		        if (GUILayout.Toggle(wheelMode == (int)ColorWheelMode.Linear, "Linear", EditorStyles.miniButtonLeft)) wheelMode = (int)ColorWheelMode.Linear;
-		        if (GUILayout.Toggle(wheelMode == (int)ColorWheelMode.Log, "Log", EditorStyles.miniButtonRight)) wheelMode = (int)ColorWheelMode.Log;
-	        }
-
-	        m_ColorWheels.mode.intValue = wheelMode;
-	        EditorGUILayout.Space();
-
-	        if (wheelMode == (int)ColorWheelMode.Linear)
-	        {
-		        EditorGUILayout.PropertyField(m_ColorWheels.linear);
-		        WheelSetTitle(GUILayoutUtility.GetLastRect(), "Linear Controls");
-	        }
-			else if (wheelMode == (int)ColorWheelMode.Log)
-			{
-				EditorGUILayout.PropertyField(m_ColorWheels.log);
-				WheelSetTitle(GUILayoutUtility.GetLastRect(), "Log Controls");
-			}
-        }
-
-        static void WheelSetTitle(Rect position, string label)
-        {
-            var matrix = GUI.matrix;
-            var rect = new Rect(position.x - 10f, position.y, TrackballGroupDrawer.m_Size, TrackballGroupDrawer.m_Size);
-            GUIUtility.RotateAroundPivot(-90f, rect.center);
-            GUI.Label(rect, label, FxStyles.centeredMiniLabel);
-            GUI.matrix = matrix;
-        }
-
-        void ResetVisibleCurves()
-        {
-            foreach (var curve in m_CurveDict)
-            {
-                var state = m_CurveEditor.GetCurveState(curve.Key);
-                state.visible = false;
-                m_CurveEditor.SetCurveState(curve.Key, state);
-            }
-        }
-
-        void SetCurveVisible(SerializedProperty prop)
-        {
-            var state = m_CurveEditor.GetCurveState(prop);
-            state.visible = true;
-            m_CurveEditor.SetCurveState(prop, state);
-        }
-
-        bool SpecialToggle(bool value, string name, out bool rightClicked)
-        {
-            var rect = GUILayoutUtility.GetRect(EditorGUIHelper.GetContent(name), EditorStyles.toolbarButton);
-
-            var e = Event.current;
-            rightClicked = (e.type == EventType.MouseUp && rect.Contains(e.mousePosition) && e.button == 1);
-
-            return GUI.Toggle(rect, value, name, EditorStyles.toolbarButton);
-        }
-
-        static Material s_MaterialSpline;
-
-        void DoCurvesGUI()
-        {
-            EditorGUILayout.Space();
-            EditorGUI.indentLevel -= 2;
-            ResetVisibleCurves();
-
-            using (new EditorGUI.DisabledGroupScope(serializedProperty.serializedObject.isEditingMultipleObjects))
-            {
-                int curveEditingId = 0;
-
-                // Top toolbar
-                using (new GUILayout.HorizontalScope(EditorStyles.toolbar))
-                {
-                    curveEditingId = EditorGUILayout.Popup(m_Curves.currentEditingCurve.intValue, s_Curves, EditorStyles.toolbarPopup, GUILayout.MaxWidth(150f));
-                    bool y = false, r = false, g = false, b = false;
-
-                    if (curveEditingId == 0)
-                    {
-                        EditorGUILayout.Space();
-
-                        bool rightClickedY, rightClickedR, rightClickedG, rightClickedB;
-
-                        y = SpecialToggle(m_Curves.curveY.boolValue, "Y", out rightClickedY);
-                        r = SpecialToggle(m_Curves.curveR.boolValue, "R", out rightClickedR);
-                        g = SpecialToggle(m_Curves.curveG.boolValue, "G", out rightClickedG);
-                        b = SpecialToggle(m_Curves.curveB.boolValue, "B", out rightClickedB);
-
-                        if (!y && !r && !g && !b)
-                        {
-                            r = g = b = false;
-                            y = true;
-                        }
-
-                        if (rightClickedY || rightClickedR || rightClickedG || rightClickedB)
-                        {
-                            y = rightClickedY;
-                            r = rightClickedR;
-                            g = rightClickedG;
-                            b = rightClickedB;
-                        }
-
-                        if (y) SetCurveVisible(m_Curves.master);
-                        if (r) SetCurveVisible(m_Curves.red);
-                        if (g) SetCurveVisible(m_Curves.green);
-                        if (b) SetCurveVisible(m_Curves.blue);
-
-                        m_Curves.curveY.boolValue = y;
-                        m_Curves.curveR.boolValue = r;
-                        m_Curves.curveG.boolValue = g;
-                        m_Curves.curveB.boolValue = b;
-                    }
-                    else
-                    {
-                        switch (curveEditingId)
-                        {
-                            case 1: SetCurveVisible(m_Curves.hueVShue);
-                                break;
-                            case 2: SetCurveVisible(m_Curves.hueVSsat);
-                                break;
-                            case 3: SetCurveVisible(m_Curves.satVSsat);
-                                break;
-                            case 4: SetCurveVisible(m_Curves.lumVSsat);
-                                break;
-                        }
-                    }
-
-                    GUILayout.FlexibleSpace();
-
-                    if (GUILayout.Button("Reset", EditorStyles.toolbarButton))
-                    {
-                        switch (curveEditingId)
-                        {
-                            case 0:
-                                if (y) m_Curves.master.animationCurveValue = AnimationCurve.Linear(0f, 0f, 1f, 1f);
-                                if (r) m_Curves.red.animationCurveValue    = AnimationCurve.Linear(0f, 0f, 1f, 1f);
-                                if (g) m_Curves.green.animationCurveValue  = AnimationCurve.Linear(0f, 0f, 1f, 1f);
-                                if (b) m_Curves.blue.animationCurveValue   = AnimationCurve.Linear(0f, 0f, 1f, 1f);
-                                break;
-                            case 1: m_Curves.hueVShue.animationCurveValue = new AnimationCurve();
-                                break;
-                            case 2: m_Curves.hueVSsat.animationCurveValue = new AnimationCurve();
-                                break;
-                            case 3: m_Curves.satVSsat.animationCurveValue = new AnimationCurve();
-                                break;
-                            case 4: m_Curves.lumVSsat.animationCurveValue = new AnimationCurve();
-                                break;
-                        }
-                    }
-
-                    m_Curves.currentEditingCurve.intValue = curveEditingId;
-                }
-
-                // Curve area
-                var settings = m_CurveEditor.settings;
-                var rect = GUILayoutUtility.GetAspectRect(2f);
-                var innerRect = settings.padding.Remove(rect);
-
-                if (Event.current.type == EventType.Repaint)
-                {
-                    // Background
-                    EditorGUI.DrawRect(rect, new Color(0.15f, 0.15f, 0.15f, 1f));
-
-                    if (s_MaterialSpline == null)
-                        s_MaterialSpline = new Material(Shader.Find("Hidden/Post FX/UI/Curve Background")) { hideFlags = HideFlags.HideAndDontSave };
-
-                    if (curveEditingId == 1 || curveEditingId == 2)
-                        DrawBackgroundTexture(innerRect, 0);
-                    else if (curveEditingId == 3 || curveEditingId == 4)
-                        DrawBackgroundTexture(innerRect, 1);
-
-                    // Bounds
-                    Handles.color = Color.white;
-                    Handles.DrawSolidRectangleWithOutline(innerRect, Color.clear, new Color(0.8f, 0.8f, 0.8f, 0.5f));
-
-                    // Grid setup
-                    Handles.color = new Color(1f, 1f, 1f, 0.05f);
-                    int hLines = (int)Mathf.Sqrt(innerRect.width);
-                    int vLines = (int)(hLines / (innerRect.width / innerRect.height));
-
-                    // Vertical grid
-                    int gridOffset = Mathf.FloorToInt(innerRect.width / hLines);
-                    int gridPadding = ((int)(innerRect.width) % hLines) / 2;
-
-                    for (int i = 1; i < hLines; i++)
-                    {
-                        var offset = i * Vector2.right * gridOffset;
-                        offset.x += gridPadding;
-                        Handles.DrawLine(innerRect.position + offset, new Vector2(innerRect.x, innerRect.yMax - 1) + offset);
-                    }
-
-                    // Horizontal grid
-                    gridOffset = Mathf.FloorToInt(innerRect.height / vLines);
-                    gridPadding = ((int)(innerRect.height) % vLines) / 2;
-
-                    for (int i = 1; i < vLines; i++)
-                    {
-                        var offset = i * Vector2.up * gridOffset;
-                        offset.y += gridPadding;
-                        Handles.DrawLine(innerRect.position + offset, new Vector2(innerRect.xMax - 1, innerRect.y) + offset);
-                    }
-                }
-
-                // Curve editor
-                if (m_CurveEditor.OnGUI(rect))
-                {
-                    Repaint();
-                    GUI.changed = true;
-                }
-
-                if (Event.current.type == EventType.Repaint)
-                {
-                    // Borders
-                    Handles.color = Color.black;
-                    Handles.DrawLine(new Vector2(rect.x, rect.y - 18f), new Vector2(rect.xMax, rect.y - 18f));
-                    Handles.DrawLine(new Vector2(rect.x, rect.y - 19f), new Vector2(rect.x, rect.yMax));
-                    Handles.DrawLine(new Vector2(rect.x, rect.yMax), new Vector2(rect.xMax, rect.yMax));
-                    Handles.DrawLine(new Vector2(rect.xMax, rect.yMax), new Vector2(rect.xMax, rect.y - 18f));
-
-                    // Selection info
-                    var selection = m_CurveEditor.GetSelection();
-
-                    if (selection.curve != null && selection.keyframeIndex > -1)
-                    {
-                        var key = selection.keyframe.Value;
-                        var infoRect = innerRect;
-                        infoRect.x += 5f;
-                        infoRect.width = 100f;
-                        infoRect.height = 30f;
-                        GUI.Label(infoRect, string.Format("{0}\n{1}", key.time.ToString("F3"), key.value.ToString("F3")), FxStyles.preLabel);
-                    }
-                }
-            }
-
-            /*
-            EditorGUILayout.HelpBox(
-                @"Curve editor cheat sheet:
-- [Del] or [Backspace] to remove a key
-- [Ctrl] to break a tangent handle
-- [Shift] to align tangent handles
-- [Double click] to create a key on the curve(s) at mouse position
-- [Alt] + [Double click] to create a key on the curve(s) at a given time",
-                MessageType.Info);
-            */
-
-            EditorGUILayout.Space();
-            EditorGUI.indentLevel += 2;
-        }
-
-        void DrawBackgroundTexture(Rect rect, int pass)
-        {
-            float scale = EditorGUIUtility.pixelsPerPoint;
-
-            var oldRt = RenderTexture.active;
-            var rt = RenderTexture.GetTemporary(Mathf.CeilToInt(rect.width * scale), Mathf.CeilToInt(rect.height * scale), 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
-            s_MaterialSpline.SetFloat("_DisabledState", GUI.enabled ? 1f : 0.5f);
-            s_MaterialSpline.SetFloat("_PixelScaling", EditorGUIUtility.pixelsPerPoint);
-
-            Graphics.Blit(null, rt, s_MaterialSpline, pass);
-            RenderTexture.active = oldRt;
-
-            GUI.DrawTexture(rect, rt);
-            RenderTexture.ReleaseTemporary(rt);
-        }
-    }
-}
+using UnityEngine;
+using UnityEngine.PostProcessing;
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+
+namespace UnityEditor.PostProcessing
+{
+    using Settings = ColorGradingModel.Settings;
+    using Tonemapper = ColorGradingModel.Tonemapper;
+	using ColorWheelMode = ColorGradingModel.ColorWheelMode;
+
+    [PostProcessingModelEditor(typeof(ColorGradingModel))]
+    public class ColorGradingModelEditor : PostProcessingModelEditor
+    {
+        static GUIContent[] s_Tonemappers =
+        {
+            new GUIContent("None"),
+            new GUIContent("Filmic (ACES)"),
+            new GUIContent("Neutral")
+        };
+
+        struct TonemappingSettings
+        {
+            public SerializedProperty tonemapper;
+            public SerializedProperty neutralBlackIn;
+            public SerializedProperty neutralWhiteIn;
+            public SerializedProperty neutralBlackOut;
+            public SerializedProperty neutralWhiteOut;
+            public SerializedProperty neutralWhiteLevel;
+            public SerializedProperty neutralWhiteClip;
+        }
+
+        struct BasicSettings
+        {
+            public SerializedProperty exposure;
+            public SerializedProperty temperature;
+            public SerializedProperty tint;
+            public SerializedProperty hueShift;
+            public SerializedProperty saturation;
+            public SerializedProperty contrast;
+        }
+
+        struct ChannelMixerSettings
+        {
+            public SerializedProperty[] channels;
+            public SerializedProperty currentEditingChannel;
+        }
+
+        struct ColorWheelsSettings
+        {
+	        public SerializedProperty mode;
+            public SerializedProperty log;
+            public SerializedProperty linear;
+        }
+
+        static GUIContent[] s_Curves =
+        {
+            new GUIContent("YRGB"),
+            new GUIContent("Hue VS Hue"),
+            new GUIContent("Hue VS Sat"),
+            new GUIContent("Sat VS Sat"),
+            new GUIContent("Lum VS Sat")
+        };
+
+        struct CurvesSettings
+        {
+            public SerializedProperty master;
+            public SerializedProperty red;
+            public SerializedProperty green;
+            public SerializedProperty blue;
+
+            public SerializedProperty hueVShue;
+            public SerializedProperty hueVSsat;
+            public SerializedProperty satVSsat;
+            public SerializedProperty lumVSsat;
+
+            public SerializedProperty currentEditingCurve;
+            public SerializedProperty curveY;
+            public SerializedProperty curveR;
+            public SerializedProperty curveG;
+            public SerializedProperty curveB;
+        }
+
+        TonemappingSettings m_Tonemapping;
+        BasicSettings m_Basic;
+        ChannelMixerSettings m_ChannelMixer;
+        ColorWheelsSettings m_ColorWheels;
+        CurvesSettings m_Curves;
+
+        CurveEditor m_CurveEditor;
+        Dictionary<SerializedProperty, Color> m_CurveDict;
+
+		// Neutral tonemapping curve helper
+        const int k_CurveResolution = 24;
+        const float k_NeutralRangeX = 2f;
+        const float k_NeutralRangeY = 1f;
+        Vector3[] m_RectVertices = new Vector3[4];
+        Vector3[] m_LineVertices = new Vector3[2];
+        Vector3[] m_CurveVertices = new Vector3[k_CurveResolution];
+	    Rect m_NeutralCurveRect;
+
+        public override void OnEnable()
+        {
+            // Tonemapping settings
+            m_Tonemapping = new TonemappingSettings
+            {
+                tonemapper = FindSetting((Settings x) => x.tonemapping.tonemapper),
+                neutralBlackIn = FindSetting((Settings x) => x.tonemapping.neutralBlackIn),
+                neutralWhiteIn = FindSetting((Settings x) => x.tonemapping.neutralWhiteIn),
+                neutralBlackOut = FindSetting((Settings x) => x.tonemapping.neutralBlackOut),
+                neutralWhiteOut = FindSetting((Settings x) => x.tonemapping.neutralWhiteOut),
+                neutralWhiteLevel = FindSetting((Settings x) => x.tonemapping.neutralWhiteLevel),
+                neutralWhiteClip = FindSetting((Settings x) => x.tonemapping.neutralWhiteClip)
+            };
+
+            // Basic settings
+            m_Basic = new BasicSettings
+            {
+                exposure = FindSetting((Settings x) => x.basic.postExposure),
+                temperature = FindSetting((Settings x) => x.basic.temperature),
+                tint = FindSetting((Settings x) => x.basic.tint),
+                hueShift = FindSetting((Settings x) => x.basic.hueShift),
+                saturation = FindSetting((Settings x) => x.basic.saturation),
+                contrast = FindSetting((Settings x) => x.basic.contrast)
+            };
+
+            // Channel mixer
+            m_ChannelMixer = new ChannelMixerSettings
+            {
+                channels = new[]
+                {
+                    FindSetting((Settings x) => x.channelMixer.red),
+                    FindSetting((Settings x) => x.channelMixer.green),
+                    FindSetting((Settings x) => x.channelMixer.blue)
+                },
+                currentEditingChannel = FindSetting((Settings x) => x.channelMixer.currentEditingChannel)
+            };
+
+            // Color wheels
+            m_ColorWheels = new ColorWheelsSettings
+            {
+				mode = FindSetting((Settings x) => x.colorWheels.mode),
+                log = FindSetting((Settings x) => x.colorWheels.log),
+                linear = FindSetting((Settings x) => x.colorWheels.linear)
+            };
+
+            // Curves
+            m_Curves = new CurvesSettings
+            {
+                master = FindSetting((Settings x) => x.curves.master.curve),
+                red = FindSetting((Settings x) => x.curves.red.curve),
+                green = FindSetting((Settings x) => x.curves.green.curve),
+                blue = FindSetting((Settings x) => x.curves.blue.curve),
+
+                hueVShue = FindSetting((Settings x) => x.curves.hueVShue.curve),
+                hueVSsat = FindSetting((Settings x) => x.curves.hueVSsat.curve),
+                satVSsat = FindSetting((Settings x) => x.curves.satVSsat.curve),
+                lumVSsat = FindSetting((Settings x) => x.curves.lumVSsat.curve),
+
+                currentEditingCurve = FindSetting((Settings x) => x.curves.e_CurrentEditingCurve),
+                curveY = FindSetting((Settings x) => x.curves.e_CurveY),
+                curveR = FindSetting((Settings x) => x.curves.e_CurveR),
+                curveG = FindSetting((Settings x) => x.curves.e_CurveG),
+                curveB = FindSetting((Settings x) => x.curves.e_CurveB)
+            };
+
+            // Prepare the curve editor and extract curve display settings
+            m_CurveDict = new Dictionary<SerializedProperty, Color>();
+
+            var settings = CurveEditor.Settings.defaultSettings;
+
+            m_CurveEditor = new CurveEditor(settings);
+            AddCurve(m_Curves.master,   new Color(1f, 1f, 1f), 2, false);
+            AddCurve(m_Curves.red,      new Color(1f, 0f, 0f), 2, false);
+            AddCurve(m_Curves.green,    new Color(0f, 1f, 0f), 2, false);
+            AddCurve(m_Curves.blue,     new Color(0f, 0.5f, 1f), 2, false);
+            AddCurve(m_Curves.hueVShue, new Color(1f, 1f, 1f), 0, true);
+            AddCurve(m_Curves.hueVSsat, new Color(1f, 1f, 1f), 0, true);
+            AddCurve(m_Curves.satVSsat, new Color(1f, 1f, 1f), 0, false);
+            AddCurve(m_Curves.lumVSsat, new Color(1f, 1f, 1f), 0, false);
+        }
+
+        void AddCurve(SerializedProperty prop, Color color, uint minPointCount, bool loop)
+        {
+            var state = CurveEditor.CurveState.defaultState;
+            state.color = color;
+            state.visible = false;
+            state.minPointCount = minPointCount;
+            state.onlyShowHandlesOnSelection = true;
+            state.zeroKeyConstantValue = 0.5f;
+            state.loopInBounds = loop;
+            m_CurveEditor.Add(prop, state);
+            m_CurveDict.Add(prop, color);
+        }
+
+        public override void OnDisable()
+        {
+            m_CurveEditor.RemoveAll();
+        }
+
+        public override void OnInspectorGUI()
+        {
+            DoGUIFor("Tonemapping", DoTonemappingGUI);
+            EditorGUILayout.Space();
+            DoGUIFor("Basic", DoBasicGUI);
+            EditorGUILayout.Space();
+            DoGUIFor("Channel Mixer", DoChannelMixerGUI);
+            EditorGUILayout.Space();
+            DoGUIFor("Trackballs", DoColorWheelsGUI);
+            EditorGUILayout.Space();
+            DoGUIFor("Grading Curves", DoCurvesGUI);
+        }
+
+        void DoGUIFor(string title, Action func)
+        {
+            EditorGUILayout.LabelField(title, EditorStyles.boldLabel);
+            EditorGUI.indentLevel++;
+            func();
+            EditorGUI.indentLevel--;
+        }
+
+        void DoTonemappingGUI()
+        {
+            int tid = EditorGUILayout.Popup(EditorGUIHelper.GetContent("Tonemapper"), m_Tonemapping.tonemapper.intValue, s_Tonemappers);
+
+            if (tid == (int)Tonemapper.Neutral)
+            {
+	            DrawNeutralTonemappingCurve();
+
+                EditorGUILayout.PropertyField(m_Tonemapping.neutralBlackIn, EditorGUIHelper.GetContent("Black In"));
+                EditorGUILayout.PropertyField(m_Tonemapping.neutralWhiteIn, EditorGUIHelper.GetContent("White In"));
+                EditorGUILayout.PropertyField(m_Tonemapping.neutralBlackOut, EditorGUIHelper.GetContent("Black Out"));
+                EditorGUILayout.PropertyField(m_Tonemapping.neutralWhiteOut, EditorGUIHelper.GetContent("White Out"));
+                EditorGUILayout.PropertyField(m_Tonemapping.neutralWhiteLevel, EditorGUIHelper.GetContent("White Level"));
+                EditorGUILayout.PropertyField(m_Tonemapping.neutralWhiteClip, EditorGUIHelper.GetContent("White Clip"));
+            }
+
+            m_Tonemapping.tonemapper.intValue = tid;
+        }
+
+	    void DrawNeutralTonemappingCurve()
+	    {
+            using (new GUILayout.HorizontalScope())
+            {
+                GUILayout.Space(EditorGUI.indentLevel * 15f);
+                m_NeutralCurveRect = GUILayoutUtility.GetRect(128, 80);
+            }
+
+			// Background
+			m_RectVertices[0] = PointInRect(             0f,              0f);
+            m_RectVertices[1] = PointInRect(k_NeutralRangeX,              0f);
+            m_RectVertices[2] = PointInRect(k_NeutralRangeX, k_NeutralRangeY);
+            m_RectVertices[3] = PointInRect(             0f, k_NeutralRangeY);
+
+            Handles.DrawSolidRectangleWithOutline(
+                m_RectVertices,
+                Color.white * 0.1f,
+                Color.white * 0.4f
+                );
+
+            // Horizontal lines
+            for (var i = 1; i < k_NeutralRangeY; i++)
+                DrawLine(0, i, k_NeutralRangeX, i, 0.4f);
+
+            // Vertical lines
+            for (var i = 1; i < k_NeutralRangeX; i++)
+                DrawLine(i, 0, i, k_NeutralRangeY, 0.4f);
+
+			// Label
+            Handles.Label(
+                PointInRect(0, k_NeutralRangeY) + Vector3.right,
+                "Neutral Tonemapper", EditorStyles.miniLabel
+                );
+
+			// Precompute some values
+            var tonemap = ((ColorGradingModel)target).settings.tonemapping;
+
+		    const float scaleFactor = 20f;
+            const float scaleFactorHalf = scaleFactor * 0.5f;
+
+            float inBlack = tonemap.neutralBlackIn * scaleFactor + 1f;
+            float outBlack = tonemap.neutralBlackOut * scaleFactorHalf + 1f;
+            float inWhite = tonemap.neutralWhiteIn / scaleFactor;
+            float outWhite = 1f - tonemap.neutralWhiteOut / scaleFactor;
+            float blackRatio = inBlack / outBlack;
+            float whiteRatio = inWhite / outWhite;
+
+            const float a = 0.2f;
+            float b = Mathf.Max(0f, Mathf.LerpUnclamped(0.57f, 0.37f, blackRatio));
+            float c = Mathf.LerpUnclamped(0.01f, 0.24f, whiteRatio);
+            float d = Mathf.Max(0f, Mathf.LerpUnclamped(0.02f, 0.20f, blackRatio));
+            const float e = 0.02f;
+            const float f = 0.30f;
+		    float whiteLevel = tonemap.neutralWhiteLevel;
+		    float whiteClip = tonemap.neutralWhiteClip / scaleFactorHalf;
+
+			// Tonemapping curve
+            var vcount = 0;
+            while (vcount < k_CurveResolution)
+            {
+                float x = k_NeutralRangeX * vcount / (k_CurveResolution - 1);
+                float y = NeutralTonemap(x, a, b, c, d, e, f, whiteLevel, whiteClip);
+
+                if (y < k_NeutralRangeY)
+                {
+                    m_CurveVertices[vcount++] = PointInRect(x, y);
+                }
+                else
+                {
+                    if (vcount > 1)
+                    {
+                        // Extend the last segment to the top edge of the rect.
+                        var v1 = m_CurveVertices[vcount - 2];
+                        var v2 = m_CurveVertices[vcount - 1];
+                        var clip = (m_NeutralCurveRect.y - v1.y) / (v2.y - v1.y);
+                        m_CurveVertices[vcount - 1] = v1 + (v2 - v1) * clip;
+                    }
+                    break;
+                }
+            }
+
+            if (vcount > 1)
+            {
+                Handles.color = Color.white * 0.9f;
+                Handles.DrawAAPolyLine(2.0f, vcount, m_CurveVertices);
+            }
+	    }
+
+		void DrawLine(float x1, float y1, float x2, float y2, float grayscale)
+        {
+            m_LineVertices[0] = PointInRect(x1, y1);
+            m_LineVertices[1] = PointInRect(x2, y2);
+            Handles.color = Color.white * grayscale;
+            Handles.DrawAAPolyLine(2f, m_LineVertices);
+        }
+
+		Vector3 PointInRect(float x, float y)
+        {
+            x = Mathf.Lerp(m_NeutralCurveRect.x, m_NeutralCurveRect.xMax, x / k_NeutralRangeX);
+            y = Mathf.Lerp(m_NeutralCurveRect.yMax, m_NeutralCurveRect.y, y / k_NeutralRangeY);
+            return new Vector3(x, y, 0);
+        }
+
+		float NeutralCurve(float x, float a, float b, float c, float d, float e, float f)
+		{
+			return ((x * (a * x + c * b) + d * e) / (x * (a * x + b) + d * f)) - e / f;
+		}
+
+	    float NeutralTonemap(float x, float a, float b, float c, float d, float e, float f, float whiteLevel, float whiteClip)
+	    {
+			x = Mathf.Max(0f, x);
+
+			// Tonemap
+			float whiteScale = 1f / NeutralCurve(whiteLevel, a, b, c, d, e, f);
+			x = NeutralCurve(x * whiteScale, a, b, c, d, e, f);
+			x *= whiteScale;
+
+			// Post-curve white point adjustment
+			x /= whiteClip;
+
+			return x;
+	    }
+
+        void DoBasicGUI()
+        {
+            EditorGUILayout.PropertyField(m_Basic.exposure, EditorGUIHelper.GetContent("Post Exposure (EV)"));
+            EditorGUILayout.PropertyField(m_Basic.temperature);
+            EditorGUILayout.PropertyField(m_Basic.tint);
+            EditorGUILayout.PropertyField(m_Basic.hueShift);
+            EditorGUILayout.PropertyField(m_Basic.saturation);
+            EditorGUILayout.PropertyField(m_Basic.contrast);
+        }
+
+        void DoChannelMixerGUI()
+        {
+            int currentChannel = m_ChannelMixer.currentEditingChannel.intValue;
+
+            EditorGUI.BeginChangeCheck();
+            {
+                using (new EditorGUILayout.HorizontalScope())
+                {
+                    EditorGUILayout.PrefixLabel("Channel");
+                    if (GUILayout.Toggle(currentChannel == 0, EditorGUIHelper.GetContent("Red|Red output channel."), EditorStyles.miniButtonLeft)) currentChannel = 0;
+                    if (GUILayout.Toggle(currentChannel == 1, EditorGUIHelper.GetContent("Green|Green output channel."), EditorStyles.miniButtonMid)) currentChannel = 1;
+                    if (GUILayout.Toggle(currentChannel == 2, EditorGUIHelper.GetContent("Blue|Blue output channel."), EditorStyles.miniButtonRight)) currentChannel = 2;
+                }
+            }
+            if (EditorGUI.EndChangeCheck())
+            {
+                GUI.FocusControl(null);
+            }
+
+            var serializedChannel = m_ChannelMixer.channels[currentChannel];
+            m_ChannelMixer.currentEditingChannel.intValue = currentChannel;
+
+            var v = serializedChannel.vector3Value;
+            v.x = EditorGUILayout.Slider(EditorGUIHelper.GetContent("Red|Modify influence of the red channel within the overall mix."), v.x, -2f, 2f);
+            v.y = EditorGUILayout.Slider(EditorGUIHelper.GetContent("Green|Modify influence of the green channel within the overall mix."), v.y, -2f, 2f);
+            v.z = EditorGUILayout.Slider(EditorGUIHelper.GetContent("Blue|Modify influence of the blue channel within the overall mix."), v.z, -2f, 2f);
+            serializedChannel.vector3Value = v;
+        }
+
+        void DoColorWheelsGUI()
+        {
+	        int wheelMode = m_ColorWheels.mode.intValue;
+
+	        using (new EditorGUILayout.HorizontalScope())
+	        {
+		        GUILayout.Space(15);
+		        if (GUILayout.Toggle(wheelMode == (int)ColorWheelMode.Linear, "Linear", EditorStyles.miniButtonLeft)) wheelMode = (int)ColorWheelMode.Linear;
+		        if (GUILayout.Toggle(wheelMode == (int)ColorWheelMode.Log, "Log", EditorStyles.miniButtonRight)) wheelMode = (int)ColorWheelMode.Log;
+	        }
+
+	        m_ColorWheels.mode.intValue = wheelMode;
+	        EditorGUILayout.Space();
+
+	        if (wheelMode == (int)ColorWheelMode.Linear)
+	        {
+		        EditorGUILayout.PropertyField(m_ColorWheels.linear);
+		        WheelSetTitle(GUILayoutUtility.GetLastRect(), "Linear Controls");
+	        }
+			else if (wheelMode == (int)ColorWheelMode.Log)
+			{
+				EditorGUILayout.PropertyField(m_ColorWheels.log);
+				WheelSetTitle(GUILayoutUtility.GetLastRect(), "Log Controls");
+			}
+        }
+
+        static void WheelSetTitle(Rect position, string label)
+        {
+            var matrix = GUI.matrix;
+            var rect = new Rect(position.x - 10f, position.y, TrackballGroupDrawer.m_Size, TrackballGroupDrawer.m_Size);
+            GUIUtility.RotateAroundPivot(-90f, rect.center);
+            GUI.Label(rect, label, FxStyles.centeredMiniLabel);
+            GUI.matrix = matrix;
+        }
+
+        void ResetVisibleCurves()
+        {
+            foreach (var curve in m_CurveDict)
+            {
+                var state = m_CurveEditor.GetCurveState(curve.Key);
+                state.visible = false;
+                m_CurveEditor.SetCurveState(curve.Key, state);
+            }
+        }
+
+        void SetCurveVisible(SerializedProperty prop)
+        {
+            var state = m_CurveEditor.GetCurveState(prop);
+            state.visible = true;
+            m_CurveEditor.SetCurveState(prop, state);
+        }
+
+        bool SpecialToggle(bool value, string name, out bool rightClicked)
+        {
+            var rect = GUILayoutUtility.GetRect(EditorGUIHelper.GetContent(name), EditorStyles.toolbarButton);
+
+            var e = Event.current;
+            rightClicked = (e.type == EventType.MouseUp && rect.Contains(e.mousePosition) && e.button == 1);
+
+            return GUI.Toggle(rect, value, name, EditorStyles.toolbarButton);
+        }
+
+        static Material s_MaterialSpline;
+
+        void DoCurvesGUI()
+        {
+            EditorGUILayout.Space();
+            EditorGUI.indentLevel -= 2;
+            ResetVisibleCurves();
+
+            using (new EditorGUI.DisabledGroupScope(serializedProperty.serializedObject.isEditingMultipleObjects))
+            {
+                int curveEditingId = 0;
+
+                // Top toolbar
+                using (new GUILayout.HorizontalScope(EditorStyles.toolbar))
+                {
+                    curveEditingId = EditorGUILayout.Popup(m_Curves.currentEditingCurve.intValue, s_Curves, EditorStyles.toolbarPopup, GUILayout.MaxWidth(150f));
+                    bool y = false, r = false, g = false, b = false;
+
+                    if (curveEditingId == 0)
+                    {
+                        EditorGUILayout.Space();
+
+                        bool rightClickedY, rightClickedR, rightClickedG, rightClickedB;
+
+                        y = SpecialToggle(m_Curves.curveY.boolValue, "Y", out rightClickedY);
+                        r = SpecialToggle(m_Curves.curveR.boolValue, "R", out rightClickedR);
+                        g = SpecialToggle(m_Curves.curveG.boolValue, "G", out rightClickedG);
+                        b = SpecialToggle(m_Curves.curveB.boolValue, "B", out rightClickedB);
+
+                        if (!y && !r && !g && !b)
+                        {
+                            r = g = b = false;
+                            y = true;
+                        }
+
+                        if (rightClickedY || rightClickedR || rightClickedG || rightClickedB)
+                        {
+                            y = rightClickedY;
+                            r = rightClickedR;
+                            g = rightClickedG;
+                            b = rightClickedB;
+                        }
+
+                        if (y) SetCurveVisible(m_Curves.master);
+                        if (r) SetCurveVisible(m_Curves.red);
+                        if (g) SetCurveVisible(m_Curves.green);
+                        if (b) SetCurveVisible(m_Curves.blue);
+
+                        m_Curves.curveY.boolValue = y;
+                        m_Curves.curveR.boolValue = r;
+                        m_Curves.curveG.boolValue = g;
+                        m_Curves.curveB.boolValue = b;
+                    }
+                    else
+                    {
+                        switch (curveEditingId)
+                        {
+                            case 1: SetCurveVisible(m_Curves.hueVShue);
+                                break;
+                            case 2: SetCurveVisible(m_Curves.hueVSsat);
+                                break;
+                            case 3: SetCurveVisible(m_Curves.satVSsat);
+                                break;
+                            case 4: SetCurveVisible(m_Curves.lumVSsat);
+                                break;
+                        }
+                    }
+
+                    GUILayout.FlexibleSpace();
+
+                    if (GUILayout.Button("Reset", EditorStyles.toolbarButton))
+                    {
+                        switch (curveEditingId)
+                        {
+                            case 0:
+                                if (y) m_Curves.master.animationCurveValue = AnimationCurve.Linear(0f, 0f, 1f, 1f);
+                                if (r) m_Curves.red.animationCurveValue    = AnimationCurve.Linear(0f, 0f, 1f, 1f);
+                                if (g) m_Curves.green.animationCurveValue  = AnimationCurve.Linear(0f, 0f, 1f, 1f);
+                                if (b) m_Curves.blue.animationCurveValue   = AnimationCurve.Linear(0f, 0f, 1f, 1f);
+                                break;
+                            case 1: m_Curves.hueVShue.animationCurveValue = new AnimationCurve();
+                                break;
+                            case 2: m_Curves.hueVSsat.animationCurveValue = new AnimationCurve();
+                                break;
+                            case 3: m_Curves.satVSsat.animationCurveValue = new AnimationCurve();
+                                break;
+                            case 4: m_Curves.lumVSsat.animationCurveValue = new AnimationCurve();
+                                break;
+                        }
+                    }
+
+                    m_Curves.currentEditingCurve.intValue = curveEditingId;
+                }
+
+                // Curve area
+                var settings = m_CurveEditor.settings;
+                var rect = GUILayoutUtility.GetAspectRect(2f);
+                var innerRect = settings.padding.Remove(rect);
+
+                if (Event.current.type == EventType.Repaint)
+                {
+                    // Background
+                    EditorGUI.DrawRect(rect, new Color(0.15f, 0.15f, 0.15f, 1f));
+
+                    if (s_MaterialSpline == null)
+                        s_MaterialSpline = new Material(Shader.Find("Hidden/Post FX/UI/Curve Background")) { hideFlags = HideFlags.HideAndDontSave };
+
+                    if (curveEditingId == 1 || curveEditingId == 2)
+                        DrawBackgroundTexture(innerRect, 0);
+                    else if (curveEditingId == 3 || curveEditingId == 4)
+                        DrawBackgroundTexture(innerRect, 1);
+
+                    // Bounds
+                    Handles.color = Color.white;
+                    Handles.DrawSolidRectangleWithOutline(innerRect, Color.clear, new Color(0.8f, 0.8f, 0.8f, 0.5f));
+
+                    // Grid setup
+                    Handles.color = new Color(1f, 1f, 1f, 0.05f);
+                    int hLines = (int)Mathf.Sqrt(innerRect.width);
+                    int vLines = (int)(hLines / (innerRect.width / innerRect.height));
+
+                    // Vertical grid
+                    int gridOffset = Mathf.FloorToInt(innerRect.width / hLines);
+                    int gridPadding = ((int)(innerRect.width) % hLines) / 2;
+
+                    for (int i = 1; i < hLines; i++)
+                    {
+                        var offset = i * Vector2.right * gridOffset;
+                        offset.x += gridPadding;
+                        Handles.DrawLine(innerRect.position + offset, new Vector2(innerRect.x, innerRect.yMax - 1) + offset);
+                    }
+
+                    // Horizontal grid
+                    gridOffset = Mathf.FloorToInt(innerRect.height / vLines);
+                    gridPadding = ((int)(innerRect.height) % vLines) / 2;
+
+                    for (int i = 1; i < vLines; i++)
+                    {
+                        var offset = i * Vector2.up * gridOffset;
+                        offset.y += gridPadding;
+                        Handles.DrawLine(innerRect.position + offset, new Vector2(innerRect.xMax - 1, innerRect.y) + offset);
+                    }
+                }
+
+                // Curve editor
+                if (m_CurveEditor.OnGUI(rect))
+                {
+                    Repaint();
+                    GUI.changed = true;
+                }
+
+                if (Event.current.type == EventType.Repaint)
+                {
+                    // Borders
+                    Handles.color = Color.black;
+                    Handles.DrawLine(new Vector2(rect.x, rect.y - 18f), new Vector2(rect.xMax, rect.y - 18f));
+                    Handles.DrawLine(new Vector2(rect.x, rect.y - 19f), new Vector2(rect.x, rect.yMax));
+                    Handles.DrawLine(new Vector2(rect.x, rect.yMax), new Vector2(rect.xMax, rect.yMax));
+                    Handles.DrawLine(new Vector2(rect.xMax, rect.yMax), new Vector2(rect.xMax, rect.y - 18f));
+
+                    // Selection info
+                    var selection = m_CurveEditor.GetSelection();
+
+                    if (selection.curve != null && selection.keyframeIndex > -1)
+                    {
+                        var key = selection.keyframe.Value;
+                        var infoRect = innerRect;
+                        infoRect.x += 5f;
+                        infoRect.width = 100f;
+                        infoRect.height = 30f;
+                        GUI.Label(infoRect, string.Format("{0}\n{1}", key.time.ToString("F3"), key.value.ToString("F3")), FxStyles.preLabel);
+                    }
+                }
+            }
+
+            /*
+            EditorGUILayout.HelpBox(
+                @"Curve editor cheat sheet:
+- [Del] or [Backspace] to remove a key
+- [Ctrl] to break a tangent handle
+- [Shift] to align tangent handles
+- [Double click] to create a key on the curve(s) at mouse position
+- [Alt] + [Double click] to create a key on the curve(s) at a given time",
+                MessageType.Info);
+            */
+
+            EditorGUILayout.Space();
+            EditorGUI.indentLevel += 2;
+        }
+
+        void DrawBackgroundTexture(Rect rect, int pass)
+        {
+            float scale = EditorGUIUtility.pixelsPerPoint;
+
+            var oldRt = RenderTexture.active;
+            var rt = RenderTexture.GetTemporary(Mathf.CeilToInt(rect.width * scale), Mathf.CeilToInt(rect.height * scale), 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
+            s_MaterialSpline.SetFloat("_DisabledState", GUI.enabled ? 1f : 0.5f);
+            s_MaterialSpline.SetFloat("_PixelScaling", EditorGUIUtility.pixelsPerPoint);
+
+            Graphics.Blit(null, rt, s_MaterialSpline, pass);
+            RenderTexture.active = oldRt;
+
+            GUI.DrawTexture(rect, rt);
+            RenderTexture.ReleaseTemporary(rt);
+        }
+    }
+}

--
Gitblit v1.8.0