51 lines
1.5 KiB
TypeScript
51 lines
1.5 KiB
TypeScript
import ELK, { ElkNode } from "elkjs/lib/elk.bundled.js";
|
|
import { Unit, Behaviour } from "@incgame/engine";
|
|
|
|
const elk = new ELK();
|
|
|
|
const UNIT_WIDTH = 200;
|
|
const NODE_HEIGHT = 150;
|
|
|
|
export type GraphNode = {
|
|
position: { x: number, y: number };
|
|
kind: 'behaviour';
|
|
entity: Behaviour;
|
|
}
|
|
|
|
export async function build2dNodes(units: Unit[], area: { width: number, height: number, padding: number }): Promise<GraphNode[]> {
|
|
const entitiesById = new Map(units.map((unit) => [unit.behaviour.id, unit.behaviour]));
|
|
|
|
const graph: ElkNode = {
|
|
id: "root",
|
|
layoutOptions: {
|
|
"elk.algorithm": "layered",
|
|
"elk.direction": "LEFT",
|
|
"elk.spacing.nodeNode": "100",
|
|
"elk.layered.spacing.nodeNodeBetweenLayers": "100",
|
|
},
|
|
children: units.map((unit) => ({
|
|
id: unit.behaviour.id,
|
|
width: UNIT_WIDTH,
|
|
height: NODE_HEIGHT,
|
|
})),
|
|
edges: units.flatMap((node) =>
|
|
node.behaviour.inputLinks.map((link, idx) => ({
|
|
id: `${node.behaviour.id}->${link.target}.${idx}`,
|
|
sources: [node.behaviour.id],
|
|
targets: [link.target],
|
|
}))
|
|
),
|
|
};
|
|
|
|
const layout = await elk.layout(graph);
|
|
|
|
return (layout.children ?? []).map((child) => ({
|
|
position: {
|
|
x: (child.x ?? 0) + area.padding,
|
|
y: (child.y ?? 0) + area.padding,
|
|
},
|
|
kind: 'behaviour',
|
|
entity: entitiesById.get(child.id)!,
|
|
}));
|
|
}
|