// constants.js - Global constants and configuration // Scene configuration export const CONFIG = { defaultCameraZ: 300, defaultViewZoom: 1.0, minZoom: 0.5, maxZoom: 5.0, earthRadius: 100, rotationSpeed: 0.0005, dragRotationFactorBase: 0.005, dragRotationZoomExponent: 1.8, dragRotationScaleMin: 0.12, dragRotationScaleMax: 1.65, }; export const ROTATION_MODE = { ROTATE: "rotate", CRUISE: "cruise", }; export const CRUISE_MODULES = { BGP: "bgp", NEWS: "news", }; export const DEFAULT_CRUISE_MODULES = [CRUISE_MODULES.BGP]; export const SATELLITE_DISPLAY_STYLES = { SELF_GLOW: "self_glow", GROUND_FOOTPRINT: "ground_footprint", }; export const DEFAULT_SATELLITE_DISPLAY_STYLE = SATELLITE_DISPLAY_STYLES.GROUND_FOOTPRINT; export const CRUISE_CONFIG = { dwellMs: 7_000, focusDurationMs: 1_400, pollIntervalMs: 15_000, maxPolledEvents: 200, cardAnchorXRatio: 0.68, cardAnchorYRatio: 0.24, }; export const CONNECTOR_CONFIG = { markerGapPx: 18, panelGapPx: 12, obstacleClearancePx: 8, }; export const HUD_CONFIG = { scaleReferenceWidth: 1920, scaleReferenceHeight: 1080, minScale: 0.7, maxScale: 1, brandLanguage: "zh", }; // Earth coordinate constants export const EARTH_CONFIG = { tilt: 23.5, // earth tilt angle (degrees) tiltRad: 23.5 * Math.PI / 180, // earth tilt angle (radians) // hangzhou coordinates chinaLat: 30.2741, chinaLon: 120.1552, chinaRotLon: 120.1552 - 270, // for rotation calculation (chinaLon - 270) // view reset coefficient latCoefficient: 0.5 }; export const CELESTIAL_CONFIG = { enabled: true, updateIntervalMs: 10_000, skyRadius: 2600, skyOpacity: 1, starMapUrl: "./assets/celestial/starmap_equatorial_4k.jpg", brightStarsUrl: "./assets/celestial/bright-stars.json", orientationEulerRad: { x: 0.46, y: 1.18, z: -0.08, }, followEarthRotation: { enabled: true, x: true, y: true, z: false, invertX: true, invertY: false, invertZ: false, }, sunDistance: 2150, moonDistance: 2050, sunScale: 78, moonScale: 38, sunHaloScale: 136, moonHaloScale: 62, brightStarDistance: 2350, brightStarMinMag: 2.1, brightStarMaxCount: 36, brightStarMinScale: 2.4, brightStarMaxScale: 6.8, brightStarOpacity: 0.88, sunLightDistance: 460, sunLightIntensity: 1.02, sunLightColor: 0xfff4df, backLightIntensity: 0.3, backLightColor: 0x2b4c78, inspectionLighting: { enabled: true, ambientIntensity: 0.64, ambientColor: 0x707070, keyLightIntensity: 0.92, keyLightColor: 0xfcfcfb, keyLightDistance: 380, keyLightOffset: { x: 0.42, y: 0.34, z: 0.84 }, backLightIntensity: 0.26, backLightColor: 0x8f96a0, backLightDistance: 260, backLightOffset: { x: -0.52, y: -0.1, z: -0.62 }, pointLightIntensity: 0.36, pointLightColor: 0xfafcff, pointLightDistance: 320, pointLightOffset: { x: 0.18, y: 0.52, z: 0.62 }, }, }; export const SCENE_LIGHT_CONFIG = { ambient: { color: 0x404060, intensity: 1, }, sun: { color: 0xffffff, intensity: 1.2, position: { x: 5, y: 3, z: 5 }, }, back: { color: 0x446688, intensity: 0.3, position: { x: -5, y: 0, z: -5 }, }, point: { color: 0xffffff, intensity: 0.4, position: { x: 10, y: 10, z: 10 }, }, }; export const TERRAIN_CONFIG = { enabled: true, tileSize: 256, baseZoom: 4, geometryWidthSegments: 320, geometryHeightSegments: 320, baseRadiusOffset: 0.16, exaggeration: 34, landRevealFadeMeters: 220, maxConcurrentRequests: 10, opacity: 0.68, color: 0x8aa884, emissive: 0x030704, specular: 0x344438, shininess: 16, urlTemplate: "/api/v1/visualization/terrain/terrarium/{z}/{x}/{y}.png", }; export const COUNTRY_BOUNDARY_CONFIG = { dataPath: "/earth/data/countries-admin0.min.geojson", lineAltitudeOffset: 0.115, hoverAltitudeOffset: 0.14, lineColor: 0x7fc7ff, lineOpacity: 0.58, lineRenderOrder: 2.2, dimmedLineOpacity: 0.18, hoverLineColor: 0xff3b1f, hoverLineOpacity: 1.0, hoverLineRenderOrder: 2.3, hoverGlowOpacity: 0.38, hoverGlowLineWidth: 3, hoverGlowRenderOrderOffset: 0.01, hoverGlowRadiusOffset: 0.04, tintAltitudeOffset: 0.04, tintColor: 0x0b1830, tintRenderOrder: 0.2, landColor: 0x080f1b, landOpacity: 1.0, landAltitudeOffset: 0.08, landRenderOrder: 0.86, landMaskWidth: 2048, landMaskHeight: 1024, }; export const PATHS = { cablesApi: '/api/v1/visualization/geo/cables', landingPointsApi: '/api/v1/visualization/geo/landing-points', computeCentersApi: '/api/v1/visualization/geo/compute-centers', vesselsApi: '/api/v1/visualization/geo/vessels', vesselTrackApi: (mmsi) => `/api/v1/visualization/vessels/${encodeURIComponent(mmsi)}/track`, bgpApi: '/api/v1/visualization/geo/bgp-anomalies', bgpIncidentsApi: '/api/v1/visualization/geo/bgp-incidents', bgpCollectorsApi: '/api/v1/visualization/geo/bgp-collectors', earthSummaryApi: '/api/v1/visualization/geo/summary', earthClientLogsApi: '/api/v1/system/logs/earth-client', }; export const VESSEL_CONFIG = { altitudeOffset: 0.2, maxRenderedMarkers: 5000, marker: { baseScale: 7.5, baseOpacity: 0.88, hoverScale: 1.28, lockedScale: 1.48, dimmedScale: 0.78, dimmedOpacity: 0.26, }, colors: { cargo: "#4A90D9", tanker: "#E85D04", passenger: "#06D6A0", fishing: "#FFD166", military: "#73797E", other: "#9B9B9B", }, sizeStabilization: { min: 0.1, max: 2.4, }, track: { altitudeOffset: 0.2, color: 0x7dd3fc, opacity: 0.82, }, }; export const COMPUTE_CENTER_CONFIG = { altitudeOffset: 0.48, maxRenderedMarkers: 300, overlapSpread: { groupPrecision: 4, radius: 1.4, offsetStep: 0.28, }, marker: { baseOpacity: 0.88, supercomputerScale: 12, gpuClusterScale: 12, hoverScale: 1.16, lockedScale: 1.22, dimmedScale: 0.82, dimmedOpacity: 0.34, pulseSpeed: 0.0038, pulseAmplitude: 0.03, }, colors: { supercomputer: "#38bdf8", gpu_cluster: "#2dd4bf", linked: "#f8fafc", }, sizeStabilization: { enabled: true, min: 0.12, max: 3.0, }, }; // Cable colors mapping export const CABLE_COLORS = { 'Americas II': 0xff4444, 'AU Aleutian A': 0x44ff44, 'AU Aleutian B': 0x4444ff, 'default': 0xffff44 }; export const CABLE_CONFIG = { lockedOpacityMin: 0.2, lockedOpacityMax: 1.0, otherOpacity: 0.5, otherBrightness: 0.6, pulseSpeed: 0.008, pulseCoefficient: 0.4, line: { altitudeOffset: 0.2, greatCircleSegments: 50, nearPointThreshold: 0.01, lineWidth: 1, opacity: 1.0, renderOrder: 1, }, landingPoint: { altitudeOffset: 0.2, color: 0xffaa00, opacity: 1.0, renderOrder: 1, }, landingPointVisual: { pulseSpeed: 0.003, dimBrightness: 0.62, related: { opacityBase: 0.8, opacityPulse: 0.2, }, dimmed: { colorRGB: { r: 180, g: 116, b: 28 }, opacity: 0.78, }, }, }; export const CABLE_STATE = { NORMAL: 'normal', HOVERED: 'hovered', LOCKED: 'locked' }; export const SATELLITE_CONFIG = { maxCount: -1, initialLoadCount: null, hydrateFullAfterInitialLoad: false, trailLength: 10, trailLineWidth: 3, displayAltitudeOffset: 8, frontFacingDotThreshold: 0.015, overlayRenderOrder: 12, dotBaseSize: 2.8, dotBackdropScale: 1.28, dotZoomScalePower: 1, ringSize: 0.07, apiPath: '/api/v1/visualization/geo/satellites', breathingSpeed: 0.08, breathingScaleAmplitude: 0.15, breathingOpacityMin: 0.5, breathingOpacityMax: 0.8, dotBreathingSpeed: 0.12, dotBreathingScaleAmplitude: 0.2, dotOpacityMin: 0.7, dotOpacityMax: 1.0 }; export const BGP_CONFIG = { defaultFetchLimit: 200, maxRenderedMarkers: 200, altitudeOffset: 0.48, collectorAltitudeOffset: 0.2, marker: { eventBaseScale: 6.2, collectorBaseScale: 7.4, hoverScale: 1.16, dimmedScale: 0.92, collectorStatusCoreBaseScale: 0.12, collectorStatusCoreMinScale: 1.2, }, pulse: { eventSpeed: 0.0045, collectorSpeed: 0.0024, normalAmplitude: 0.03, lockedAmplitude: 0.16, }, regionScale: 11.5, opacity: { normal: 0.78, hover: 1.0, dimmed: 0.24, collector: 0.62, collectorHover: 0.9, lockedMin: 0.65, lockedMax: 1.0 }, severityColors: { critical: 0xff4d4f, high: 0xff9f43, medium: 0xffd166, low: 0x4dabf7 }, severityScales: { critical: 1.18, high: 1.08, medium: 1.0, low: 0.94 }, collectorColor: 0x6db7ff, collectorHeatColors: { idle: 0x6db7ff, low: 0x60a5fa, medium: 0xfbbf24, high: 0xfb923c, hot: 0xff5f57 }, collectorIcon: { ringStroke: "rgba(111, 160, 197, 0.34)", ringLineWidth: 1.2, ringRadius: 22, pathStroke: "rgba(64, 106, 136, 0.74)", pathLineWidth: 0.9, pathFill: "rgba(214,224,233,0.88)", centerFill: "rgba(222,231,239,0.72)", centerRadius: 0.85, idleBaseColor: 0xb7c4cf, idleBlend: 0.56, idleOpacity: 0.74, hoverBlend: 0.42, hoverNeutralColor: 0xc8d5e0, lockedBlend: 0.48, lockedNeutralColor: 0xd8e4ed, dimmedColor: 0x7d8ca3, }, regionColor: 0x2dd4bf, ring: { scaleA: 2.5, scaleB: 3.4, opacity: 0.5, speed: 0.001, }, halo: { collectorScale: 11.5, collectorPulseScale: 16.5, collectorCoverageScale: 22.5, }, sizeStabilization: { enabled: true, collectorMin: 0.12, collectorMax: 3.0, eventMin: 0.12, eventMax: 3.0, }, }; export const PREDICTED_ORBIT_CONFIG = { sampleInterval: 10, opacity: 0.8 }; export const GRID_CONFIG = { radiusOffset: 0.14, color: 0xc0e0ff, opacity: 0.08, lineWidth: 1, renderOrder: 2.05, latitudeStep: 15, longitudeStep: 30, segmentStep: 5, }; export const CLOUD_LAYER_CONFIG = { radiusOffset: 3, widthSegments: 64, heightSegments: 64, opacity: 0.15, textureUrl: "./assets/earth_clouds_1024.png", }; export const STARFIELD_CONFIG = { count: 8000, minRadius: 800, radiusJitter: 200, color: 0xffffff, size: 0.5, }; export const EARTH_MATERIAL_CONFIG = { // Base sphere sits below the country fill and high-res texture overlays. // Keep it dark so a delayed overlay never flashes or reads as a white layer. color: 0x010609, specular: 0x1a2d45, shininess: 12, emissive: 0x010609, opacity: 1, textureOverlayAltitudeOffset: 0.1, textureOverlayOpacity: 0.88, textureOverlayRenderOrder: 0.96, textureOverlaySpecular: 0x05080d, textureOverlayShininess: 4, // Depth-mask occluder keeps far-side objects hidden behind the earth occluderRadiusFactor: 0.999, occluderSegments: 48, // Fresnel atmosphere glow — inner rim atmosInnerRadiusFactor: 1.01, atmosInnerSegments: 64, atmosInnerColor: [0.25, 0.62, 1.0], atmosInnerRimPower: 3.2, atmosInnerIntensity: 0.18, // Fresnel atmosphere glow — outer corona atmosOuterRadiusFactor: 1.0025, atmosOuterSegments: 48, atmosOuterColor: [0.18, 0.45, 0.9], atmosOuterRimPower: 9.0, atmosOuterIntensity: 0.0025, // Subtle Fresnel edge cue shown when the high-res texture is hidden or unavailable. rimGlowColor: [0.42, 0.72, 1.0], rimGlowRadiusFactor: 1.0035, rimGlowPower: 3.4, rimGlowIntensity: 0.24, rimGlowSegments: 96, rimGlowRenderOrder: 1.08, // Texture candidates — tried in order, first success wins textureUrls: [ './assets/8k_earth_daymap.jpg', 'https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/textures/planets/earth_atmos_2048.jpg', 'https://threejs.org/examples/textures/planets/earth_atmos_2048.jpg', ], dayNight: { enabled: true, sunDirection: { x: 1, y: 0.2, z: 0.4 }, nightFloor: 0.24, dayBoost: 1.12, twilightWidth: 0.2, twilightIntensity: 0.14, twilightColor: 0x4ea0ff, nightTintColor: 0x0b1830, nightTintIntensity: 0.08, }, };