fix(earth-bgp): consolidate visual constants and bump version to 0.22.12
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "planet-frontend",
|
||||
"version": "0.22.11",
|
||||
"version": "0.22.12",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^5.2.6",
|
||||
|
||||
@@ -277,13 +277,39 @@ function blendHexColors(fromHex, toHex, ratio) {
|
||||
}
|
||||
|
||||
function getCollectorDistanceScale(marker, camera) {
|
||||
if (!marker || !camera) return 1;
|
||||
if (!marker || !camera || BGP_CONFIG.sizeStabilization?.enabled === false) return 1;
|
||||
|
||||
marker.getWorldPosition(collectorWorldPosition);
|
||||
const distanceToCamera = camera.position.distanceTo(collectorWorldPosition);
|
||||
const referenceDistance = CONFIG.defaultCameraZ - CONFIG.earthRadius + BGP_CONFIG.collectorAltitudeOffset;
|
||||
const referenceFovRad = (75 * Math.PI) / 180;
|
||||
const cameraFovRad = ((camera.fov || 75) * Math.PI) / 180;
|
||||
const min = Number(BGP_CONFIG.sizeStabilization?.collectorMin ?? 0.6);
|
||||
const max = Number(BGP_CONFIG.sizeStabilization?.collectorMax ?? 1.9);
|
||||
const worldPerPixel =
|
||||
distanceToCamera * Math.tan(cameraFovRad / 2);
|
||||
const referenceWorldPerPixel =
|
||||
referenceDistance * Math.tan(referenceFovRad / 2);
|
||||
|
||||
return clamp(distanceToCamera / referenceDistance, 0.6, 1.9);
|
||||
return clamp(worldPerPixel / referenceWorldPerPixel, min, max);
|
||||
}
|
||||
|
||||
function getEventDistanceScale(marker, camera) {
|
||||
if (!marker || !camera || BGP_CONFIG.sizeStabilization?.enabled === false) return 1;
|
||||
|
||||
marker.getWorldPosition(collectorWorldPosition);
|
||||
const distanceToCamera = camera.position.distanceTo(collectorWorldPosition);
|
||||
const referenceDistance = CONFIG.defaultCameraZ - CONFIG.earthRadius + BGP_CONFIG.altitudeOffset;
|
||||
const referenceFovRad = (75 * Math.PI) / 180;
|
||||
const cameraFovRad = ((camera.fov || 75) * Math.PI) / 180;
|
||||
const min = Number(BGP_CONFIG.sizeStabilization?.eventMin ?? 0.7);
|
||||
const max = Number(BGP_CONFIG.sizeStabilization?.eventMax ?? 1.9);
|
||||
const worldPerPixel =
|
||||
distanceToCamera * Math.tan(cameraFovRad / 2);
|
||||
const referenceWorldPerPixel =
|
||||
referenceDistance * Math.tan(referenceFovRad / 2);
|
||||
|
||||
return clamp(worldPerPixel / referenceWorldPerPixel, min, max);
|
||||
}
|
||||
|
||||
function orientCollectorMarkerToSurface(marker, position) {
|
||||
@@ -332,13 +358,13 @@ function getCollectorActivityProfile(markerData) {
|
||||
|
||||
const scaleBoost = clamp(1 + Math.log2(activityScore + 1) * 0.12, 1, 1.55);
|
||||
const haloScale =
|
||||
BGP_CONFIG.collectorHaloScale +
|
||||
BGP_CONFIG.halo.collectorScale +
|
||||
clamp(Math.log2(recent24h + prefixes + 1) * 2.2, 0, 12);
|
||||
const pulseHaloScale =
|
||||
BGP_CONFIG.collectorPulseHaloScale +
|
||||
BGP_CONFIG.halo.collectorPulseScale +
|
||||
clamp(Math.log2(recent24h + recent7d + 1) * 2.8, 0, 14);
|
||||
const coverageHaloScale =
|
||||
BGP_CONFIG.collectorCoverageHaloScale +
|
||||
BGP_CONFIG.halo.collectorCoverageScale +
|
||||
clamp(Math.log2(prefixes + origins + 1) * 3.4, 0, 18);
|
||||
|
||||
return {
|
||||
@@ -994,7 +1020,7 @@ function createCollectorMarker(markerData) {
|
||||
);
|
||||
|
||||
marker.position.copy(position);
|
||||
marker.scale.set(BGP_CONFIG.collectorScale * 0.88 * activity.scaleBoost, BGP_CONFIG.collectorScale * 1.08 * activity.scaleBoost, 1);
|
||||
marker.scale.set(BGP_CONFIG.marker.collectorBaseScale * 0.88 * activity.scaleBoost, BGP_CONFIG.marker.collectorBaseScale * 1.08 * activity.scaleBoost, 1);
|
||||
marker.renderOrder = 3;
|
||||
marker.visible = showBGP;
|
||||
orientCollectorMarkerToSurface(marker, position);
|
||||
@@ -1018,7 +1044,11 @@ function createCollectorMarker(markerData) {
|
||||
const statusCore = createOverlaySprite({
|
||||
color: activity.color,
|
||||
opacity: 0.0,
|
||||
scale: Math.max(BGP_CONFIG.collectorScale * 0.12, 1.2),
|
||||
scale: Math.max(
|
||||
BGP_CONFIG.marker.collectorBaseScale *
|
||||
BGP_CONFIG.marker.collectorStatusCoreBaseScale,
|
||||
BGP_CONFIG.marker.collectorStatusCoreMinScale,
|
||||
),
|
||||
});
|
||||
statusCore.position.set(0, 0, 0.02);
|
||||
statusCore.renderOrder = 4;
|
||||
@@ -1036,7 +1066,7 @@ function createCollectorMarker(markerData) {
|
||||
marker.userData = {
|
||||
type: "bgp_collector",
|
||||
state: "normal",
|
||||
baseScale: BGP_CONFIG.collectorScale * activity.scaleBoost,
|
||||
baseScale: BGP_CONFIG.marker.collectorBaseScale * activity.scaleBoost,
|
||||
baseColor,
|
||||
idleColor,
|
||||
pulseOffset: Math.random() * Math.PI * 2,
|
||||
@@ -1072,7 +1102,7 @@ function createAnomalyMarker(markerData) {
|
||||
CONFIG.earthRadius + BGP_CONFIG.altitudeOffset,
|
||||
);
|
||||
|
||||
const baseScale = BGP_CONFIG.baseScale * getSeverityScale(markerData.severity);
|
||||
const baseScale = BGP_CONFIG.marker.eventBaseScale * getSeverityScale(markerData.severity);
|
||||
sprite.position.copy(position);
|
||||
sprite.scale.setScalar(baseScale);
|
||||
sprite.renderOrder = 5;
|
||||
@@ -1097,7 +1127,7 @@ function createAnomalyMarker(markerData) {
|
||||
blending: THREE.AdditiveBlending,
|
||||
}),
|
||||
);
|
||||
ringA.scale.setScalar(baseScale * BGP_CONFIG.eventRingScaleA);
|
||||
ringA.scale.setScalar(baseScale * BGP_CONFIG.ring.scaleA);
|
||||
ringA.position.set(0, 0, -0.01);
|
||||
sprite.add(ringA);
|
||||
|
||||
@@ -1112,7 +1142,7 @@ function createAnomalyMarker(markerData) {
|
||||
blending: THREE.AdditiveBlending,
|
||||
}),
|
||||
);
|
||||
ringB.scale.setScalar(baseScale * BGP_CONFIG.eventRingScaleB);
|
||||
ringB.scale.setScalar(baseScale * BGP_CONFIG.ring.scaleB);
|
||||
ringB.position.set(0, 0, -0.02);
|
||||
sprite.add(ringB);
|
||||
|
||||
@@ -1338,7 +1368,7 @@ export function updateBGPVisualState(lockedObjectType, lockedObject, camera) {
|
||||
0.5 +
|
||||
0.5 *
|
||||
Math.sin(
|
||||
now * BGP_CONFIG.collectorPulseSpeed + marker.userData.pulseOffset,
|
||||
now * BGP_CONFIG.pulse.collectorSpeed + marker.userData.pulseOffset,
|
||||
);
|
||||
|
||||
let scale = marker.userData.baseScale * getCollectorDistanceScale(marker, camera);
|
||||
@@ -1411,7 +1441,11 @@ export function updateBGPVisualState(lockedObjectType, lockedObject, camera) {
|
||||
isLocked ? 0.58 : isHovered ? 0.4 : hasLockedLayer ? 0.0 : 0.18;
|
||||
marker.userData.statusCore.material.color.setHex(marker.userData.baseColor || BGP_CONFIG.collectorColor);
|
||||
marker.userData.statusCore.scale.setScalar(
|
||||
Math.max(BGP_CONFIG.collectorScale * 0.12, 1.2) * (isLocked ? 1.08 : isHovered ? 1.04 : 0.92),
|
||||
Math.max(
|
||||
BGP_CONFIG.marker.collectorBaseScale *
|
||||
BGP_CONFIG.marker.collectorStatusCoreBaseScale,
|
||||
BGP_CONFIG.marker.collectorStatusCoreMinScale,
|
||||
) * (isLocked ? 1.08 : isHovered ? 1.04 : 0.92),
|
||||
);
|
||||
}
|
||||
if (marker.userData.coverageHalo) {
|
||||
@@ -1433,33 +1467,35 @@ export function updateBGPVisualState(lockedObjectType, lockedObject, camera) {
|
||||
const isHovered = marker.userData.state === "hover";
|
||||
const pulse =
|
||||
0.5 +
|
||||
0.5 * Math.sin(now * BGP_CONFIG.pulseSpeed + marker.userData.pulseOffset);
|
||||
0.5 * Math.sin(now * BGP_CONFIG.pulse.eventSpeed + marker.userData.pulseOffset);
|
||||
|
||||
let scale = marker.userData.baseScale;
|
||||
const iconAnchorScale =
|
||||
marker.userData.baseScale * getEventDistanceScale(marker, camera);
|
||||
let scale = iconAnchorScale;
|
||||
let opacity = BGP_CONFIG.opacity.normal;
|
||||
let markerColor = marker.userData.baseColor || getSeverityColor(marker.userData.severity);
|
||||
const isIncidentMarker = marker.userData.source === "bgp_incident";
|
||||
let ringBaseOpacity = isIncidentMarker
|
||||
? BGP_CONFIG.eventRingOpacity
|
||||
: BGP_CONFIG.eventRingOpacity * 0.45;
|
||||
? BGP_CONFIG.ring.opacity
|
||||
: BGP_CONFIG.ring.opacity * 0.45;
|
||||
|
||||
if (isLocked || isLinkedCollectorLocked) {
|
||||
scale *= 1 + BGP_CONFIG.lockedPulseAmplitude * pulse;
|
||||
scale *= 1 + BGP_CONFIG.pulse.lockedAmplitude * pulse;
|
||||
opacity =
|
||||
BGP_CONFIG.opacity.lockedMin +
|
||||
(BGP_CONFIG.opacity.lockedMax - BGP_CONFIG.opacity.lockedMin) * pulse;
|
||||
ringBaseOpacity *= 1.2;
|
||||
} else if (isHovered) {
|
||||
scale *= BGP_CONFIG.hoverScale;
|
||||
scale *= BGP_CONFIG.marker.hoverScale;
|
||||
opacity = BGP_CONFIG.opacity.hover;
|
||||
ringBaseOpacity *= 1.05;
|
||||
} else if (isOtherLocked) {
|
||||
scale *= BGP_CONFIG.dimmedScale;
|
||||
scale *= BGP_CONFIG.marker.dimmedScale;
|
||||
opacity = 0.1;
|
||||
markerColor = 0x7d8ca3;
|
||||
ringBaseOpacity = 0.02;
|
||||
} else {
|
||||
scale *= 1 + BGP_CONFIG.normalPulseAmplitude * pulse;
|
||||
scale *= 1 + BGP_CONFIG.pulse.normalAmplitude * pulse;
|
||||
opacity = isIncidentMarker ? 0.7 : 0.62;
|
||||
}
|
||||
|
||||
@@ -1468,13 +1504,13 @@ export function updateBGPVisualState(lockedObjectType, lockedObject, camera) {
|
||||
marker.material.opacity = opacity;
|
||||
marker.visible = showBGP;
|
||||
|
||||
const ringPhaseA = (now * BGP_CONFIG.eventRingSpeed + marker.userData.pulseOffset) % 1;
|
||||
const ringPhaseA = (now * BGP_CONFIG.ring.speed + marker.userData.pulseOffset) % 1;
|
||||
const applyRingState = (ring, phase, maxScale) => {
|
||||
if (!ring) return;
|
||||
const progress = Math.max(0, Math.min(1, phase));
|
||||
const minScale = 1.28;
|
||||
const desiredWorldScale =
|
||||
marker.userData.baseScale * (minScale + progress * (maxScale - minScale));
|
||||
iconAnchorScale * (minScale + progress * (maxScale - minScale));
|
||||
const parentScale = Math.max(scale, 0.0001);
|
||||
const localRingScale = desiredWorldScale / parentScale;
|
||||
const fadeIn = Math.max(0, Math.min(1, (progress - 0.08) / 0.14));
|
||||
@@ -1486,7 +1522,7 @@ export function updateBGPVisualState(lockedObjectType, lockedObject, camera) {
|
||||
ring.visible = showBGP;
|
||||
};
|
||||
|
||||
applyRingState(marker.userData.ringA, ringPhaseA, BGP_CONFIG.eventRingScaleA);
|
||||
applyRingState(marker.userData.ringA, ringPhaseA, BGP_CONFIG.ring.scaleA);
|
||||
if (marker.userData.ringB) {
|
||||
marker.userData.ringB.material.opacity = 0;
|
||||
marker.userData.ringB.visible = false;
|
||||
|
||||
@@ -2,7 +2,13 @@
|
||||
|
||||
import * as THREE from "three";
|
||||
|
||||
import { CONFIG, CABLE_COLORS, PATHS, CABLE_STATE } from "./constants.js";
|
||||
import {
|
||||
CONFIG,
|
||||
CABLE_COLORS,
|
||||
PATHS,
|
||||
CABLE_STATE,
|
||||
CABLE_CONFIG,
|
||||
} from "./constants.js";
|
||||
import { latLonToVector3 } from "./utils.js";
|
||||
import { updateEarthStats, showStatusMessage } from "./ui.js";
|
||||
import { showInfoCard } from "./info-card.js";
|
||||
@@ -14,6 +20,37 @@ export let lockedCable = null;
|
||||
let cableIdMap = new Map();
|
||||
let cableStates = new Map();
|
||||
let cablesVisible = true;
|
||||
const landingPointWorldPosition = new THREE.Vector3();
|
||||
|
||||
function clamp(value, min, max) {
|
||||
return Math.min(max, Math.max(min, value));
|
||||
}
|
||||
|
||||
function getLandingPointDistanceScale(point, camera) {
|
||||
if (
|
||||
!point ||
|
||||
!camera ||
|
||||
CABLE_CONFIG.landingPointSizeStabilization?.enabled === false
|
||||
) return 1;
|
||||
point.getWorldPosition(landingPointWorldPosition);
|
||||
const distanceToCamera = camera.position.distanceTo(landingPointWorldPosition);
|
||||
const referenceDistance =
|
||||
CONFIG.defaultCameraZ -
|
||||
CONFIG.earthRadius +
|
||||
CABLE_CONFIG.landingPoint.altitudeOffset;
|
||||
const referenceFovDeg =
|
||||
CABLE_CONFIG.landingPointSizeStabilization?.referenceFov || 75;
|
||||
const referenceFovRad = (referenceFovDeg * Math.PI) / 180;
|
||||
const cameraFovRad =
|
||||
(((camera.fov || referenceFovDeg)) * Math.PI) / 180;
|
||||
const worldPerPixel = distanceToCamera * Math.tan(cameraFovRad / 2);
|
||||
const referenceWorldPerPixel = referenceDistance * Math.tan(referenceFovRad / 2);
|
||||
return clamp(
|
||||
worldPerPixel / referenceWorldPerPixel,
|
||||
CABLE_CONFIG.landingPointSizeStabilization?.min ?? 0.12,
|
||||
CABLE_CONFIG.landingPointSizeStabilization?.max ?? 3.0,
|
||||
);
|
||||
}
|
||||
|
||||
function disposeMaterial(material) {
|
||||
if (!material) return;
|
||||
@@ -83,9 +120,9 @@ function createCableLine(points, color, properties) {
|
||||
|
||||
const lineMaterial = new THREE.LineBasicMaterial({
|
||||
color,
|
||||
linewidth: 1,
|
||||
linewidth: CABLE_CONFIG.line.lineWidth,
|
||||
transparent: true,
|
||||
opacity: 1.0,
|
||||
opacity: CABLE_CONFIG.line.opacity,
|
||||
depthTest: true,
|
||||
depthWrite: true,
|
||||
});
|
||||
@@ -115,7 +152,7 @@ function createCableLine(points, color, properties) {
|
||||
localCenter:
|
||||
lineGeometry.boundingSphere?.center?.clone() || new THREE.Vector3(),
|
||||
};
|
||||
cableLine.renderOrder = 1;
|
||||
cableLine.renderOrder = CABLE_CONFIG.line.renderOrder;
|
||||
|
||||
if (!cableIdMap.has(cableId)) {
|
||||
cableIdMap.set(cableId, []);
|
||||
@@ -149,7 +186,7 @@ function calculateGreatCirclePoints(
|
||||
|
||||
let delta = Math.acos(Math.max(-1, Math.min(1, cosDelta)));
|
||||
|
||||
if (delta < 0.01) {
|
||||
if (delta < CABLE_CONFIG.line.nearPointThreshold) {
|
||||
const p1 = latLonToVector3(lat1, lon1, radius);
|
||||
const p2 = latLonToVector3(lat2, lon2, radius);
|
||||
return [p1, p2];
|
||||
@@ -248,8 +285,8 @@ export async function loadGeoJSONFromPath(scene, earthObj) {
|
||||
lon1,
|
||||
lat2,
|
||||
lon2,
|
||||
CONFIG.earthRadius + 0.2,
|
||||
50,
|
||||
CONFIG.earthRadius + CABLE_CONFIG.line.altitudeOffset,
|
||||
CABLE_CONFIG.line.greatCircleSegments,
|
||||
);
|
||||
points.push(...(i === 0 ? segment : segment.slice(1)));
|
||||
}
|
||||
@@ -273,8 +310,8 @@ export async function loadGeoJSONFromPath(scene, earthObj) {
|
||||
lon1,
|
||||
lat2,
|
||||
lon2,
|
||||
CONFIG.earthRadius + 0.2,
|
||||
50,
|
||||
CONFIG.earthRadius + CABLE_CONFIG.line.altitudeOffset,
|
||||
CABLE_CONFIG.line.greatCircleSegments,
|
||||
);
|
||||
points.push(...(i === 0 ? segment : segment.slice(1)));
|
||||
}
|
||||
@@ -324,7 +361,11 @@ export async function loadLandingPoints(scene, earthObj) {
|
||||
|
||||
clearLandingPoints(earthObj);
|
||||
|
||||
const sphereGeometry = new THREE.SphereGeometry(0.4, 16, 16);
|
||||
const sphereGeometry = new THREE.SphereGeometry(
|
||||
CABLE_CONFIG.landingPoint.radius,
|
||||
CABLE_CONFIG.landingPoint.widthSegments,
|
||||
CABLE_CONFIG.landingPoint.heightSegments,
|
||||
);
|
||||
let validCount = 0;
|
||||
|
||||
try {
|
||||
@@ -345,7 +386,11 @@ export async function loadLandingPoints(scene, earthObj) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const position = latLonToVector3(lat, lon, CONFIG.earthRadius + 0.1);
|
||||
const position = latLonToVector3(
|
||||
lat,
|
||||
lon,
|
||||
CONFIG.earthRadius + CABLE_CONFIG.landingPoint.altitudeOffset,
|
||||
);
|
||||
if (
|
||||
Number.isNaN(position.x) ||
|
||||
Number.isNaN(position.y) ||
|
||||
@@ -357,11 +402,11 @@ export async function loadLandingPoints(scene, earthObj) {
|
||||
const sphere = new THREE.Mesh(
|
||||
sphereGeometry.clone(),
|
||||
new THREE.MeshStandardMaterial({
|
||||
color: 0xffaa00,
|
||||
emissive: 0x442200,
|
||||
emissiveIntensity: 0.5,
|
||||
color: CABLE_CONFIG.landingPoint.color,
|
||||
emissive: CABLE_CONFIG.landingPoint.emissive,
|
||||
emissiveIntensity: CABLE_CONFIG.landingPoint.emissiveIntensity,
|
||||
transparent: true,
|
||||
opacity: 1,
|
||||
opacity: CABLE_CONFIG.landingPoint.opacity,
|
||||
}),
|
||||
);
|
||||
sphere.position.copy(position);
|
||||
@@ -371,6 +416,7 @@ export async function loadLandingPoints(scene, earthObj) {
|
||||
cableNames: properties.cable_names || [],
|
||||
country: properties.country || "未知国家",
|
||||
status: properties.status || "Unknown",
|
||||
baseScale: CABLE_CONFIG.landingPoint.baseScale,
|
||||
};
|
||||
|
||||
earthObj.add(sphere);
|
||||
@@ -493,9 +539,10 @@ export function getAllLandingPoints() {
|
||||
return landingPoints;
|
||||
}
|
||||
|
||||
export function applyLandingPointVisualState(lockedCableName, dimAll = false) {
|
||||
const pulse = (Math.sin(Date.now() * 0.003) + 1) * 0.5;
|
||||
const brightness = 0.3;
|
||||
export function applyLandingPointVisualState(lockedCableName, dimAll = false, camera = null) {
|
||||
const pulse =
|
||||
(Math.sin(Date.now() * CABLE_CONFIG.landingPointVisual.pulseSpeed) + 1) * 0.5;
|
||||
const brightness = CABLE_CONFIG.landingPointVisual.dimBrightness;
|
||||
const relatedNames = Array.isArray(lockedCableName)
|
||||
? lockedCableName.filter(Boolean)
|
||||
: lockedCableName
|
||||
@@ -509,30 +556,48 @@ export function applyLandingPointVisualState(lockedCableName, dimAll = false) {
|
||||
lp.userData.cableNames.some((name) => relatedNames.includes(name));
|
||||
|
||||
if (isRelated) {
|
||||
lp.material.color.setHex(0xffaa00);
|
||||
lp.material.emissive.setHex(0x442200);
|
||||
lp.material.emissiveIntensity = 0.5 + pulse * 0.5;
|
||||
lp.material.opacity = 0.8 + pulse * 0.2;
|
||||
lp.scale.setScalar(1.2 + pulse * 0.3);
|
||||
lp.material.color.setHex(CABLE_CONFIG.landingPoint.color);
|
||||
lp.material.emissive.setHex(CABLE_CONFIG.landingPoint.emissive);
|
||||
lp.material.emissiveIntensity =
|
||||
CABLE_CONFIG.landingPointVisual.related.emissiveIntensityBase +
|
||||
pulse * CABLE_CONFIG.landingPointVisual.related.emissiveIntensityPulse;
|
||||
lp.material.opacity =
|
||||
CABLE_CONFIG.landingPointVisual.related.opacityBase +
|
||||
pulse * CABLE_CONFIG.landingPointVisual.related.opacityPulse;
|
||||
const distanceScale = getLandingPointDistanceScale(lp, camera);
|
||||
const baseScale = lp.userData?.baseScale || CABLE_CONFIG.landingPoint.baseScale;
|
||||
lp.scale.setScalar(
|
||||
(CABLE_CONFIG.landingPointVisual.related.scaleBase +
|
||||
pulse * CABLE_CONFIG.landingPointVisual.related.scalePulse) *
|
||||
baseScale *
|
||||
distanceScale,
|
||||
);
|
||||
} else {
|
||||
const r = 255 * brightness;
|
||||
const g = 170 * brightness;
|
||||
lp.material.color.setRGB(r / 255, g / 255, 0);
|
||||
lp.material.emissive.setHex(0x000000);
|
||||
lp.material.emissiveIntensity = 0;
|
||||
lp.material.opacity = 0.3;
|
||||
lp.scale.setScalar(1.0);
|
||||
const dimColor = CABLE_CONFIG.landingPointVisual.dimmed.colorRGB;
|
||||
const r = dimColor.r * brightness;
|
||||
const g = dimColor.g * brightness;
|
||||
const b = dimColor.b * brightness;
|
||||
lp.material.color.setRGB(r / 255, g / 255, b / 255);
|
||||
lp.material.emissive.setHex(CABLE_CONFIG.landingPointVisual.dimmed.emissive);
|
||||
lp.material.emissiveIntensity =
|
||||
CABLE_CONFIG.landingPointVisual.dimmed.emissiveIntensity;
|
||||
lp.material.opacity = CABLE_CONFIG.landingPointVisual.dimmed.opacity;
|
||||
const distanceScale = getLandingPointDistanceScale(lp, camera);
|
||||
const baseScale = lp.userData?.baseScale || CABLE_CONFIG.landingPoint.baseScale;
|
||||
lp.scale.setScalar(baseScale * distanceScale);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function resetLandingPointVisualState() {
|
||||
export function resetLandingPointVisualState(camera = null) {
|
||||
landingPoints.forEach((lp) => {
|
||||
lp.material.color.setHex(0xffaa00);
|
||||
lp.material.emissive.setHex(0x442200);
|
||||
lp.material.emissiveIntensity = 0.5;
|
||||
lp.material.opacity = 1.0;
|
||||
lp.scale.setScalar(1.0);
|
||||
lp.material.color.setHex(CABLE_CONFIG.landingPoint.color);
|
||||
lp.material.emissive.setHex(CABLE_CONFIG.landingPoint.emissive);
|
||||
lp.material.emissiveIntensity = CABLE_CONFIG.landingPoint.emissiveIntensity;
|
||||
lp.material.opacity = CABLE_CONFIG.landingPoint.opacity;
|
||||
const distanceScale = getLandingPointDistanceScale(lp, camera);
|
||||
const baseScale = lp.userData?.baseScale || CABLE_CONFIG.landingPoint.baseScale;
|
||||
lp.scale.setScalar(baseScale * distanceScale);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,50 @@ export const CABLE_CONFIG = {
|
||||
otherOpacity: 0.5,
|
||||
otherBrightness: 0.6,
|
||||
pulseSpeed: 0.008,
|
||||
pulseCoefficient: 0.4
|
||||
pulseCoefficient: 0.4,
|
||||
line: {
|
||||
altitudeOffset: 0.2,
|
||||
greatCircleSegments: 50,
|
||||
nearPointThreshold: 0.01,
|
||||
lineWidth: 1,
|
||||
opacity: 1.0,
|
||||
renderOrder: 1,
|
||||
},
|
||||
landingPoint: {
|
||||
altitudeOffset: 0.1,
|
||||
radius: 0.4,
|
||||
widthSegments: 16,
|
||||
heightSegments: 16,
|
||||
baseScale: 2.5,
|
||||
color: 0xffaa00,
|
||||
emissive: 0x442200,
|
||||
emissiveIntensity: 0.5,
|
||||
opacity: 1.0,
|
||||
},
|
||||
landingPointSizeStabilization: {
|
||||
enabled: true,
|
||||
referenceFov: 75,
|
||||
min: 0.12,
|
||||
max: 3.0,
|
||||
},
|
||||
landingPointVisual: {
|
||||
pulseSpeed: 0.003,
|
||||
dimBrightness: 0.3,
|
||||
related: {
|
||||
emissiveIntensityBase: 0.5,
|
||||
emissiveIntensityPulse: 0.5,
|
||||
opacityBase: 0.8,
|
||||
opacityPulse: 0.2,
|
||||
scaleBase: 1.2,
|
||||
scalePulse: 0.3,
|
||||
},
|
||||
dimmed: {
|
||||
colorRGB: { r: 255, g: 170, b: 0 },
|
||||
emissive: 0x000000,
|
||||
emissiveIntensity: 0,
|
||||
opacity: 0.3,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const CABLE_STATE = {
|
||||
@@ -75,15 +118,21 @@ export const BGP_CONFIG = {
|
||||
maxRenderedMarkers: 200,
|
||||
altitudeOffset: 2.1,
|
||||
collectorAltitudeOffset: 1.6,
|
||||
baseScale: 6.2,
|
||||
collectorScale: 7.4,
|
||||
hoverScale: 1.16,
|
||||
dimmedScale: 0.92,
|
||||
pulseSpeed: 0.0045,
|
||||
collectorPulseSpeed: 0.0024,
|
||||
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,
|
||||
normalPulseAmplitude: 0.08,
|
||||
lockedPulseAmplitude: 0.28,
|
||||
opacity: {
|
||||
normal: 0.78,
|
||||
hover: 1.0,
|
||||
@@ -132,13 +181,24 @@ export const BGP_CONFIG = {
|
||||
dimmedColor: 0x7d8ca3,
|
||||
},
|
||||
regionColor: 0x2dd4bf,
|
||||
eventRingScaleA: 2.5,
|
||||
eventRingScaleB: 3.4,
|
||||
eventRingOpacity: 0.5,
|
||||
eventRingSpeed: 0.001,
|
||||
collectorHaloScale: 11.5,
|
||||
collectorPulseHaloScale: 16.5,
|
||||
collectorCoverageHaloScale: 22.5
|
||||
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 = {
|
||||
|
||||
@@ -1537,11 +1537,11 @@ function animate() {
|
||||
updateBGPVisualState(lockedObjectType, lockedObject, camera);
|
||||
|
||||
if (lockedObjectType === "cable" && lockedObject) {
|
||||
applyLandingPointVisualState(lockedObject.userData.name, false);
|
||||
applyLandingPointVisualState(lockedObject.userData.name, false, camera);
|
||||
} else if (
|
||||
lockedObjectType === "satellite" && lockedSatellite
|
||||
) {
|
||||
applyLandingPointVisualState(null, true);
|
||||
applyLandingPointVisualState(null, true, camera);
|
||||
} else if (lockedObjectType === "bgp" && lockedObject) {
|
||||
const relatedCableNames = getBGPRelatedCableNames(lockedObject);
|
||||
clearAllCableStates();
|
||||
@@ -1555,12 +1555,13 @@ function animate() {
|
||||
applyLandingPointVisualState(
|
||||
relatedCableNames.length > 0 ? relatedCableNames : null,
|
||||
relatedCableNames.length === 0,
|
||||
camera,
|
||||
);
|
||||
} else if (lockedObjectType === "bgp_collector" && lockedObject) {
|
||||
clearAllCableStates();
|
||||
resetLandingPointVisualState();
|
||||
resetLandingPointVisualState(camera);
|
||||
} else {
|
||||
resetLandingPointVisualState();
|
||||
resetLandingPointVisualState(camera);
|
||||
}
|
||||
|
||||
updateSatellitePositions(deltaTime);
|
||||
|
||||
Reference in New Issue
Block a user