awatif-ui
Version:
Awatif User Interface
100 lines (81 loc) • 2.89 kB
text/typescript
import * as THREE from "three";
import van, { State } from "vanjs-core";
import { Node } from "awatif-fem";
import { Structure } from "awatif-fem";
import { Settings } from "../settings/getSettings";
import { getTransformationMatrixBeam } from "./utils/getTransformationMatrixBeam";
import { get10thFromFirstPoint } from "./utils/get5thFromFirstPoint";
import { getAverage } from "./utils/getAverage";
import { getTransformationMatrixShell } from "./utils/getTransformationMatrixShell";
export function orientations(
structure: Structure,
settings: Settings,
derivedNodes: State<Node[]>,
derivedDisplayScale: State<number>
): THREE.Group {
// init
const group = new THREE.Group();
const geometry = new THREE.BufferGeometry();
const material = new THREE.LineBasicMaterial({ vertexColors: true });
const size = 0.05 * settings.gridSize.rawVal * 0.75;
// update
const o = [0, 0, 0];
const x = [1, 0, 0];
const y = [0, 1, 0];
const z = [0, 0, 1];
geometry.setAttribute(
"position",
new THREE.Float32BufferAttribute([...o, ...x, ...o, ...y, ...o, ...z], 3)
);
const xColor = [255, 0, 0];
const yColor = [0, 255, 0];
const zColor = [0, 0, 255];
geometry.setAttribute(
"color",
new THREE.Float32BufferAttribute(
[...xColor, ...xColor, ...yColor, ...yColor, ...zColor, ...zColor],
3
)
);
// on settings.orientations * deformedShape, and model clear and create visuals
van.derive(() => {
settings.deformedShape.val; // triggers update
if (!settings.orientations.val) return;
group.clear();
structure.elements?.val.forEach((element) => {
const axes = new THREE.LineSegments(geometry, material);
const node1 = derivedNodes.rawVal[element[0]];
const node2 = derivedNodes.rawVal[element[1]];
if (element.length === 2) {
// beam element
axes.position.set(...get10thFromFirstPoint(node1, node2));
axes.rotation.setFromRotationMatrix(
getTransformationMatrixBeam(node1, node2)
);
}
if (element.length === 3) {
// shell element
const node3 = derivedNodes.rawVal[element[2]];
axes.position.set(...getAverage([node1, node2, node3]));
axes.rotation.setFromRotationMatrix(
getTransformationMatrixShell(node1, node2, node3)
);
}
const scale = size * derivedDisplayScale.rawVal;
axes.scale.set(scale, scale, scale);
group.add(axes);
});
});
// on derivedDisplayScale update scale
van.derive(() => {
derivedDisplayScale.val;
if (!settings.orientations.rawVal) return;
const scale = size * derivedDisplayScale.rawVal;
group.children.forEach((c) => c.scale.set(scale, scale, scale));
});
// on settings.orientations update scale
van.derive(() => {
group.visible = settings.orientations.val;
});
return group;
}