优化指北针持续追踪手感
This commit is contained in:
@@ -57,6 +57,8 @@ const AUTO_ROTATE_SNAP_DEG = 0.1
|
|||||||
const AUTO_ROTATE_DEADZONE_DEG = 4
|
const AUTO_ROTATE_DEADZONE_DEG = 4
|
||||||
const AUTO_ROTATE_MAX_STEP_DEG = 0.75
|
const AUTO_ROTATE_MAX_STEP_DEG = 0.75
|
||||||
const AUTO_ROTATE_HEADING_SMOOTHING = 0.46
|
const AUTO_ROTATE_HEADING_SMOOTHING = 0.46
|
||||||
|
const COMPASS_NEEDLE_FRAME_MS = 16
|
||||||
|
const COMPASS_NEEDLE_SNAP_DEG = 0.08
|
||||||
const COMPASS_TUNING_PRESETS: Record<CompassTuningProfile, {
|
const COMPASS_TUNING_PRESETS: Record<CompassTuningProfile, {
|
||||||
needleMinSmoothing: number
|
needleMinSmoothing: number
|
||||||
needleMaxSmoothing: number
|
needleMaxSmoothing: number
|
||||||
@@ -827,6 +829,7 @@ export class MapEngine {
|
|||||||
previewResetTimer: number
|
previewResetTimer: number
|
||||||
viewSyncTimer: number
|
viewSyncTimer: number
|
||||||
autoRotateTimer: number
|
autoRotateTimer: number
|
||||||
|
compassNeedleTimer: number
|
||||||
pendingViewPatch: Partial<MapEngineViewState>
|
pendingViewPatch: Partial<MapEngineViewState>
|
||||||
mounted: boolean
|
mounted: boolean
|
||||||
diagnosticUiEnabled: boolean
|
diagnosticUiEnabled: boolean
|
||||||
@@ -834,6 +837,7 @@ export class MapEngine {
|
|||||||
sensorHeadingDeg: number | null
|
sensorHeadingDeg: number | null
|
||||||
smoothedSensorHeadingDeg: number | null
|
smoothedSensorHeadingDeg: number | null
|
||||||
compassDisplayHeadingDeg: number | null
|
compassDisplayHeadingDeg: number | null
|
||||||
|
targetCompassDisplayHeadingDeg: number | null
|
||||||
compassSource: 'compass' | 'motion' | null
|
compassSource: 'compass' | 'motion' | null
|
||||||
compassTuningProfile: CompassTuningProfile
|
compassTuningProfile: CompassTuningProfile
|
||||||
smoothedMovementHeadingDeg: number | null
|
smoothedMovementHeadingDeg: number | null
|
||||||
@@ -1277,6 +1281,7 @@ export class MapEngine {
|
|||||||
this.previewResetTimer = 0
|
this.previewResetTimer = 0
|
||||||
this.viewSyncTimer = 0
|
this.viewSyncTimer = 0
|
||||||
this.autoRotateTimer = 0
|
this.autoRotateTimer = 0
|
||||||
|
this.compassNeedleTimer = 0
|
||||||
this.pendingViewPatch = {}
|
this.pendingViewPatch = {}
|
||||||
this.mounted = false
|
this.mounted = false
|
||||||
this.diagnosticUiEnabled = false
|
this.diagnosticUiEnabled = false
|
||||||
@@ -1284,6 +1289,7 @@ export class MapEngine {
|
|||||||
this.sensorHeadingDeg = null
|
this.sensorHeadingDeg = null
|
||||||
this.smoothedSensorHeadingDeg = null
|
this.smoothedSensorHeadingDeg = null
|
||||||
this.compassDisplayHeadingDeg = null
|
this.compassDisplayHeadingDeg = null
|
||||||
|
this.targetCompassDisplayHeadingDeg = null
|
||||||
this.compassSource = null
|
this.compassSource = null
|
||||||
this.compassTuningProfile = 'balanced'
|
this.compassTuningProfile = 'balanced'
|
||||||
this.smoothedMovementHeadingDeg = null
|
this.smoothedMovementHeadingDeg = null
|
||||||
@@ -1399,6 +1405,7 @@ export class MapEngine {
|
|||||||
this.clearPreviewResetTimer()
|
this.clearPreviewResetTimer()
|
||||||
this.clearViewSyncTimer()
|
this.clearViewSyncTimer()
|
||||||
this.clearAutoRotateTimer()
|
this.clearAutoRotateTimer()
|
||||||
|
this.clearCompassNeedleTimer()
|
||||||
this.clearPunchFeedbackTimer()
|
this.clearPunchFeedbackTimer()
|
||||||
this.clearContentCardTimer()
|
this.clearContentCardTimer()
|
||||||
this.clearMapPulseTimer()
|
this.clearMapPulseTimer()
|
||||||
@@ -2940,27 +2947,19 @@ export class MapEngine {
|
|||||||
const compassHeadingDeg = getCompassReferenceHeadingDeg(this.northReferenceMode, this.smoothedSensorHeadingDeg)
|
const compassHeadingDeg = getCompassReferenceHeadingDeg(this.northReferenceMode, this.smoothedSensorHeadingDeg)
|
||||||
if (this.compassDisplayHeadingDeg === null) {
|
if (this.compassDisplayHeadingDeg === null) {
|
||||||
this.compassDisplayHeadingDeg = compassHeadingDeg
|
this.compassDisplayHeadingDeg = compassHeadingDeg
|
||||||
|
this.targetCompassDisplayHeadingDeg = compassHeadingDeg
|
||||||
|
this.syncCompassDisplayState()
|
||||||
} else {
|
} else {
|
||||||
|
this.targetCompassDisplayHeadingDeg = compassHeadingDeg
|
||||||
const displayDeltaDeg = Math.abs(normalizeAngleDeltaDeg(compassHeadingDeg - this.compassDisplayHeadingDeg))
|
const displayDeltaDeg = Math.abs(normalizeAngleDeltaDeg(compassHeadingDeg - this.compassDisplayHeadingDeg))
|
||||||
if (displayDeltaDeg >= COMPASS_TUNING_PRESETS[this.compassTuningProfile].displayDeadzoneDeg) {
|
if (displayDeltaDeg >= COMPASS_TUNING_PRESETS[this.compassTuningProfile].displayDeadzoneDeg) {
|
||||||
this.compassDisplayHeadingDeg = interpolateAngleDeg(
|
this.scheduleCompassNeedleFollow()
|
||||||
this.compassDisplayHeadingDeg,
|
|
||||||
compassHeadingDeg,
|
|
||||||
getCompassNeedleSmoothingFactor(
|
|
||||||
this.compassDisplayHeadingDeg,
|
|
||||||
compassHeadingDeg,
|
|
||||||
this.compassTuningProfile,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.autoRotateHeadingDeg = this.resolveAutoRotateInputHeadingDeg()
|
this.autoRotateHeadingDeg = this.resolveAutoRotateInputHeadingDeg()
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
compassNeedleDeg: formatCompassNeedleDegForMode(this.northReferenceMode, this.compassDisplayHeadingDeg),
|
compassSourceText: formatCompassSourceText(this.compassSource),
|
||||||
sensorHeadingText: formatHeadingText(this.compassDisplayHeadingDeg),
|
|
||||||
compassDeclinationText: formatCompassDeclinationText(this.northReferenceMode),
|
|
||||||
...(this.diagnosticUiEnabled
|
...(this.diagnosticUiEnabled
|
||||||
? {
|
? {
|
||||||
...this.getTelemetrySensorViewPatch(),
|
...this.getTelemetrySensorViewPatch(),
|
||||||
@@ -2986,9 +2985,11 @@ export class MapEngine {
|
|||||||
|
|
||||||
handleCompassError(message: string): void {
|
handleCompassError(message: string): void {
|
||||||
this.clearAutoRotateTimer()
|
this.clearAutoRotateTimer()
|
||||||
|
this.clearCompassNeedleTimer()
|
||||||
this.targetAutoRotationDeg = null
|
this.targetAutoRotationDeg = null
|
||||||
this.autoRotateCalibrationPending = false
|
this.autoRotateCalibrationPending = false
|
||||||
this.compassSource = null
|
this.compassSource = null
|
||||||
|
this.targetCompassDisplayHeadingDeg = null
|
||||||
this.setState({
|
this.setState({
|
||||||
compassSourceText: formatCompassSourceText(null),
|
compassSourceText: formatCompassSourceText(null),
|
||||||
autoRotateCalibrationText: formatAutoRotateCalibrationText(false, this.autoRotateCalibrationOffsetDeg),
|
autoRotateCalibrationText: formatAutoRotateCalibrationText(false, this.autoRotateCalibrationOffsetDeg),
|
||||||
@@ -3013,6 +3014,7 @@ export class MapEngine {
|
|||||||
this.northReferenceMode = nextMode
|
this.northReferenceMode = nextMode
|
||||||
this.autoRotateCalibrationOffsetDeg = nextMapNorthOffsetDeg
|
this.autoRotateCalibrationOffsetDeg = nextMapNorthOffsetDeg
|
||||||
this.compassDisplayHeadingDeg = compassHeadingDeg
|
this.compassDisplayHeadingDeg = compassHeadingDeg
|
||||||
|
this.targetCompassDisplayHeadingDeg = compassHeadingDeg
|
||||||
|
|
||||||
if (this.state.orientationMode === 'north-up') {
|
if (this.state.orientationMode === 'north-up') {
|
||||||
const exactCenter = this.getExactCenterFromTranslate(this.state.tileTranslateX, this.state.tileTranslateY)
|
const exactCenter = this.getExactCenterFromTranslate(this.state.tileTranslateX, this.state.tileTranslateY)
|
||||||
@@ -3056,6 +3058,10 @@ export class MapEngine {
|
|||||||
if (this.state.orientationMode === 'heading-up' && this.refreshAutoRotateTarget()) {
|
if (this.state.orientationMode === 'heading-up' && this.refreshAutoRotateTarget()) {
|
||||||
this.scheduleAutoRotate()
|
this.scheduleAutoRotate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.compassDisplayHeadingDeg !== null) {
|
||||||
|
this.syncCompassDisplayState()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setCourseHeading(headingDeg: number | null): void {
|
setCourseHeading(headingDeg: number | null): void {
|
||||||
@@ -3570,6 +3576,78 @@ export class MapEngine {
|
|||||||
this.autoRotateTimer = 0
|
this.autoRotateTimer = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clearCompassNeedleTimer(): void {
|
||||||
|
if (this.compassNeedleTimer) {
|
||||||
|
clearTimeout(this.compassNeedleTimer)
|
||||||
|
this.compassNeedleTimer = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
syncCompassDisplayState(): void {
|
||||||
|
this.setState({
|
||||||
|
compassNeedleDeg: formatCompassNeedleDegForMode(this.northReferenceMode, this.compassDisplayHeadingDeg),
|
||||||
|
sensorHeadingText: formatHeadingText(this.compassDisplayHeadingDeg),
|
||||||
|
compassDeclinationText: formatCompassDeclinationText(this.northReferenceMode),
|
||||||
|
...(this.diagnosticUiEnabled
|
||||||
|
? {
|
||||||
|
...this.getTelemetrySensorViewPatch(),
|
||||||
|
northReferenceButtonText: formatNorthReferenceButtonText(this.northReferenceMode),
|
||||||
|
autoRotateSourceText: this.getAutoRotateSourceText(),
|
||||||
|
northReferenceText: formatNorthReferenceText(this.northReferenceMode),
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
scheduleCompassNeedleFollow(): void {
|
||||||
|
if (
|
||||||
|
this.compassNeedleTimer
|
||||||
|
|| this.targetCompassDisplayHeadingDeg === null
|
||||||
|
|| this.compassDisplayHeadingDeg === null
|
||||||
|
) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const step = () => {
|
||||||
|
this.compassNeedleTimer = 0
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.targetCompassDisplayHeadingDeg === null
|
||||||
|
|| this.compassDisplayHeadingDeg === null
|
||||||
|
) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const deltaDeg = normalizeAngleDeltaDeg(
|
||||||
|
this.targetCompassDisplayHeadingDeg - this.compassDisplayHeadingDeg,
|
||||||
|
)
|
||||||
|
const absDeltaDeg = Math.abs(deltaDeg)
|
||||||
|
|
||||||
|
if (absDeltaDeg <= COMPASS_NEEDLE_SNAP_DEG) {
|
||||||
|
if (absDeltaDeg > 0.001) {
|
||||||
|
this.compassDisplayHeadingDeg = this.targetCompassDisplayHeadingDeg
|
||||||
|
this.syncCompassDisplayState()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.compassDisplayHeadingDeg = interpolateAngleDeg(
|
||||||
|
this.compassDisplayHeadingDeg,
|
||||||
|
this.targetCompassDisplayHeadingDeg,
|
||||||
|
getCompassNeedleSmoothingFactor(
|
||||||
|
this.compassDisplayHeadingDeg,
|
||||||
|
this.targetCompassDisplayHeadingDeg,
|
||||||
|
this.compassTuningProfile,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
this.syncCompassDisplayState()
|
||||||
|
this.scheduleCompassNeedleFollow()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.compassNeedleTimer = setTimeout(step, COMPASS_NEEDLE_FRAME_MS) as unknown as number
|
||||||
|
}
|
||||||
|
|
||||||
pickViewPatch(patch: Partial<MapEngineViewState>): Partial<MapEngineViewState> {
|
pickViewPatch(patch: Partial<MapEngineViewState>): Partial<MapEngineViewState> {
|
||||||
const viewPatch = {} as Partial<MapEngineViewState>
|
const viewPatch = {} as Partial<MapEngineViewState>
|
||||||
for (const key of VIEW_SYNC_KEYS) {
|
for (const key of VIEW_SYNC_KEYS) {
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ type MapPageData = MapEngineViewState & {
|
|||||||
showRightButtonGroups: boolean
|
showRightButtonGroups: boolean
|
||||||
showBottomDebugButton: boolean
|
showBottomDebugButton: boolean
|
||||||
}
|
}
|
||||||
const INTERNAL_BUILD_VERSION = 'map-build-282'
|
const INTERNAL_BUILD_VERSION = 'map-build-283'
|
||||||
const USER_SETTINGS_STORAGE_KEY = 'cmr_user_settings_v1'
|
const USER_SETTINGS_STORAGE_KEY = 'cmr_user_settings_v1'
|
||||||
const CLASSIC_REMOTE_GAME_CONFIG_URL = 'https://oss-mbh5.colormaprun.com/gotomars/event/classic-sequential.json'
|
const CLASSIC_REMOTE_GAME_CONFIG_URL = 'https://oss-mbh5.colormaprun.com/gotomars/event/classic-sequential.json'
|
||||||
const SCORE_O_REMOTE_GAME_CONFIG_URL = 'https://oss-mbh5.colormaprun.com/gotomars/event/score-o.json'
|
const SCORE_O_REMOTE_GAME_CONFIG_URL = 'https://oss-mbh5.colormaprun.com/gotomars/event/score-o.json'
|
||||||
|
|||||||
Reference in New Issue
Block a user