Plot routes and build the jump-link graph in a Web Worker
Route plotting ran on the main thread, and so did the jump-link graph: - the range search for a far target, HD 2626 at 236 pc, takes 4-5 s; - the graph at 8 pc is 3.7 million links, 6-10 s to build, then as many link objects again to turn into vertices. The map stopped for as long as either ran. A Web Worker now does both. RoutingClient sends it the catalogue's ids and positions once, and it keeps its own spatial index. A route question comes back with the route, or with the range that would open one. A graph comes back as one Float32Array of segment vertices, transferred rather than copied. On the scene side, only the latest route request is shown: an earlier answer arriving later is dropped. Only the graph for the range last asked for is drawn. The Routes panel says "Plotting…" and holds its button while a request is out. collectJumpLinks gave way to jumpLinkSegments, which writes the vertex pairs straight into floats rather than building link objects first; the scene was its only caller. The routing module (routing.ts) is the message protocol and the one function answering it, so the worker is a dozen lines, and the same answers are worked out in place where there is no Worker, as in the unit tests' DOM. The worker is built with its own tsconfig, as the Angular builder expects. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016jxMkwA2rbicdGxHosecYi
This commit is contained in:
@@ -29,13 +29,6 @@ export interface Route {
|
||||
readonly longestHopPc: number;
|
||||
}
|
||||
|
||||
/** An unordered pair of stars within range of each other. */
|
||||
export interface JumpLink {
|
||||
readonly from: number;
|
||||
readonly to: number;
|
||||
readonly distancePc: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* A cap on how much of the catalogue one search may walk. A search that hits it has already
|
||||
* visited more stars than any real chain passes through: the longest measured, Sol to HD 2626 at
|
||||
@@ -221,17 +214,30 @@ export function minimumRangeBetween(index: StarNeighbourhood, fromId: number, to
|
||||
}
|
||||
|
||||
/**
|
||||
* Every link within `rangePc` in the whole catalogue, each pair once.
|
||||
* Every link within `rangePc` in the whole catalogue, each pair once, as vertex pairs ready to
|
||||
* draw: six floats a link, one end then the other.
|
||||
*
|
||||
* For drawing the graph, which is the only thing that wants all of it: routing asks for a
|
||||
* star's neighbours as it reaches that star and never builds this.
|
||||
* For drawing the graph, which is the only thing that wants all of it: routing asks for a star's
|
||||
* neighbours as it reaches that star and never builds this. Written straight into floats rather
|
||||
* than collected as link objects first, since at 8 pc there are 3.7 million links.
|
||||
*/
|
||||
export function collectJumpLinks(index: StarNeighbourhood, rangePc: number): JumpLink[] {
|
||||
const links: JumpLink[] = [];
|
||||
index.forEachPairWithin(rangePc, (a, b, distancePc) => {
|
||||
// The smaller id first, always. The grid hands pairs over in whatever order it walks its
|
||||
// cells, and a link that is `3-7` here and `7-3` there is two links to anything comparing.
|
||||
links.push(a.id < b.id ? { from: a.id, to: b.id, distancePc } : { from: b.id, to: a.id, distancePc });
|
||||
export function jumpLinkSegments(index: StarNeighbourhood, rangePc: number): Float32Array {
|
||||
let vertices = new Float32Array(6 * 4096);
|
||||
let length = 0;
|
||||
index.forEachPairWithin(rangePc, (a, b) => {
|
||||
if (length + 6 > vertices.length) {
|
||||
const grown = new Float32Array(vertices.length * 2);
|
||||
grown.set(vertices);
|
||||
vertices = grown;
|
||||
}
|
||||
vertices[length++] = a.x;
|
||||
vertices[length++] = a.y;
|
||||
vertices[length++] = a.z;
|
||||
vertices[length++] = b.x;
|
||||
vertices[length++] = b.y;
|
||||
vertices[length++] = b.z;
|
||||
});
|
||||
return links;
|
||||
// Exact length rather than a view on the grown buffer: the answer is transferred whole, and a
|
||||
// view would carry up to as much again in unused capacity with it.
|
||||
return vertices.slice(0, length);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user