修复馆内三维点位显示异常
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
lyf
2026-07-04 23:42:05 +08:00
parent f03783201d
commit 39f1fc1198
5 changed files with 629 additions and 47 deletions

View File

@@ -31,6 +31,15 @@ interface CachedModelEntry {
lastUsedAt: number
}
type GuideModelDiagnosticEvent =
| 'cache-hit'
| 'cache-miss'
| 'in-flight-hit'
| 'load-start'
| 'load-complete'
| 'load-failed'
| 'preload-skip'
// 当前 SDK 数据包含 8 个可导览楼层;缓存需覆盖多层展开、全楼模型和相邻预加载余量,避免加载中途淘汰刚加载过的单层模型。
const defaultMaxModelSourceEntries = 10
@@ -53,6 +62,30 @@ const emptyResources = (): GuideModelResourceSet => ({
textures: new Set()
})
const getNow = () => (
typeof performance !== 'undefined' && typeof performance.now === 'function'
? performance.now()
: Date.now()
)
const isModelDiagnosticsEnabled = () => {
if (!import.meta.env.DEV) return false
if (typeof window === 'undefined') return true
const diagnosticsWindow = window as unknown as {
__GUIDE_3D_MODEL_DIAGNOSTICS__?: boolean
}
return diagnosticsWindow.__GUIDE_3D_MODEL_DIAGNOSTICS__ !== false
}
const logModelDiagnostic = (
event: GuideModelDiagnosticEvent,
payload: Record<string, unknown>
) => {
if (!isModelDiagnosticsEnabled()) return
console.debug(`[GuideModelLoadManager] ${event}`, payload)
}
const collectMaterialTextures = (material: THREE.Material) => {
const textures = new Set<THREE.Texture>()
const materialRecord = material as unknown as Record<string, unknown>
@@ -295,7 +328,16 @@ export class GuideModelLoadManager {
const candidates = options.urls.map((url) => url.trim()).filter(Boolean)
for (const url of candidates) {
const key = this.createCacheKey(url, options.semanticKey)
if (!key || this.sourceCache.has(key) || this.inFlightCache.has(key)) return
if (!key || this.sourceCache.has(key) || this.inFlightCache.has(key)) {
logModelDiagnostic('preload-skip', {
label: options.label,
url,
key,
reason: !key ? 'empty-key' : this.sourceCache.has(key) ? 'cache-hit' : 'in-flight-hit',
diagnostics: this.getDiagnostics()
})
return
}
await this.loadSource(url, options)
return
}
@@ -315,23 +357,60 @@ export class GuideModelLoadManager {
if (cached) {
cached.lastUsedAt = Date.now()
this.diagnostics.hits += 1
logModelDiagnostic('cache-hit', {
label: options.label,
url,
key,
diagnostics: this.getDiagnostics()
})
return cached
}
this.diagnostics.misses += 1
logModelDiagnostic('cache-miss', {
label: options.label,
url,
key,
diagnostics: this.getDiagnostics()
})
let inFlight = this.inFlightCache.get(key)
const startedAt = getNow()
if (inFlight) {
this.diagnostics.inFlightHits += 1
logModelDiagnostic('in-flight-hit', {
label: options.label,
url,
key,
diagnostics: this.getDiagnostics()
})
} else {
logModelDiagnostic('load-start', {
label: options.label,
url,
key
})
inFlight = options.loadSource(url)
this.inFlightCache.set(key, inFlight)
}
const gltf = await inFlight.finally(() => {
let gltf: GLTF
try {
gltf = await inFlight
} catch (error) {
logModelDiagnostic('load-failed', {
label: options.label,
url,
key,
elapsedMs: Math.round(getNow() - startedAt),
error: error instanceof Error ? error.message : String(error)
})
throw error
} finally {
if (this.inFlightCache.get(key) === inFlight) {
this.inFlightCache.delete(key)
}
})
}
const entry: CachedModelEntry = {
key,
@@ -341,6 +420,13 @@ export class GuideModelLoadManager {
}
this.sourceCache.set(key, entry)
this.trim()
logModelDiagnostic('load-complete', {
label: options.label,
url,
key,
elapsedMs: Math.round(getNow() - startedAt),
diagnostics: this.getDiagnostics()
})
return entry
}