/// The inverse of ColorToRawValue. /// Returns true on success, false on failure. /// (e.g. not out of circle bounds on HSL picker) /// Prefer this over using RawValueToHSLColor, as this will work properly with HDR public static bool RawValueToColor(ColorPickerMode mode, Vector3 raw, out Color color) { switch (mode) { case ColorPickerMode.SV_H_Rect: case ColorPickerMode.HS_L_Polar: case ColorPickerMode.SL_H_Triangle: case ColorPickerMode.HL_S_Polar: { HSLColor hsl; bool ret = RawValueToHSLColor(mode, raw, out hsl); color = (Color)hsl; return(ret); } case ColorPickerMode.HS_LogV_Polar: { float hue01, saturation, value; bool ok = RawValueToHSV(mode, raw, out hue01, out saturation, out value); color = Color.HSVToRGB(hue01, saturation, value, hdr: true); return(ok); } default: Debug.Assert(false); color = Color.black; return(false); } }
protected void TriggerCurrentColorSet(ColorPickerMode mode, Vector3 rawColor) { if (CurrentColorSet != null) { CurrentColorSet(mode, rawColor); } }
public void Toogle_Alpha(ColorPickerMode mode) { var color = new MudColor(12, 220, 124, 120); var expectedColor = new MudColor(12, 220, 124, 120); var comp = ctx.RenderComponent <SimpleColorPickerTest>(p => { p.Add(x => x.ColorPickerMode, mode); p.Add(x => x.DisableAlpha, false); p.Add(x => x.ColorValue, color); }); Console.WriteLine(comp.Markup); _ = comp.Find(_alphaInputCssSelector); comp.SetParametersAndRender(p => p.Add(x => x.DisableAlpha, true)); Assert.Throws <ElementNotFoundException>(() => comp.Find(_alphaInputCssSelector)); comp.Instance.ColorValue.Should().Be(expectedColor); comp.Instance.TextValue.Should().Be(expectedColor.ToString(MudColorOutputFormats.Hex)); comp.SetParametersAndRender(p => p.Add(x => x.DisableAlpha, false)); _ = comp.Find(_alphaInputCssSelector); comp.Instance.ColorValue.Should().Be(expectedColor); comp.Instance.TextValue.Should().Be(expectedColor.ToString(MudColorOutputFormats.HexA)); }
public static bool ModeIsValid(ColorPickerMode mode) { ColorPickerInfo info = GetInfoForMode(mode); if (info == null) { return(false); } if (info.hdr) { return(false); } #if (UNITY_EDITOR || EXPERIMENTAL_ENABLED) if (Config.IsExperimental) { return(true); } #endif if (info.experimental) { return(false); } return(true); }
public void RefreshOptions() { var pickers = App.Instance.GetComponent <CustomColorPaletteStorage>(); List <Option> options = new List <Option>(); foreach (var modeAndInfo in pickers.ModeToPickerInfo) { if (ColorPickerUtils.ModeIsValid(modeAndInfo.mode)) { options.Add(new Option { m_Description = modeAndInfo.mode.ToString(), m_Texture = modeAndInfo.info.icon }); } } m_Options = options.ToArray(); if (m_Options.Length < 2) { gameObject.SetActive(false); } else { CreateOptionSides(); ColorPickerMode initialMode = CustomColorPaletteStorage.m_Instance.Mode; if (ColorPickerUtils.ModeIsValid(initialMode)) { ForceSelectedOption((int)initialMode); } else { ColorPickerUtils.GoToNextMode(); } } }
public static WriteableBitmap Get(ColorPickerMode colorMode, double columnY, int cubeWidth) { _cores = Environment.ProcessorCount; switch (colorMode) { case ColorPickerMode.H: return(CubeH(cubeWidth, columnY)); case ColorPickerMode.S: return(CubeS(cubeWidth, columnY)); case ColorPickerMode.V: return(CubeV(cubeWidth, columnY)); case ColorPickerMode.R: return(CubeR(cubeWidth, columnY)); case ColorPickerMode.G: return(CubeG(cubeWidth, columnY)); case ColorPickerMode.B: return(CubeB(cubeWidth, columnY)); default: throw new ArgumentOutOfRangeException(nameof(colorMode), colorMode, null); } }
void OnModeChanged() { ColorPickerMode mode = ColorPickerUtils.GetActiveMode(m_ColorController.IsHdr); ColorPickerInfo info = ColorPickerUtils.GetInfoForMode(mode); if (m_ColorPickerSelectorBorderCube != null && m_ColorPickerSelectorBorderCylinder != null) { m_ColorPickerSelectorBorderCube.enabled = false; m_ColorPickerSelectorBorderCylinder.enabled = false; if (info.cylindrical) { m_ColorPickerSelectorBorderCylinder.enabled = true; } else { m_ColorPickerSelectorBorderCube.enabled = true; } } if (m_CircleBack != null) { m_CircleBack.SetActive(info.cylindrical); } m_ColorPickerSelector.SetLocalMode(mode); m_ColorPickerSlider.SetLocalMode(mode); m_ColorController.CurrentColor = m_ColorController.CurrentColor; }
public static WriteableBitmap Get(Point cubeXy, ColorPickerMode colorMode, int columnWidth, int columnHeight) { _cores = Environment.ProcessorCount; switch (colorMode) { case ColorPickerMode.H: return(GetColumnH(columnWidth, columnHeight)); case ColorPickerMode.S: return(GetColumnS(columnWidth, columnHeight, cubeXy)); case ColorPickerMode.V: return(GetColumnV(columnWidth, columnHeight, cubeXy)); case ColorPickerMode.R: return(GetColumnR(columnWidth, columnHeight, cubeXy)); case ColorPickerMode.G: return(GetColumnG(columnWidth, columnHeight, cubeXy)); case ColorPickerMode.B: return(GetColumnB(columnWidth, columnHeight, cubeXy)); default: throw new ArgumentOutOfRangeException(nameof(colorMode), colorMode, null); } }
void Start() { if (PlayerPrefs.HasKey("ColorMode")) { int mode = PlayerPrefs.GetInt("ColorMode"); if (mode < (int)ColorPickerMode.NUM_MODES) { Mode = (ColorPickerMode)mode; } } }
private void Single_ColorPickerRoundTripFromColor(ColorPickerMode mode, Color rgb) { Vector3 raw = ColorPickerUtils.ColorToRawValue(mode, rgb); Color rgb2; bool ok = ColorPickerUtils.RawValueToColor(mode, raw, out rgb2); Assert.IsTrue(ok, "Mode {0}: {1} -> {2} -> fail", mode, Repr(rgb), raw); // RawValueToColor should always return colors with a=1 Assert.AreEqual(1, rgb2.a, "RawValueToColor alpha"); rgb.a = 1; // Don't check incoming alpha AssertNearlyEqualRGB(rgb, rgb2); }
// Apply brush and geometric constraints to value.x and value.y. // Examples of brush constraint: lum >= epsilon // Examples of geometric constraint: radius <= 1 public static Vector3 ApplyPlanarConstraint(Vector3 value, ColorPickerMode mode, float luminanceMin, float saturationMax) { switch (mode) { case ColorPickerMode.SV_H_Rect: // TODO: simplify luminance clamping. Instead of clamping in UI space, we can // get HSL color from prospective selection, clamp, then update UI to match. // Given HSL and HSV color spaces: L = (2 - S) * V / 2 // (See http://ariya.blogspot.com/2008/07/converting-between-hsl-and-hsv.html) // To clamp exactly to our minimum luminance value we'd need to solve for closest // point on a curve to user's selected position. The function is mostly linear // in our given range for small L, so we could approximate by closest point to a // line. Even simpler, since the slope is mostly parallel to S axis, we take S // as is and solve for V. value.x = Mathf.Min(saturationMax, value.x); float s = value.x; // float v = value.y float vMin = 2 * luminanceMin / (2 - s); value.y = Mathf.Clamp(value.y, vMin, 1); break; case ColorPickerMode.SL_H_Triangle: value.y = Mathf.Clamp(value.y, luminanceMin, 1); // If we end up shipping this picker, should change this to closest-point-in-triangle float maxX = SQRT3 * ((value.y < .5f) ? value.y : (1 - value.y)); maxX *= saturationMax; value.x = Mathf.Clamp(value.x, 0, maxX); break; case ColorPickerMode.HS_LogV_Polar: case ColorPickerMode.HS_L_Polar: case ColorPickerMode.HL_S_Polar: { float maxRadius = (mode == ColorPickerMode.HL_S_Polar) ? 1 - luminanceMin : (mode == ColorPickerMode.HS_L_Polar) ? saturationMax : 1; Vector2 offset = new Vector2(0.5f, 0.5f); Vector2 flat = (((Vector2)value) - offset) * 2; float radius = flat.magnitude; if (radius > maxRadius) { flat *= (maxRadius / radius); // Assign back flat = flat / 2 + offset; value.x = flat.x; value.y = flat.y; } break; } } return(value); }
public void TestColorPickerRoundTripFromColor( [Values(ColorPickerMode.HS_L_Polar, ColorPickerMode.SV_H_Rect, ColorPickerMode.SL_H_Triangle, ColorPickerMode.HL_S_Polar)] ColorPickerMode mode) { foreach (HSLColor hsl in HslTestCases(30)) { Single_ColorPickerRoundTripFromColor(mode, (Color)hsl); } }
public static ColorPickerInfo GetInfoForMode(ColorPickerMode mode) { // N is small, so I don't feel bad about this for (int i = 0; i < ModeToPickerInfo.Length; ++i) { if (ModeToPickerInfo[i].mode == mode) { return(ModeToPickerInfo[i].info); } } return(null); }
public void TestColorPickerRoundTripFromValue( [Values(ColorPickerMode.HS_L_Polar, ColorPickerMode.SV_H_Rect, ColorPickerMode.SL_H_Triangle, ColorPickerMode.HL_S_Polar)] ColorPickerMode mode) { foreach (var pos in ColorPickerPositions()) { Single_ColorPickerRoundTripFromRawValue(mode, pos); } }
private void ActRadio(string name, object state) { if (!(bool)state) { return; } _colorMode = _elementModes[name]; ColorPickerCoordinatesModel.Get(ColorNew.Color, _colorMode, out _cubeXy, out _columnY); SetIndicators(); ColorCube = ColorPickerCubeModel.Get(_colorMode, _columnY, (int)_canvasCube.ActualWidth); ColorColumn = ColorPickerColumnModel.Get(_cubeXy, _colorMode, (int)_canvasColumn.ActualWidth, (int)_canvasColumn.ActualHeight); SetText(ColorNew.Color); }
private void Single_ColorPickerRoundTripFromRawValue(ColorPickerMode mode, Vector3 raw) { Color rgb; bool ok = ColorPickerUtils.RawValueToColor(mode, raw, out rgb); if (!ok) { return; } Vector3 raw2 = ColorPickerUtils.ColorToRawValue(mode, rgb); Vector3 diff = raw2 - raw; float EPSILON = 1e-4f; if (Mathf.Abs(diff.x) > EPSILON || Mathf.Abs(diff.y) > EPSILON || Mathf.Abs(diff.z) > EPSILON) { Assert.Fail("Mode {0} sent {1} -> {2}", mode, raw, raw2); } }
private static void Count(ColorPickerMode colorMode, double h, double s, double v, double r, double g, double b, out Point cubeXy, out double columnY) { cubeXy = new Point(); switch (colorMode) { case ColorPickerMode.H: cubeXy.X = s; cubeXy.Y = 1.0 - v; columnY = 1.0 - h / 360.0; return; case ColorPickerMode.S: cubeXy.X = h / 360.0; cubeXy.Y = 1.0 - v; columnY = 1.0 - s; return; case ColorPickerMode.V: cubeXy.X = h / 360.0; cubeXy.Y = 1.0 - s; columnY = 1.0 - v; return; case ColorPickerMode.R: cubeXy.X = b / 255.0; cubeXy.Y = 1.0 - g / 255.0; columnY = 1.0 - r / 255.0; return; case ColorPickerMode.G: cubeXy.X = b / 255.0; cubeXy.Y = 1.0 - r / 255.0; columnY = 1.0 - g / 255.0; return; case ColorPickerMode.B: cubeXy.X = r / 255.0; cubeXy.Y = 1.0 - g / 255.0; columnY = 1.0 - b / 255.0; return; default: throw new ArgumentOutOfRangeException(nameof(colorMode), colorMode, null); } }
public static void Get(Hsb hsb, ColorPickerMode colorMode, out Point cubeXy, out double columnY) { var h = hsb.H; var s = hsb.S; var v = hsb.B; double r = 0.0, g = 0.0, b = 0.0; if ((int)colorMode > 2) { var rgb = hsb.To <Rgb>(); r = rgb.R; g = rgb.G; b = rgb.B; } Count(colorMode, h, s, v, r, g, b, out cubeXy, out columnY); }
public static void GoToNextMode(bool forward = true) { int NUM_MODES = (int)ColorPickerMode.NUM_MODES; int iCur = (int)CustomColorPaletteStorage.m_Instance.Mode; /// We want modulo, but C#'s % operator is a remainder. /// So use positive numbers, noting that -1 == K-1 (in mod K arithmetic) int direction = forward ? 1 : NUM_MODES - 1; for (int i = 0; i < NUM_MODES; ++i) { int iNext = iCur + (i + 1) * direction; ColorPickerMode nextMode = (ColorPickerMode)(iNext % NUM_MODES); if (ModeIsValid(nextMode)) { CustomColorPaletteStorage.m_Instance.Mode = nextMode; return; } } }
public void Toogle_Input(ColorPickerMode mode) { var comp = ctx.RenderComponent <SimpleColorPickerTest>(p => { p.Add(x => x.ColorPickerMode, mode); p.Add(x => x.DisableInput, false); }); Console.WriteLine(comp.Markup); _ = comp.Find(_colorInputCssSelector); comp.SetParametersAndRender(p => p.Add(x => x.DisableInput, true)); Assert.Throws <ElementNotFoundException>(() => comp.Find(_colorInputCssSelector)); comp.SetParametersAndRender(p => p.Add(x => x.DisableInput, false)); _ = comp.Find(_colorInputCssSelector); }
public static void MakeRamp(ColorPickerMode mode, int width, int height, Color[] buf, Vector3?raw = null) { switch (mode) { case ColorPickerMode.SL_H_Triangle: case ColorPickerMode.SV_H_Rect: MakeHueRamp(width, height, buf); break; case ColorPickerMode.HL_S_Polar: { Debug.Assert(raw.HasValue); HSLColor color; bool ok = RawValueToHSLColor(mode, raw.Value, out color); Debug.Assert(ok); MakeSaturationRamp(color, width, height, buf); break; } case ColorPickerMode.HS_L_Polar: { Debug.Assert(raw.HasValue); HSLColor color; bool ok = RawValueToHSLColor(mode, raw.Value, out color); Debug.Assert(ok); MakeLightnessRamp(color, width, height, buf); break; } case ColorPickerMode.HS_LogV_Polar: { Debug.Assert(raw.HasValue); float hue01, saturation, value; bool ok = RawValueToHSV(mode, raw.Value, out hue01, out saturation, out value); Debug.Assert(ok); MakeLogValueRamp(hue01, saturation, width, height, buf); break; } } }
/// Returns true on success, false on failure. /// Failure cases are guaranteed to be identical to the failure cases of RawValueToColor /// Only implemented for the subset of pickers that are hsv "native" static bool RawValueToHSV( ColorPickerMode mode, Vector3 raw, out float hue01, out float saturation, out float value) { switch (mode) { case ColorPickerMode.HS_LogV_Polar: { // H is angle, S is radius, log(V) is depth var position = new Vector2(raw.x - 0.5f, raw.y - 0.5f) * 2; var radius = position.magnitude; if (radius > 1) { hue01 = saturation = value = 0; return(false); } // x direction is 0 degrees (red) hue01 = (Mathf.Atan2(position.y, position.x) / (Mathf.PI * 2)) % 1; if (hue01 < 0) { hue01 += 1; } saturation = radius; // remap [0, 1] to [kLogVMin, kLogVMax] float logValue = kLogVMin + raw.z * (sm_LogVMax - kLogVMin); value = Mathf.Pow(2, logValue) - MinHDRValue; return(true); } default: Debug.Assert(false); hue01 = saturation = value = 0; return(false); } }
// Apply luminance and/or saturation constraints to the slider (ie, RawValue.z) public static float ApplySliderConstraint( ColorPickerMode mode, float value_z, float luminanceMin, float saturationMax) { switch (mode) { case ColorPickerMode.SL_H_Triangle: case ColorPickerMode.SV_H_Rect: // Slider should be the half-open range [0, 1) to avoid double-covering red // (which causes artifacts when switching) value_z = Mathf.Clamp(value_z, 0, 1 - 1e-4f); break; case ColorPickerMode.HS_L_Polar: value_z = Mathf.Max(value_z, luminanceMin); break; case ColorPickerMode.HL_S_Polar: value_z = Mathf.Max(value_z, 1 - saturationMax); break; } return(value_z); }
public static void Get(Color color, ColorPickerMode colorMode, out Point cubeXy, out double columnY) { var r = color.R; var g = color.G; var b = color.B; double h = 0.0, s = 0.0, v = 0.0; if ((int)colorMode < 3) { var rgb = new Rgb { R = r, G = g, B = b }; var hsb = rgb.To <Hsb>(); h = hsb.H; s = hsb.S; v = hsb.B; } Count(colorMode, h, s, v, r, g, b, out cubeXy, out columnY); }
void Awake() { m_Instance = this; m_StoredColors = new StoredColor[m_NumColors]; m_Mode = ColorPickerMode.HS_L_Polar; }
public void SetLocalMode(ColorPickerMode mode) { m_LocalMode = mode; }
/// Can never fail (unlike RawValueToColor) /// /// Note: Behavior is currently undefined if an hdr color is passed in, /// but the color picker cannot handle hdr. public static Vector3 ColorToRawValue(ColorPickerMode mode, Color rgb) { bool colorIsHdr = (rgb.r > 1 || rgb.g > 1 || rgb.b > 1); // If we do this a lot, maybe add this to ColorPickerInfo.hdr? // Or better, refactor this whole mess of code into small mode-specific classes. bool pickerSupportsHdr = (mode == ColorPickerMode.HS_LogV_Polar); if (colorIsHdr && !pickerSupportsHdr) { // Shouldn't happen except in experimental Debug.LogErrorFormat("Truncating HDR color to LDR"); float h, s, v; Color.RGBToHSV(rgb, out h, out s, out v); rgb = Color.HSVToRGB(h, s, v, hdr: false); } switch (mode) { case ColorPickerMode.SV_H_Rect: { float h, s, v; Color.RGBToHSV(rgb, out h, out s, out v); return(new Vector3(s, v, h)); } case ColorPickerMode.HS_L_Polar: { // H is angle, S is radius, L is depth HSLColor color = (HSLColor)rgb; var angle = color.HueDegrees * Mathf.Deg2Rad; var vector = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) * color.s / 2 + new Vector2(0.5f, 0.5f); return(new Vector3(vector.x, vector.y, color.l)); } case ColorPickerMode.HL_S_Polar: { // H is angle, (1-L) is radius, (1-S) is depth HSLColor color = (HSLColor)rgb; var angle = color.HueDegrees * Mathf.Deg2Rad; float radius = 1 - color.l; var vector = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) * radius / 2 + new Vector2(0.5f, 0.5f); return(new Vector3(vector.x, vector.y, 1 - color.s)); } case ColorPickerMode.SL_H_Triangle: { HSLColor color = (HSLColor)rgb; Vector3 ret = new Vector3(); ret.y = color.l; ret.z = color.Hue01; float maxChroma = SQRT3 * ((color.l < .5f) ? color.l : (1 - color.l)); ret.x = maxChroma * color.s; return(ret); } case ColorPickerMode.HS_LogV_Polar: { // H is angle, S is radius, log(V) is depth // This only needs to be > 0 and < the minimum ColorPickerMode.HS_LogV_Polar float kMinValue = 1e-7f; float h, s, v; Color.RGBToHSV(rgb, out h, out s, out v); Vector2 cartesian; { float angle = h * (Mathf.PI * 2); cartesian = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) * s; // convert from [-1, 1] to [0, 1] cartesian = cartesian / 2 + new Vector2(.5f, .5f); } // Log-remap [2^-n, 2^n] to [-n, n] v += MinHDRValue; float slider = Mathf.Log(Mathf.Max(v, kMinValue), 2); slider = Mathf.Clamp(slider, kLogVMin, sm_LogVMax); // remap from [min, max] to [0, 1] slider = (slider - kLogVMin) / (sm_LogVMax - kLogVMin); return(new Vector3(cartesian.x, cartesian.y, slider)); } default: return(new Vector3(1, 1, 1)); } }
void UpdateColorSelectorAndSlider(bool inputValid, Ray inputRay, Collider parentCollider) { // Reset our input object if we're not holding the trigger. if (!InputManager.m_Instance.GetCommand(InputManager.SketchCommands.Activate)) { ResetActiveInputObject(); } // Color limits if we're tied to the brush color. float luminanceMin = 0.0f; float saturationMax = 1.0f; BrushColorController brushController = m_ColorController as BrushColorController; if (brushController != null) { luminanceMin = brushController.BrushLuminanceMin; saturationMax = brushController.BrushSaturationMax; } // Cache mode cause we use it a bunch. ColorPickerMode mode = ColorPickerUtils.GetActiveMode(m_ColorController.IsHdr); // Check for collision against our color slider first. RaycastHit hitInfo; if (m_ActiveInputObject == null || m_ActiveInputObject == m_ColorPickerSlider.gameObject) { bool validCollision = BasePanel.DoesRayHitCollider(inputRay, m_ColorPickerSlider.GetCollider(), out hitInfo); // TODO : ColorPickerSlider should be a UIComponent that handles this stuff // on its own. // If we're not colliding with the slider, but we were before, get our collision with // our parent collider. if (!validCollision && m_ActiveInputObject == m_ColorPickerSlider.gameObject) { validCollision = BasePanel.DoesRayHitCollider(inputRay, parentCollider, out hitInfo); } if (validCollision) { // Over slider, check for mouse down. if (InputManager.m_Instance.GetCommand(InputManager.SketchCommands.Activate)) { float value = ColorPickerUtils.ApplySliderConstraint(mode, m_ColorPickerSlider.GetValueFromHit(hitInfo), luminanceMin, saturationMax); UpdateSelectorSlider(value); UpdateSliderPosition(); Color newColor; if (ColorPickerUtils.RawValueToColor(mode, m_ColorPickerSelector.RawValue, out newColor)) { m_ColorController.SetCurrentColorSilently(newColor); TriggerColorPicked(newColor); } else { // Indicates some logic fault: the user isn't modifying the color plane, // so why is the color plane's value outside the valid range? Debug.LogErrorFormat("Unexpected bad RawValue. mode:{0} val:{1}", mode, m_ColorPickerSelector.RawValue); } SketchSurfacePanel.m_Instance.VerifyValidToolWithColorUpdate(); m_ActiveInputObject = m_ColorPickerSlider.gameObject; } } } if (m_ActiveInputObject == null || m_ActiveInputObject == m_ColorPickerSelector.gameObject) { if (BasePanel.DoesRayHitCollider(inputRay, m_ColorPickerSelector.GetCollider(), out hitInfo)) { // Over color picker, check for input. if (InputManager.m_Instance.GetCommand(InputManager.SketchCommands.Activate)) { Vector3 value = ColorPickerUtils.ApplyPlanarConstraint( m_ColorPickerSelector.GetValueFromHit(hitInfo), mode, luminanceMin, saturationMax); Color color; if (ColorPickerUtils.RawValueToColor(mode, value, out color)) { m_ColorPickerSelector.RawValue = value; m_ColorController.SetCurrentColorSilently(color); TriggerColorPicked(color); m_ColorPickerSlider.OnColorChanged(mode, value); SketchSurfacePanel.m_Instance.VerifyValidToolWithColorUpdate(); m_ActiveInputObject = m_ColorPickerSelector.gameObject; } } } } }
void OnCurrentColorSet(ColorPickerMode mode, Vector3 rawColor) { m_ColorPickerSelector.RawValue = rawColor; m_ColorPickerSlider.RawValue = m_ColorPickerSelector.RawValue.z; m_ColorPickerSlider.OnColorChanged(mode, rawColor); }
/// Returns true on success, false on failure. /// Failure cases are guaranteed to be identical to the failure cases of RawValueToColor /// Use if converting raw -> Color is lossy; otherwise, use RawValueToColor /// HDR color pickers might disallow conversion to HSL. static bool RawValueToHSLColor(ColorPickerMode mode, Vector3 raw, out HSLColor color) { const float EPSILON = 1e-5f; switch (mode) { case ColorPickerMode.SV_H_Rect: color = HSLColor.FromHSV(raw.z * HSLColor.HUE_MAX, raw.x, raw.y); return(true); case ColorPickerMode.HS_L_Polar: { var position = new Vector2(raw.x - 0.5f, raw.y - 0.5f) * 2; var radius = position.magnitude; color = new HSLColor(); if (radius > 1) { if (radius > 1 + EPSILON) { return(false); } else { radius = 1; } } // x direction is 0 degrees (red) color.HueDegrees = Mathf.Atan2(position.y, position.x) * Mathf.Rad2Deg; color.s = radius; color.l = raw.z; color.a = 1; return(true); } case ColorPickerMode.SL_H_Triangle: { color.h = 0; // assigned later color.l = raw.y; float maxChroma = SQRT3 * ((color.l < .5f) ? color.l : (1 - color.l)); color.s = (maxChroma == 0) ? 0 : raw.x / maxChroma; color.a = 1; color.Hue01 = raw.z; return(0 <= raw.x && raw.x <= maxChroma); } case ColorPickerMode.HL_S_Polar: { var position = new Vector2(raw.x - 0.5f, raw.y - 0.5f) * 2; var radius = position.magnitude; color = new HSLColor(); if (radius > 1) { if (radius > 1 + EPSILON) { return(false); } else { radius = 1; } } color.HueDegrees = Mathf.Atan2(position.y, position.x) * Mathf.Rad2Deg; color.l = 1 - radius; color.s = 1 - raw.z; color.a = 1; return(true); } case ColorPickerMode.HS_LogV_Polar: throw new InvalidOperationException("This is a HDR mode"); default: Debug.Assert(false); color = new HSLColor(); return(false); } }