恢复空间标签层级与模型锚点
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
cxk
2026-07-20 08:56:03 +08:00
parent 298e7d7606
commit 3cc0336806
6 changed files with 223 additions and 80 deletions

View File

@@ -65,6 +65,11 @@ import type {
GuideRouteFloorSegment,
GuideRouteResult
} from '@/domain/museum'
import {
getPoiDisplayPolicy,
isPoiVisibilityTierAtLeast,
type PoiVisibilityTier
} from '@/domain/poiDisplay'
import {
compareFloorsTopToBottom,
getFloorSortLevel
@@ -341,7 +346,6 @@ interface FloorOption {
type RenderPoi = GuideRenderPoi
type PoiDisplayMode = 'core' | 'balanced' | 'detail'
type PoiVisibilityTier = 'tight' | 'balanced' | 'full'
interface PoiSpriteUserData {
poi?: RenderPoi
@@ -607,8 +611,6 @@ const poiHitTargetScaleMultiplier = 4.8
const poiHitTargetCoreScaleMultiplier = 5.4
const poiScreenHitRadiusPx = 64
const poiScreenHitRadiusCorePx = 76
const poiAmbientLabelHallSpacingPx = 92
const poiAmbientLabelServiceSpacingPx = 72
const modelLoadRetryDelaysMs = [300, 900]
const adjacentPreloadDelayMs = 900
const manualAutoSwitchPauseMs = 1500
@@ -844,29 +846,6 @@ const syncControlInteractionOptions = (event?: PointerEvent) => {
controls.touches.TWO = THREE.TOUCH.DOLLY_ROTATE
}
const corePoiCategories = new Set([
'poi',
'touring_poi',
'exhibition_hall',
'exhibition_hall_entrance',
'basic_service_facility',
'transport_circulation',
'accessibility_special_service'
])
const poiCategoryPriority: Record<string, number> = {
target_preview: 100,
exhibition_hall: 96,
exhibition_hall_entrance: 92,
touring_poi: 90,
poi: 86,
accessibility_special_service: 88,
basic_service_facility: 82,
business_poi: 80,
transport_circulation: 76,
operation_experience: 46
}
const isHallPoi = (poi: RenderPoi) => (
poi.kind === 'hall'
|| poi.primaryCategory === 'exhibition_hall'
@@ -881,6 +860,13 @@ const isServiceFacilityPoi = (poi: RenderPoi) => (
const isTransportPoi = (poi: RenderPoi) => poi.primaryCategory === 'transport_circulation'
const getPoiPolicy = (poi: RenderPoi) => (
poi.displayPolicy || getPoiDisplayPolicy({
primaryCategory: poi.primaryCategory,
kind: poi.kind
})
)
const poiGlyphMap: Record<string, string> = {
poi: '点',
accessible_restroom: '无',
@@ -1263,15 +1249,11 @@ const getPoiGlyph = (poi: RenderPoi) => (
const shouldShowPoiInCurrentMode = (poi: RenderPoi) => {
const mode = getPoiDisplayMode()
const policy = getPoiPolicy(poi)
if (mode === 'core') {
return corePoiCategories.has(poi.primaryCategory)
}
if (mode === 'balanced') {
return corePoiCategories.has(poi.primaryCategory) || poi.primaryCategory === 'touring_poi'
}
if (!policy.markerVisible) return false
if (mode === 'core') return policy.allowOverview
if (mode === 'balanced') return policy.allowMulti
return true
}
@@ -1314,22 +1296,9 @@ const shouldShowPoiAtDistance = (poi: RenderPoi, tier: PoiVisibilityTier) => {
return true
}
if (activeView.value === 'floor' && isHallPoi(poi)) {
return true
}
if (tier === 'tight') {
return corePoiCategories.has(poi.primaryCategory) && !isTransportPoi(poi)
}
if (tier === 'balanced') {
return !isTransportPoi(poi) && (
corePoiCategories.has(poi.primaryCategory)
|| poi.primaryCategory === 'touring_poi'
)
}
return true
const policy = getPoiPolicy(poi)
return policy.markerVisible
&& isPoiVisibilityTierAtLeast(tier, policy.minMarkerTier)
}
const getPoiVisibilityLimit = (tier: PoiVisibilityTier) => {
@@ -1345,7 +1314,7 @@ const getPoiScreenSpacing = (tier: PoiVisibilityTier) => {
}
const getPoiPriority = (poi: RenderPoi) => {
const categoryPriority = poiCategoryPriority[poi.primaryCategory] || 20
const categoryPriority = getPoiPolicy(poi).priority
const selectedBoost = poi.id === activeFocusPoiId.value ? 1000 : 0
const hallBoost = activeView.value === 'floor' && isHallPoi(poi) ? 40 : 0
const transportPenalty = isTransportPoi(poi) ? 18 : 0
@@ -1364,8 +1333,7 @@ const getPoiLabelDensityTier = (): PoiVisibilityTier => {
}
const shouldCreateAmbientPoiLabel = (poi: RenderPoi) => (
isHallPoi(poi)
|| isServiceFacilityPoi(poi)
getPoiPolicy(poi).labelVisible
)
const shouldShowAmbientPoiLabel = (
@@ -1375,11 +1343,9 @@ const shouldShowAmbientPoiLabel = (
) => {
if (!markerVisible || activeView.value !== 'floor') return false
if (poi.id === activeFocusPoiId.value || poi.primaryCategory === 'target_preview') return false
if (isHallPoi(poi)) return true
if (isTransportPoi(poi)) return false
if (isServiceFacilityPoi(poi)) return densityTier === 'full'
return false
const policy = getPoiPolicy(poi)
return policy.labelVisible
&& isPoiVisibilityTierAtLeast(densityTier, policy.minLabelTier)
}
const getPoiAmbientLabelPriority = (poi: RenderPoi) => {
@@ -1490,17 +1456,15 @@ const updateAmbientPoiLabels = () => {
return
}
const spacing = isHallPoi(poi) ? poiAmbientLabelHallSpacingPx : poiAmbientLabelServiceSpacingPx
const spacing = getPoiPolicy(poi).labelCollisionSpacing
const bounds = updatePoiDomLabelPosition(labelHandle)
if (!bounds) {
return
}
if (!bounds) return
const overlaps = acceptedBounds.some((acceptedBound) => domLabelBoundsOverlap(bounds, acceptedBound, spacing))
const overlaps = acceptedBounds.some((acceptedBound) => (
domLabelBoundsOverlap(bounds, acceptedBound, spacing)
))
setPoiDomLabelVisible(labelHandle, !overlaps)
if (!overlaps) {
acceptedBounds.push(bounds)
}
if (!overlaps) acceptedBounds.push(bounds)
})
}
@@ -4802,7 +4766,7 @@ const findLoadedPoi = (poiId: string) => (
const createPoiMarkerSprites = (poi: RenderPoi, markerSize: number) => {
const sprite = new THREE.Sprite(createPoiMaterial(poi))
const hitTarget = new THREE.Sprite(createPoiHitTargetMaterial())
const isCorePoi = corePoiCategories.has(poi.primaryCategory) || poi.primaryCategory === 'target_preview'
const isCorePoi = getPoiPolicy(poi).allowOverview || poi.primaryCategory === 'target_preview'
const hitTargetScale = markerSize * (isCorePoi ? poiHitTargetCoreScaleMultiplier : poiHitTargetScaleMultiplier)
sprite.userData.baseScale = markerSize