From 5e1defa793be15465d8be0be20fdffc795a6d03b Mon Sep 17 00:00:00 2001 From: Mark Joshwel Date: Mon, 18 Nov 2024 18:02:41 +0800 Subject: [PATCH] game: working game, half-working database --- .../inspectionProfiles/Project_Default.xml | 6 ++ ColourMeOKGame/Assets/Scenes/GameScene.unity | 38 +-------- ColourMeOKGame/Assets/Scripts/Backend.cs | 2 +- ColourMeOKGame/Assets/Scripts/Colorimetry.cs | 81 ++++++++++++++++--- ColourMeOKGame/Assets/Scripts/GameManager.cs | 64 ++++++++++----- ColourMeOKGame/Assets/Scripts/Gameplay.cs | 42 +++++----- .../Assets/Scripts/LocalPlayerData.cs | 12 +-- ColourMeOKGame/Assets/Scripts/SideViewUI.cs | 10 +-- 8 files changed, 150 insertions(+), 105 deletions(-) create mode 100644 ColourMeOKGame/.idea/.idea.ColourMeOKGame/.idea/inspectionProfiles/Project_Default.xml diff --git a/ColourMeOKGame/.idea/.idea.ColourMeOKGame/.idea/inspectionProfiles/Project_Default.xml b/ColourMeOKGame/.idea/.idea.ColourMeOKGame/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..ebdfbd6 --- /dev/null +++ b/ColourMeOKGame/.idea/.idea.ColourMeOKGame/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/ColourMeOKGame/Assets/Scenes/GameScene.unity b/ColourMeOKGame/Assets/Scenes/GameScene.unity index c80fb31..87fe1f5 100644 --- a/ColourMeOKGame/Assets/Scenes/GameScene.unity +++ b/ColourMeOKGame/Assets/Scenes/GameScene.unity @@ -143,7 +143,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!114 &133964671 MonoBehaviour: m_ObjectHideFlags: 0 @@ -258,7 +258,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!4 &447905427 Transform: m_ObjectHideFlags: 0 @@ -476,7 +476,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!114 &1204483825 MonoBehaviour: m_ObjectHideFlags: 0 @@ -505,37 +505,6 @@ Transform: m_Children: [] m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &1680304394 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1680304395} - m_Layer: 0 - m_Name: GameObject - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &1680304395 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1680304394} - serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 0} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1660057539 &9223372036854775807 SceneRoots: m_ObjectHideFlags: 0 @@ -545,4 +514,3 @@ SceneRoots: - {fileID: 133964672} - {fileID: 447905427} - {fileID: 1204483826} - - {fileID: 1680304395} diff --git a/ColourMeOKGame/Assets/Scripts/Backend.cs b/ColourMeOKGame/Assets/Scripts/Backend.cs index 3daf4e4..b9a558f 100644 --- a/ColourMeOKGame/Assets/Scripts/Backend.cs +++ b/ColourMeOKGame/Assets/Scripts/Backend.cs @@ -546,7 +546,7 @@ public void GetRecentScores(Action + /// calculate a similarity percentage from a colour distance + /// + /// + /// the DeltaLabChE object returned by CalculateDistance, + /// + /// + /// the maximum chroma value to use for the similarity percentage calculation, + /// defaults to 1.0f + /// + /// + /// the maximum hue value to use for the similarity percentage calculation, + /// defaults to 1.0f + /// + /// + /// the maximum lightness value to use for the similarity percentage calculation, + /// defaults to 1.0f + /// + /// a LCh struct with 0-1f values + public static LCh CalculateLChSimilarityPercentage( + DeltaLabChE delta, + double chromaMax = 1.0d, + double hueMax = 1.0d, + double lightnessMax = 1.0d) + { + // dL = [-1, 1] lightness difference (negative = template is darker) + // dC = [-inf, +inf] chroma difference (negative = template is more chromatic) + // dH = [0, +inf] hue difference (zero for grayscale or similar hues) + // dE = [0, 1] overall perceptual difference in the oklab colour space + // (but since we're using sRGB, we just use 1.0f as the max bounds) + return new LCh((float)Math.Clamp(1 - Math.Abs(delta.dL) / lightnessMax, 0, 1), + (float)Math.Clamp(1 - Math.Abs(delta.dC) / chromaMax, 0, 1), + (float)Math.Clamp(1 - delta.dh / hueMax, 0, 1)); + } + /// /// calculate a 0-100% distance/accuracy between two unity rgba colour objects /// /// the template colour to compare against /// the response colour to compare - /// a DeltaLabCHE struct - public static DeltaLabCHE CalculateDistance(Color template, Color response) + /// a DeltaLabChE struct + public static DeltaLabChE CalculateDistance(Color template, Color response) { // rgb to oklab var templateOklab = linear_srgb_to_oklab(new RGB( @@ -48,7 +83,7 @@ public static DeltaLabCHE CalculateDistance(Color template, Color response) var deltaH = Math.Max(0d, Math.Sqrt(deltaA * deltaA + deltaB * deltaB - deltaC * deltaC)); var deltaE = Math.Sqrt(deltaL * deltaL + deltaC * deltaC + deltaH * deltaH); - return new DeltaLabCHE(deltaL, deltaA, deltaB, deltaC, deltaH, deltaE); + return new DeltaLabChE(deltaL, deltaA, deltaB, deltaC, deltaH, deltaE); } /// @@ -136,7 +171,6 @@ public static RGB gamut_clip_preserve_chroma(RGB rgb) /// a and b must be normalized so a^2 + b^2 == 1 /// // https://bottosson.github.io/posts/gamutclipping/ (MIT) - // ReSharper disable once MemberCanBePrivate.Global public static float find_gamut_intersection( float a, float b, @@ -380,27 +414,27 @@ public static float compute_max_saturation(float a, float b) } // ReSharper disable once InconsistentNaming - public struct DeltaLabCHE + public struct DeltaLabChE { // ReSharper disable once InconsistentNaming - public double dL; + public readonly double dL; // ReSharper disable once InconsistentNaming - public double da; + public readonly double da; // ReSharper disable once InconsistentNaming - public double db; + public readonly double db; // ReSharper disable once InconsistentNaming - public double dC; + public readonly double dC; // ReSharper disable once InconsistentNaming - public double dH; + public readonly double dh; // ReSharper disable once InconsistentNaming - public double dE; + public readonly double dE; - public DeltaLabCHE( + public DeltaLabChE( // ReSharper disable once InconsistentNaming double L, double a, @@ -416,7 +450,7 @@ public struct DeltaLabCHE da = a; db = b; dC = C; - dH = H; + dh = H; dE = E; } } @@ -440,6 +474,27 @@ public Lab(float L, float a, float b) } } + public readonly struct LCh + { + public readonly float L; + public readonly float C; + + // ReSharper disable once InconsistentNaming + public readonly float h; + + public LCh( + // ReSharper disable once InconsistentNaming + float L, + // ReSharper disable once InconsistentNaming + float C, + float h) + { + this.L = L; + this.C = C; + this.h = h; + } + } + public readonly struct RGB { // ReSharper disable once InconsistentNaming diff --git a/ColourMeOKGame/Assets/Scripts/GameManager.cs b/ColourMeOKGame/Assets/Scripts/GameManager.cs index 5c8f6d0..74cf866 100644 --- a/ColourMeOKGame/Assets/Scripts/GameManager.cs +++ b/ColourMeOKGame/Assets/Scripts/GameManager.cs @@ -202,24 +202,48 @@ public void SignalGameEnd(List playedRounds) var roundChromaAcc = 0d; var roundHueAcc = 0d; var roundPerceivedAcc = 0d; - - var maxDistance = Colorimetry.CalculateDistance(Color.black, Color.white); - - foreach (var distance in playedRounds.Select(round => - Colorimetry.CalculateDistance(round.TemplateColour, round.ResponseColour))) + + var templateColour = Color.clear; + var responseColour = Color.clear; + var roundNumber = 1; + foreach (var distance in playedRounds.Take(Gameplay.RoundsPerGame).Select(round => + Colorimetry.CalculateDistance(templateColour = round.TemplateColour, + responseColour = round.ResponseColour))) { - roundLightnessAcc += distance.dL / maxDistance.dL; - roundChromaAcc += distance.dC / maxDistance.dC; - roundHueAcc += distance.dH / maxDistance.dH; - roundPerceivedAcc += distance.dE / maxDistance.dE; + var dLCh = Colorimetry.CalculateLChSimilarityPercentage(distance); + + Debug.Log( + $"processing round: template={templateColour}, response={responseColour} (dL%={dLCh.L}, dC%={dLCh.C}, dh%={dLCh.h}, dEok={distance.dE:F})"); + + roundLightnessAcc += Math.Clamp(dLCh.L * 100d, 0d, 100d); + roundChromaAcc += Math.Clamp(dLCh.C * 100d, 0d, 100d); + roundHueAcc += Math.Clamp(dLCh.h * 100d, 0d, 100d); + roundPerceivedAcc += Math.Clamp((100d - distance.dE) * 100d, 0d, 100d); + + var showcaseTemplate = ui.UI.Q($"ShowcasePair{roundNumber}TemplateColour"); + var showcaseResponse = ui.UI.Q($"ShowcasePair{roundNumber}ResponseColour"); + var showcaseInfo = ui.UI.Q