release: bump version to 0.44.1

This commit is contained in:
linkong
2026-04-29 18:07:35 +08:00
parent 87594a95ff
commit a87537e903
8 changed files with 414 additions and 96 deletions

View File

@@ -258,6 +258,7 @@ let lastBGPClickTime = 0;
let lastBGPClickCollector = null;
let lastBGPClickType = null;
let lastBGPClickPos = { x: 0, y: 0 };
let lastVesselHoverPickTime = 0;
let earthTexture = null;
let animationFrameId = null;
let initialized = false;
@@ -295,7 +296,9 @@ const scratchBGPWorldPosition = new THREE.Vector3();
const scratchComputeCenterDirection = new THREE.Vector3();
const scratchComputeCenterWorldPosition = new THREE.Vector3();
const scratchVesselDirection = new THREE.Vector3();
const scratchVesselCameraLocal = new THREE.Vector3();
const scratchVesselWorldPosition = new THREE.Vector3();
const scratchVesselScreenPosition = new THREE.Vector3();
const scratchSatelliteWorldPosition = new THREE.Vector3();
const scratchSatelliteScreenPosition = new THREE.Vector3();
const scratchViewCenterWorld = new THREE.Vector3();
@@ -310,6 +313,8 @@ const TOOLTIP_CURSOR_OFFSET = 14; // px offset from cursor for hover tooltips
const TOOLTIP_COORDS_OFFSET = 10; // px offset for earth-coordinate tooltip
const RELATED_SATELLITE_HIGHLIGHT_COLOR = "#7dd3fc";
const DRAG_POINTER_THRESHOLD_PX = 8;
const VESSEL_HOVER_PICK_INTERVAL_MS = 100;
const VESSEL_POINTER_RADIUS_PX = 22;
const GLOBE_DRAGGING_CLASS = "is-globe-dragging";
const HUD_INTERACTIVE_SELECTORS = [
".earth-left-column",
@@ -364,6 +369,13 @@ function setGlobeDraggingUiState(active) {
document.documentElement.classList.toggle(GLOBE_DRAGGING_CLASS, active);
}
function hasActiveGlobeInertia() {
return (
Math.abs(inertialVelocity.x) > INERTIA_MIN_VELOCITY ||
Math.abs(inertialVelocity.y) > INERTIA_MIN_VELOCITY
);
}
function getDragRotationFactor() {
const zoom = Math.max(getZoomLevel(), 0.01);
const scale = THREE.MathUtils.clamp(
@@ -540,21 +552,92 @@ function getFrontFacingVesselMarkers(markers) {
const earth = getEarth();
if (!earth) return markers;
scratchCameraToEarth.subVectors(camera.position, earth.position).normalize();
scratchVesselCameraLocal.copy(camera.position);
earth.worldToLocal(scratchVesselCameraLocal);
scratchVesselCameraLocal.normalize();
return markers.filter((marker) => {
scratchVesselWorldPosition.copy(marker.position);
marker.parent?.localToWorld(scratchVesselWorldPosition);
scratchVesselDirection
.subVectors(scratchVesselWorldPosition, earth.position)
.normalize();
scratchVesselDirection.copy(marker.position).normalize();
return (
scratchCameraToEarth.dot(scratchVesselDirection) >
scratchVesselCameraLocal.dot(scratchVesselDirection) >
SATELLITE_CONFIG.frontFacingDotThreshold
);
});
}
function getVesselPointerIntersections() {
const earth = getEarth();
if (!earth) return [];
scratchVesselCameraLocal.copy(camera.position);
earth.worldToLocal(scratchVesselCameraLocal);
scratchVesselCameraLocal.normalize();
const pointerX = ((interactionMouse.x + 1) / 2) * window.innerWidth;
const pointerY = ((1 - interactionMouse.y) / 2) * window.innerHeight;
const radiusSq = VESSEL_POINTER_RADIUS_PX * VESSEL_POINTER_RADIUS_PX;
const intersections = [];
getVesselMarkers().forEach((marker) => {
scratchVesselDirection.copy(marker.position).normalize();
if (
scratchVesselCameraLocal.dot(scratchVesselDirection) <=
SATELLITE_CONFIG.frontFacingDotThreshold
) {
return;
}
scratchVesselWorldPosition.copy(marker.position);
earth.localToWorld(scratchVesselWorldPosition);
scratchVesselScreenPosition.copy(scratchVesselWorldPosition).project(camera);
if (
scratchVesselScreenPosition.z < -1 ||
scratchVesselScreenPosition.z > 1
) {
return;
}
const screenX = (scratchVesselScreenPosition.x * 0.5 + 0.5) * window.innerWidth;
const screenY = (-scratchVesselScreenPosition.y * 0.5 + 0.5) * window.innerHeight;
const deltaX = screenX - pointerX;
const deltaY = screenY - pointerY;
const distancePxSq = deltaX * deltaX + deltaY * deltaY;
if (distancePxSq > radiusSq) return;
intersections.push({
object: marker,
point: scratchVesselWorldPosition.clone(),
distance: camera.position.distanceTo(scratchVesselWorldPosition),
distancePxSq,
});
});
return intersections.sort((a, b) => a.distancePxSq - b.distancePxSq);
}
function shouldSkipVesselHoverPicking() {
return isDragging || hasActiveGlobeInertia();
}
function getVesselHoverIntersections() {
if (!getShowVessels()) {
return { checked: true, intersects: [] };
}
if (shouldSkipVesselHoverPicking()) {
return { checked: false, intersects: [] };
}
const now = performance.now();
if (now - lastVesselHoverPickTime < VESSEL_HOVER_PICK_INTERVAL_MS) {
return { checked: false, intersects: [] };
}
lastVesselHoverPickTime = now;
return {
checked: true,
intersects: getVesselPointerIntersections(),
};
}
function applyBGPHoverState(marker) {
resetTransientBGPStates();
if (!marker) {
@@ -590,14 +673,14 @@ function applyComputeCenterHoverState(marker) {
}
function resetTransientVesselStates() {
getVesselMarkers().forEach((marker) => {
if (marker !== lockedObject) {
setVesselMarkerState(marker, "normal");
}
});
if (hoveredVessel && hoveredVessel !== lockedObject) {
setVesselMarkerState(hoveredVessel, "normal");
}
hoveredVessel = null;
}
function applyVesselHoverState(marker) {
if (isSameVessel(hoveredVessel, marker)) return;
resetTransientVesselStates();
if (!marker) {
hoveredVessel = null;
@@ -3134,11 +3217,8 @@ function onMouseMove(event) {
const computeCenterIntersects = getShowComputeCenters()
? interactionRaycaster.intersectObjects(frontFacingComputeCenterMarkers)
: [];
const vesselIntersects = getShowVessels()
? interactionRaycaster.intersectObjects(
getFrontFacingVesselMarkers(getVesselMarkers()),
)
: [];
const vesselPick = getVesselHoverIntersections();
const vesselIntersects = vesselPick.intersects;
let hoveredSat = null;
let hoveredSatIndexFromIntersect = null;
@@ -3161,7 +3241,7 @@ function onMouseMove(event) {
const hoveredComputeCenterMarker =
computeCenterIntersects.length > 0 ? computeCenterIntersects[0].object : null;
const hoveredVesselMarker =
vesselIntersects.length > 0 ? vesselIntersects[0].object : null;
vesselPick.checked && vesselIntersects.length > 0 ? vesselIntersects[0].object : null;
if (
hoveredComputeCenter &&
@@ -3169,7 +3249,11 @@ function onMouseMove(event) {
) {
clearTransientHoverState();
}
if (hoveredVessel && !isSameVessel(hoveredVessel, hoveredVesselMarker)) {
if (
vesselPick.checked &&
hoveredVessel &&
!isSameVessel(hoveredVessel, hoveredVesselMarker)
) {
clearTransientHoverState();
}
@@ -3216,6 +3300,7 @@ function onMouseMove(event) {
);
objectTooltipShown = true;
} else if (
vesselPick.checked &&
hoveredVesselMarker &&
getShowVessels() &&
lockedObjectType !== "vessel"
@@ -3262,7 +3347,9 @@ function onMouseMove(event) {
} else if (!lockedObjectType && !isCruisePresentationPinned()) {
resetTransientBGPStates();
resetTransientComputeCenterStates();
resetTransientVesselStates();
if (vesselPick.checked) {
resetTransientVesselStates();
}
hideInfoCard();
}
@@ -3483,9 +3570,7 @@ function onClick(event) {
)
: [];
const vesselIntersects = getShowVessels()
? interactionRaycaster.intersectObjects(
getFrontFacingVesselMarkers(getVesselMarkers()),
)
? getVesselPointerIntersections()
: [];
const satIntersects = getSatellitePointerIntersections(event);
@@ -3681,9 +3766,7 @@ function animate() {
const earth = getEarth();
const deltaTime = clock.getDelta() * 1000;
const hasInertia =
Math.abs(inertialVelocity.x) > INERTIA_MIN_VELOCITY ||
Math.abs(inertialVelocity.y) > INERTIA_MIN_VELOCITY;
const hasInertia = hasActiveGlobeInertia();
if (getAutoRotate() && getRotationMode() === ROTATION_MODE.ROTATE && earth) {
earth.rotation.y += CONFIG.rotationSpeed * (deltaTime / 16);