Commit 328c1bba by James Yuan

fix: 照明模式不再改太阳时间与环境光照

N/E 照明仅同步设施聚光灯,进出时不调用压暗/恢复环境参数。

Co-authored-by: Cursor <cursoragent@cursor.com>
parent b045a98f
......@@ -33,9 +33,6 @@ type BridgeLike = {
removeLight: (id: string) => void
clearLights?: () => void
setLightVisible: (id: string, visible: boolean) => void
applyDayNight: (night: boolean, opts?: { denseFog?: boolean }) => void
captureEnvironmentLighting?: () => void
restoreInitialEnvironment?: () => void
}
function isLightMode(mode: ScreenMode) {
......@@ -89,7 +86,7 @@ function toSpot(s: SensorSnapshot, on: boolean): RtengineLight {
}
/**
* 照明模式:夜晚压暗(无雾)+ 每盏设施朝下 spotlight。
* 照明模式:仅同步设施朝下 spotlight,不改太阳时间 / 天气 / 日照等任何环境光照参数。
* 开 → 显示灯;关 → 隐藏灯。
*/
export function useLightSceneEffects(bridge: BridgeLike, enabled: Ref<boolean>) {
......@@ -101,14 +98,7 @@ export function useLightSceneEffects(bridge: BridgeLike, enabled: Ref<boolean>)
/** sensorId → 是否开 */
const knownOn = new Map<string, boolean>()
let activeSpotIds: string[] = []
let nightOn = false
let timer: number | undefined
let restoreTimers: number[] = []
function clearRestoreTimers() {
for (const t of restoreTimers) window.clearTimeout(t)
restoreTimers = []
}
function clearSpots() {
for (const id of activeSpotIds) {
......@@ -128,34 +118,6 @@ export function useLightSceneEffects(bridge: BridgeLike, enabled: Ref<boolean>)
}
}
function ensureNight(want: boolean, force = false) {
if (!force && want === nightOn) return
if (want) {
clearRestoreTimers()
bridge.captureEnvironmentLighting?.()
// 照明模式:黑底但空气清澈,灯光才能照亮整间房
bridge.applyDayNight(true)
nightOn = true
return
}
// 切走照明:恢复场景初始光线(solarTime=16 等),并补几次以防引擎异步冲掉
bridge.applyDayNight(false)
bridge.restoreInitialEnvironment?.()
nightOn = false
clearRestoreTimers()
for (const ms of [150, 500, 1200]) {
restoreTimers.push(
window.setTimeout(() => {
if (!enabled.value || !bridge.ready.value) return
if (isLightMode(mode.value)) return
bridge.restoreInitialEnvironment?.()
bridge.applyDayNight(false)
nightOn = false
}, ms),
)
}
}
function upsertLight(
light: RtengineLight,
on: boolean,
......@@ -203,19 +165,13 @@ export function useLightSceneEffects(bridge: BridgeLike, enabled: Ref<boolean>)
const modeChanged = current !== lastMode
if (!lighting) {
const leavingLight =
isLightMode(lastMode as ScreenMode) || nightOn || activeSpotIds.length > 0
// 仅从照明切走时卸灯并恢复初始光线;首次进压差等不要误触恢复
if (leavingLight) {
clearSpots()
ensureNight(false, true)
}
const leavingLight = isLightMode(lastMode as ScreenMode) || activeSpotIds.length > 0
// 仅从照明切走时卸灯;不改环境光照
if (leavingLight) clearSpots()
lastMode = current
return
}
ensureNight(true, force || modeChanged)
const sensors = lightsOf(realtime.snapshot, current)
if (force || modeChanged) {
clearSpots()
......
......@@ -63,12 +63,11 @@ export type RtengineLight = {
* 勿传小数小时(12.5);需先换算。
*/
export const DAY_SOLAR_TIME = 12.0
/** 照明模式深夜:0:00,配合阴天/雾压暗 */
export const NIGHT_SOLAR_TIME = 0
/**
* 镜湖医院场景初始环境(来自 designer scenes/.../environment + 运行时 getSunParam 核对)。
* 离开照明模式时按此恢复,避免假白天 12:00 / setSunParam(1,0) 对不上初始光线。
* 照明 N/E 模式不改太阳时间(preserveSolarTime)。
* 见 deploy/rtengine_env_snapshot_177.json
*/
export const SCENE_INITIAL_ENV = {
......@@ -1084,9 +1083,10 @@ export function useRtengineBridge(opts: {
})
}
function applyEnvSnapshot(snap: EnvLightingSnapshot) {
function applyEnvSnapshot(snap: EnvLightingSnapshot, opts?: { preserveSolarTime?: boolean }) {
const [intensity, fogDensity, h, s, v, a] = snap.sunParam
setSolarTime(snap.solarTime)
// 照明模式要求不改太阳时间,仅恢复天气/日照参数
if (!opts?.preserveSolarTime) setSolarTime(snap.solarTime)
setWeather(snap.weatherId, { ...snap.weather })
setSunParam(intensity, fogDensity, h, s, v, a)
setLighting({
......@@ -1095,7 +1095,7 @@ export function useRtengineBridge(opts: {
sunBrightness: snap.lighting.sunBrightness,
})
setFog(snap.fog)
setSolarTime(snap.solarTime)
if (!opts?.preserveSolarTime) setSolarTime(snap.solarTime)
}
/** 从引擎异步读取当前环境,写入 envSnapshot(进夜景后忽略晚到的回调) */
......@@ -1149,23 +1149,26 @@ export function useRtengineBridge(opts: {
}
/** 恢复进入照明前的初始光线(场景 environment) */
function restoreInitialEnvironment() {
function restoreInitialEnvironment(opts?: { preserveSolarTime?: boolean }) {
if (!envSnapshot) envSnapshot = defaultEnvSnapshot()
applyEnvSnapshot(envSnapshot)
applyEnvSnapshot(envSnapshot, opts)
}
/**
* 昼夜切换。
* 夜间默认「关太阳、空气清澈」,便于 spotlight 照亮房间。
* opts.denseFog=true 才恢复旧的浓雾全黑(一般不用)。
* 离开夜景:恢复场景初始环境,而不是假白天 12:00。
* 昼夜切换(照明压暗)。
* 关太阳、清空气,便于 spotlight 照亮房间;不改太阳时间。
* opts.denseFog=true 才用浓雾全黑(一般不用)。
* 离开夜景:恢复场景初始环境(同样可不改太阳时间)。
*/
function applyDayNight(night: boolean, opts?: { denseFog?: boolean }) {
function applyDayNight(
night: boolean,
opts?: { denseFog?: boolean; preserveSolarTime?: boolean },
) {
const preserveSolarTime = opts?.preserveSolarTime !== false
if (night) {
if (!envSnapshot) captureEnvironmentLighting()
// 关闭采集窗,避免夜景参数被当成「初始光线」
envCaptureOpen = false
setSolarTime(NIGHT_SOLAR_TIME)
if (opts?.denseFog) {
setWeather(5, {
fog: 1,
......@@ -1178,7 +1181,7 @@ export function useRtengineBridge(opts: {
setSunParam(0, 1, 0, 0, 0, 1)
setFog(1)
} else {
// 深夜无日照 + 无雾:场景黑底,由 spotlight 照亮房间
// 无日照 + 无雾:场景黑底,由 spotlight 照亮房间(不碰 setSolarTime)
setWeather(1, {
fog: 0,
fogDensity: 0,
......@@ -1190,9 +1193,8 @@ export function useRtengineBridge(opts: {
setSunParam(0, 0, 0, 0, 0, 1)
setFog(0)
}
setSolarTime(NIGHT_SOLAR_TIME)
} else {
restoreInitialEnvironment()
restoreInitialEnvironment({ preserveSolarTime })
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment