From 0b1330de9b8d78f398753d878f495f324617d203 Mon Sep 17 00:00:00 2001 From: "Somhairle H. Marisol" Date: Tue, 29 Sep 2026 10:58:24 +0800 Subject: p73: 昼夜光照四时段档(清晨/正午/黄昏/夜晚) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit M6Presentation 新增 periodAtTick/periodLighting 参数表(AmbientTint 乘性色调 + Veil/VeilAlpha 加性覆盖 + LanternGlow),边界与 timePeriodLabel 一致;正午为恒等档不改白平衡。DrawWorldView 并入时段色调与 effectiveLanternGlow(黄昏 0.6 起点亮、夜晚 1.0),覆盖色最后叠加。新增 P73 回归;新增 LV_P73_SHOT 同机位四帧证据 + analyze-p73(verdict=PASS);字形表补 正/午(345)。Desktop 346/346、Kernel 120/120、digest 与 p70 一致。 --- .../LivingVillage.Desktop.Tests.fsproj | 1 + .../P73LightingTierTests.fs | 67 ++++++++++++++++++++++ src/LivingVillage.Desktop.Tests/PrototypeTests.fs | 2 +- 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 src/LivingVillage.Desktop.Tests/P73LightingTierTests.fs (limited to 'src/LivingVillage.Desktop.Tests') diff --git a/src/LivingVillage.Desktop.Tests/LivingVillage.Desktop.Tests.fsproj b/src/LivingVillage.Desktop.Tests/LivingVillage.Desktop.Tests.fsproj index 432cd03..11a1b90 100644 --- a/src/LivingVillage.Desktop.Tests/LivingVillage.Desktop.Tests.fsproj +++ b/src/LivingVillage.Desktop.Tests/LivingVillage.Desktop.Tests.fsproj @@ -44,6 +44,7 @@ + diff --git a/src/LivingVillage.Desktop.Tests/P73LightingTierTests.fs b/src/LivingVillage.Desktop.Tests/P73LightingTierTests.fs new file mode 100644 index 0000000..e5baf0a --- /dev/null +++ b/src/LivingVillage.Desktop.Tests/P73LightingTierTests.fs @@ -0,0 +1,67 @@ +namespace LivingVillage.Desktop.Tests + +open Microsoft.VisualStudio.TestTools.UnitTesting +open Microsoft.Xna.Framework +open LivingVillage.Desktop +open LivingVillage.Kernel +open LivingVillage.Kernel.Sim + +/// P73 回归:四时段光照档参数表完整性 + 与既有连续光照/时段标签一致。 +[] +type P73LightingTierTests () = + + let ticksPerHour = Sim.ticksPerDay / 24L + let atHour hour = int64 hour * ticksPerHour + + [] + member _.PeriodTableCoversFourDistinctTiers () = + let periods = [ M6Presentation.Morning; M6Presentation.Noon; M6Presentation.Dusk; M6Presentation.Night ] + let stated = + periods + |> List.map (fun p -> + let l = M6Presentation.periodLighting p + (p, l.AmbientTint.R, l.AmbientTint.G, l.AmbientTint.B, l.Veil.R, l.Veil.G, l.Veil.B, l.VeilAlpha, l.LanternGlow)) + // 四档两两不同(色调/覆盖色/alpha/灯光至少一项相异)。 + Assert.AreEqual(4, stated |> List.map (fun (_, r, g, b, vr, vg, vb, a, glow) -> (r, g, b, vr, vg, vb, a, glow)) |> List.distinct |> List.length) + // 名称表覆盖全四档。 + let names = periods |> List.map M6Presentation.lightingPeriodName + Assert.AreEqual(4, names |> List.distinct |> List.length) + Assert.IsTrue(names |> List.forall (fun n -> n <> "")) + + [] + member _.NoonTierIsIdentityAndNightLightsLanterns () = + let noon = M6Presentation.periodLighting M6Presentation.Noon + Assert.AreEqual(255, int noon.AmbientTint.R) + Assert.AreEqual(255, int noon.AmbientTint.G) + Assert.AreEqual(255, int noon.AmbientTint.B) + Assert.AreEqual(0, noon.VeilAlpha) + Assert.AreEqual(0.0f, noon.LanternGlow) + + let night = M6Presentation.periodLighting M6Presentation.Night + Assert.AreEqual(1.0f, night.LanternGlow) + let dusk = M6Presentation.periodLighting M6Presentation.Dusk + Assert.IsTrue(dusk.LanternGlow >= 0.3f, "黄昏须开始点亮路灯/灯笼") + + // 实际灯光强度:夜晚点亮,正午熄灭。 + Assert.IsTrue(M6Presentation.effectiveLanternGlow (atHour 22) >= 1.0f) + Assert.AreEqual(0.0f, M6Presentation.effectiveLanternGlow (atHour 12)) + + [] + member _.PeriodAtTickMatchesRequestedHoursAndExistingLabels () = + Assert.AreEqual(M6Presentation.Morning, M6Presentation.periodAtTick (atHour 6)) + Assert.AreEqual(M6Presentation.Noon, M6Presentation.periodAtTick (atHour 12)) + Assert.AreEqual(M6Presentation.Dusk, M6Presentation.periodAtTick (atHour 18)) + Assert.AreEqual(M6Presentation.Night, M6Presentation.periodAtTick (atHour 22)) + // 边界与既有 timePeriodLabel 完全一致:清晨↔清晨、正午↔白天、黄昏↔黄昏、夜晚↔夜晚。 + let expectedLabel period = + match period with + | M6Presentation.Morning -> "清晨" + | M6Presentation.Noon -> "白天" + | M6Presentation.Dusk -> "黄昏" + | M6Presentation.Night -> "夜晚" + for hour in 0 .. 23 do + let label = M6Presentation.timePeriodLabel (atHour hour) + Assert.AreEqual(expectedLabel (M6Presentation.periodAtTick (atHour hour)), label) + // 乘法色调:白色恒等。 + let day = M6Presentation.profileAtTick (atHour 12) + Assert.AreEqual(day.WorldTint, M6Presentation.multiplyTint day.WorldTint (M6Presentation.periodLighting M6Presentation.Noon).AmbientTint) diff --git a/src/LivingVillage.Desktop.Tests/PrototypeTests.fs b/src/LivingVillage.Desktop.Tests/PrototypeTests.fs index 68e5b93..5da55f1 100644 --- a/src/LivingVillage.Desktop.Tests/PrototypeTests.fs +++ b/src/LivingVillage.Desktop.Tests/PrototypeTests.fs @@ -1100,7 +1100,7 @@ type PrototypeTests () = [] member _.CjkGlyphAtlasHasAStableCharacterTableAndGeometry () = - Assert.AreEqual(343, characters.Length) + Assert.AreEqual(345, characters.Length) CollectionAssert.AreEqual(characters, characters |> Array.sort) Assert.AreEqual(characters.Length, characters |> Array.distinct |> Array.length) Assert.AreEqual(16, columns) -- cgit v1.2.3