MCPcopy
hub / github.com/opentrace/opentrace / update3D

Method update3D

ui/src/components/pixi/PixiRenderer.ts:2900–3045  ·  view source on GitHub ↗

* Called from the Pixi ticker every frame when 3D mode is active. * Projects all nodes and redraws edges.

()

Source from the content-addressed store, hash-verified

2898 * Projects all nodes and redraws edges.
2899 */
2900 private update3D(): void {
2901 // Auto-rotation used to be gated on `layoutSettled` (Fix #54) to hide
2902 // ticker stutter while the main thread was busy in bursts during
2903 // indexing. After Plans D + E moved the store and embedder off the
2904 // main thread, that stutter source is gone, and the gate was instead
2905 // suppressing rotation on graphs where d3-force never reports settled
2906 // (large graphs, warm alphaTarget). Manual drag still updates
2907 // `mode3dAngle` directly in the pointer handler regardless.
2908 if (this.mode3dAutoRotate) {
2909 this.mode3dAngle += this.mode3dSpeed;
2910 }
2911
2912 // Keep sphere bounds in sync with the layout.
2913 // • While the worker simulation is running (`!layoutSettled`) we
2914 // recompute every frame with allow-shrink so R tracks live
2915 // positions through any transition — e.g. spread → compact,
2916 // compact → spread. Without this, switching to a tighter
2917 // layout leaves R stuck at the larger value and the projection
2918 // collapses into a vertical cylinder (Fix #8).
2919 // • Once settled, fall back to throttled only-grows so brief
2920 // outward jitter doesn't trigger Z=0 hard-clamp flicker.
2921 this.mode3dFrameCounter++;
2922 if (!this.layoutSettled) {
2923 this.recomputeMode3DExtents(true);
2924 } else if (this.mode3dFrameCounter % 30 === 0) {
2925 this.recomputeMode3DExtents();
2926 }
2927
2928 const invScale = this.zoomInvScale();
2929 const lblInv = this.labelInvScale();
2930 // Fold community-centroid accumulation into the projection loop so
2931 // the wayfinders re-aim every frame at zero extra cost (Fix #34).
2932 // Allocating a Map per frame is cheap (~20 entries); the per-node
2933 // dict lookup is a single property read.
2934 const trackCommunities =
2935 this.showCommunityLabels &&
2936 this.communityLabels.size > 0 &&
2937 this.communityAssignments !== null;
2938 const communitySums: Map<
2939 number,
2940 { x: number; y: number; n: number }
2941 > | null = trackCommunities ? new Map() : null;
2942 // Per-community representative Z (golden-angle bucket from
2943 // set3DMode), captured from the first member encountered. Reused
2944 // below to project each community's 2D centroid through the
2945 // current rotation.
2946 const communityZ: Map<number, number> | null = trackCommunities
2947 ? new Map()
2948 : null;
2949 const assignments = this.communityAssignments;
2950 for (const node of this.nodeArray) {
2951 if (!node.visible) continue;
2952 // Skip the dragged node — its sprite position is controlled by pointermove
2953 if (this.dragNode === node) continue;
2954 const z = this.getNodeZ(node);
2955 const p = this.project3d(node.x, node.y, z);
2956 node.sprite.position.set(p.px, p.py);
2957

Callers 2

_initMethod · 0.95
set3DModeMethod · 0.95

Calls 8

zoomInvScaleMethod · 0.95
labelInvScaleMethod · 0.95
getNodeZMethod · 0.95
project3dMethod · 0.95
redrawAllEdges3DMethod · 0.95
getMethod · 0.65

Tested by

no test coverage detected