feat: expand bgp observability surfaces
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
import * as THREE from "three";
|
||||
import { twoline2satrec, propagate } from "satellite.js";
|
||||
import { CONFIG, SATELLITE_CONFIG } from "./constants.js";
|
||||
import { latLonToVector3 } from "./utils.js";
|
||||
|
||||
let satellitePoints = null;
|
||||
let satelliteTrails = null;
|
||||
@@ -15,6 +16,7 @@ let hoverRingSprite = null;
|
||||
let lockedRingSprite = null;
|
||||
let lockedDotSprite = null;
|
||||
let predictedOrbitLine = null;
|
||||
let relatedSatelliteSprites = [];
|
||||
let earthObjRef = null;
|
||||
let sceneRef = null;
|
||||
let cameraRef = null;
|
||||
@@ -759,6 +761,25 @@ function createRingSprite(position, isLocked = false) {
|
||||
return sprite;
|
||||
}
|
||||
|
||||
function createRelatedSatelliteSprite(position, color = "#7dd3fc") {
|
||||
if (!earthObjRef) return null;
|
||||
|
||||
const ringTexture = createRingTexture(7, 11, color);
|
||||
const spriteMaterial = new THREE.SpriteMaterial({
|
||||
map: ringTexture,
|
||||
transparent: true,
|
||||
opacity: 0.55,
|
||||
depthTest: false,
|
||||
sizeAttenuation: false,
|
||||
});
|
||||
|
||||
const sprite = new THREE.Sprite(spriteMaterial);
|
||||
sprite.position.copy(position);
|
||||
sprite.scale.set(SATELLITE_CONFIG.ringSize * 0.8, SATELLITE_CONFIG.ringSize * 0.8, 1);
|
||||
earthObjRef.add(sprite);
|
||||
return sprite;
|
||||
}
|
||||
|
||||
export function showHoverRing(position, isLocked = false) {
|
||||
if (!earthObjRef || !position) return null;
|
||||
|
||||
@@ -866,6 +887,82 @@ export function setSatelliteRingState(index, state, position) {
|
||||
}
|
||||
}
|
||||
|
||||
export function clearRelatedSatelliteHighlights() {
|
||||
relatedSatelliteSprites.forEach((item) => {
|
||||
if (item.sprite) {
|
||||
disposeObject3D(item.sprite);
|
||||
}
|
||||
});
|
||||
relatedSatelliteSprites = [];
|
||||
}
|
||||
|
||||
export function highlightRelatedSatellites(indices, color = "#7dd3fc") {
|
||||
clearRelatedSatelliteHighlights();
|
||||
if (!Array.isArray(indices) || indices.length === 0) return;
|
||||
|
||||
indices.forEach((index) => {
|
||||
const pos = satellitePositions?.[index]?.current;
|
||||
if (!pos) return;
|
||||
const sprite = createRelatedSatelliteSprite(pos, color);
|
||||
if (!sprite) return;
|
||||
relatedSatelliteSprites.push({ index, sprite, color });
|
||||
});
|
||||
}
|
||||
|
||||
export function updateRelatedSatelliteHighlights() {
|
||||
if (relatedSatelliteSprites.length === 0) return;
|
||||
relatedSatelliteSprites = relatedSatelliteSprites.filter((item) => {
|
||||
const pos = satellitePositions?.[item.index]?.current;
|
||||
if (!pos || !item.sprite) return false;
|
||||
item.sprite.position.copy(pos);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
export function getRelatedSatelliteIndicesForRegions(
|
||||
regions,
|
||||
{ limit = 6, maxAngleDeg = 22 } = {},
|
||||
) {
|
||||
if (!Array.isArray(regions) || regions.length === 0 || satellitePositions.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const regionVectors = regions
|
||||
.filter(
|
||||
(region) =>
|
||||
typeof region?.latitude === "number" &&
|
||||
typeof region?.longitude === "number",
|
||||
)
|
||||
.map((region) =>
|
||||
latLonToVector3(region.latitude, region.longitude, CONFIG.earthRadius + 1)
|
||||
.clone()
|
||||
.normalize(),
|
||||
);
|
||||
|
||||
if (regionVectors.length === 0) return [];
|
||||
|
||||
const threshold = Math.cos((maxAngleDeg * Math.PI) / 180);
|
||||
const ranked = [];
|
||||
|
||||
satellitePositions.forEach((item, index) => {
|
||||
const current = item?.current;
|
||||
if (!current || current.lengthSq() === 0) return;
|
||||
const satVector = current.clone().normalize();
|
||||
let bestDot = -1;
|
||||
regionVectors.forEach((regionVector) => {
|
||||
bestDot = Math.max(bestDot, satVector.dot(regionVector));
|
||||
});
|
||||
if (bestDot >= threshold) {
|
||||
ranked.push({ index, score: bestDot });
|
||||
}
|
||||
});
|
||||
|
||||
return ranked
|
||||
.sort((a, b) => b.score - a.score)
|
||||
.slice(0, limit)
|
||||
.map((item) => item.index);
|
||||
}
|
||||
|
||||
export function initSatelliteScene(scene, earth) {
|
||||
sceneRef = scene;
|
||||
earthObjRef = earth;
|
||||
@@ -1000,6 +1097,7 @@ export function clearSatelliteData() {
|
||||
hideHoverRings();
|
||||
hideLockedRing();
|
||||
hidePredictedOrbit();
|
||||
clearRelatedSatelliteHighlights();
|
||||
}
|
||||
|
||||
export function resetSatelliteState() {
|
||||
|
||||
Reference in New Issue
Block a user