fix: keep satellite selection glow whole at limb
This commit is contained in:
@@ -101,7 +101,7 @@ Base, tint, land fill and HD surface now use `createEarthSurfaceGeometry()` and
|
||||
Cables and landing points share R+0.48, the `earthSurfacePoint` triangle projection and renderOrder=1. Related landing halos use an emphasis attribute in the existing batch, adding no Sprite or draw call. Rounded badges use GPU anchor ray/sphere occlusion: draw the entire billboard when its anchor is visible, otherwise clip it entirely. CPU picking uses the same test to reject rear anchors. Only `icon.badge` layers (including compute and collectors; vessels independently use heading arrows) use this path. BGP event rings use the same whole-anchor front/rear decision: front-side rings disable per-pixel depth testing and sit in the foreground adjacent to the event icon, preventing the Earth from slicing their edges; rear-side anchors hide the entire ring.
|
||||
|
||||
|
||||
The `.map-clusters` projection layer uses z-index 8 below HUD and whole-marker occlusion from real surface anchors. Ordinary points retain their Three.js layers; transitioning members render only once in the projection layer. Spider legs use widened transparent hit areas; hover highlights the matching line and child, and both clicks resolve the same business object. Wheel input over projected markers and legs continues to zoom the globe.
|
||||
The `.map-clusters` projection layer uses z-index 8 below HUD and whole-marker occlusion from real surface anchors. Ordinary points retain their Three.js layers; transitioning members render only once in the projection layer. Spider legs use widened transparent hit areas; hover highlights the matching line and child, and both clicks resolve the same business object. Wheel input over projected markers and legs continues to zoom the globe. Satellite selection/hover rings and self-glow use the same whole-anchor front/rear decision: front-side overlays render in full, while rear-side overlays hide together so the Earth cannot slice their edges.
|
||||
|
||||
Co-located markers share a compact projection stack across categories; screen collisions never merge different locations. A selected child uses projection `z-index: 1000`, while the locked overlay for an unclustered marker uses the shared foreground `renderOrder >= 100`, so focus stays on top across layers; clearing focus restores stable ID order. The aggregate badge stays below a selected child during its opening tween. `icon_presentation_screen` lets detail connectors follow display offsets while markers retain their real anchors. Ownership changes immediately rebuild the corresponding GPU batch.
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ Earth 的地表不是单一 mesh,而是多层近似同心球:基座球、海
|
||||
海缆和登陆点现在统一使用 R+0.48 及 `earthSurfacePoint` 三角表面投影,并保持 renderOrder=1。登陆点关联光晕进入原实例批次的 emphasis 属性,不增加独立 Sprite 或 draw call。侧面的完整圆角徽标采用 GPU 锚点射线/球体遮挡:锚点可见则整个 billboard 绘制,锚点被地球挡住则整块裁除。CPU 拾取使用同样的射线判断,避免点到背面图标。该路径只作用于 `icon.badge` 层(含算力、观测站;船舶独立使用航向箭头)。BGP 事件圆环同样按锚点做整块前后判断,前面锚点的圆环关闭逐像素深度测试并置于事件图标邻近前景层,避免圆环边缘被地球切断;背面锚点整圈隐藏。
|
||||
|
||||
|
||||
聚合投影层 `.map-clusters` 的 z-index 为 8,低于 HUD;以真实地表锚点做整标遮挡。普通点仍使用原 Three.js 图层,过渡中的成员只在投影层显示一次,避免双图标。Spiderfy 引线有透明加宽命中区域,悬停联动高亮引线与子点,点击返回同一业务对象;滚轮在图标与引线上继续缩放地球。
|
||||
聚合投影层 `.map-clusters` 的 z-index 为 8,低于 HUD;以真实地表锚点做整标遮挡。普通点仍使用原 Three.js 图层,过渡中的成员只在投影层显示一次,避免双图标。Spiderfy 引线有透明加宽命中区域,悬停联动高亮引线与子点,点击返回同一业务对象;滚轮在图标与引线上继续缩放地球。卫星选中/悬停环和自发光也按卫星锚点做整块前后判断,前侧完整显示,背侧整组隐藏,避免环或光晕被地表切边。
|
||||
|
||||
跨图层同坐标/极近坐标标记在同一投影层内紧凑堆叠,不以屏幕碰撞合并不同地点;选中项使用投影子点 `z-index: 1000`,普通未聚合图标的锁定覆盖层使用共享的前景 `renderOrder >= 100`,因此跨图层重叠时仍由焦点对象在最上层;取消后恢复稳定 ID 顺序。聚合徽标在展开过渡期间保持低于选中子点。`icon_presentation_screen` 仅供详情引线跟随显示偏移,真实锚点仍由原 marker 持有;隐藏状态变化立即重建对应 GPU 批次。
|
||||
|
||||
|
||||
@@ -1279,10 +1279,21 @@ export function isSatelliteFrontFacing(index, camera = cameraRef) {
|
||||
);
|
||||
}
|
||||
|
||||
function updateSatelliteOverlayVisibility() {
|
||||
const lockedVisible =
|
||||
lockedSatelliteIndex === null || isSatelliteFrontFacing(lockedSatelliteIndex);
|
||||
const hoveredVisible =
|
||||
hoveredSatelliteIndex === null || isSatelliteFrontFacing(hoveredSatelliteIndex);
|
||||
if (lockedRingSprite) lockedRingSprite.visible = lockedVisible;
|
||||
if (lockedDotSprite) lockedDotSprite.visible = lockedVisible;
|
||||
if (lockedHaloMesh) lockedHaloMesh.visible = lockedVisible;
|
||||
if (hoverRingSprite) hoverRingSprite.visible = hoveredVisible;
|
||||
}
|
||||
|
||||
function createLockedHaloMaterial(color = "#ffbf47") {
|
||||
return new THREE.ShaderMaterial({
|
||||
transparent: true,
|
||||
depthTest: true,
|
||||
depthTest: false,
|
||||
depthWrite: false,
|
||||
side: THREE.DoubleSide,
|
||||
uniforms: {
|
||||
@@ -1724,7 +1735,7 @@ function showSelfGlowStyle(position, color = "#ffd25a") {
|
||||
color: new THREE.Color(color),
|
||||
transparent: true,
|
||||
opacity: 0.96,
|
||||
depthTest: true,
|
||||
depthTest: false,
|
||||
depthWrite: false,
|
||||
side: THREE.DoubleSide,
|
||||
});
|
||||
@@ -1797,7 +1808,7 @@ function createRingSprite(position, isLocked = false, color = "#ffffff") {
|
||||
map: ringTexture,
|
||||
transparent: true,
|
||||
opacity: 0.8,
|
||||
depthTest: true,
|
||||
depthTest: false,
|
||||
depthWrite: false,
|
||||
alphaTest: 0.01,
|
||||
sizeAttenuation: false,
|
||||
@@ -1845,6 +1856,7 @@ export function showHoverRing(position, isLocked = false) {
|
||||
const legendColor = getSatelliteLegendRule(lockedProps).color;
|
||||
hideLockedRing();
|
||||
lockedRingSprite = createRingSprite(position, true, legendColor);
|
||||
updateSatelliteOverlayVisibility();
|
||||
updateLockedMarkerVisual(isLockedSatelliteHovered());
|
||||
const presentationMode = getSatellitePresentationMode(lockedProps);
|
||||
if (
|
||||
@@ -1865,6 +1877,7 @@ export function showHoverRing(position, isLocked = false) {
|
||||
hideHoverRings();
|
||||
const hoverColor = getSatelliteLegendRule(satelliteData[hoveredSatelliteIndex]?.properties).color;
|
||||
hoverRingSprite = createRingSprite(position, false, hoverColor);
|
||||
updateSatelliteOverlayVisibility();
|
||||
return hoverRingSprite;
|
||||
}
|
||||
|
||||
@@ -1959,6 +1972,7 @@ export function updateLockedRingPosition(position) {
|
||||
if (lockedIridiumFootprintMesh) {
|
||||
updateIridiumReservedStyle(position);
|
||||
}
|
||||
updateSatelliteOverlayVisibility();
|
||||
}
|
||||
|
||||
export function updateHoverRingPosition(position) {
|
||||
@@ -1969,6 +1983,7 @@ export function updateHoverRingPosition(position) {
|
||||
SATELLITE_CONFIG.ringSize,
|
||||
1,
|
||||
);
|
||||
updateSatelliteOverlayVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user