@@ -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
|
||||
|
||||
Reference in New Issue
Block a user