awatif-ui
Version:
Awatif User Interface
65 lines (53 loc) • 1.74 kB
text/typescript
import * as THREE from "three";
import { Node, Element } from "awatif-fem";
import { Lut } from "three/addons/math/Lut.js";
import van, { State } from "vanjs-core";
export function getColorMap(
nodes: State<Node[]>,
elements: State<Element[]>,
values: State<number[]>
): THREE.Mesh {
// Init
const lut = new Lut();
const color = new THREE.Color();
const colorMap = new THREE.Mesh(
new THREE.BufferGeometry(),
new THREE.MeshBasicMaterial({
side: THREE.DoubleSide,
vertexColors: true,
})
);
// Update
lut.setColorMap("rainbow");
colorMap.renderOrder = -1; // to ensure that it always set behind the mesh
colorMap.frustumCulled = false;
// Events
// When nodes, elements or values change, update the color map
van.derive(() => {
// Update geometry
colorMap.geometry.setAttribute(
"position",
new THREE.Float32BufferAttribute(nodes.val.flat(), 3)
);
colorMap.geometry.setIndex(
new THREE.Uint16BufferAttribute(
elements.val.filter((e) => e.length != 2).flat(), // we only want triangles and quads
1
)
);
colorMap.geometry.setAttribute(
"color",
new THREE.Float32BufferAttribute(nodes.val.map(() => [0, 0, 0]).flat(), 3)
);
// Update colors
lut.setMax(Math.max(...values.val));
lut.setMin(Math.min(...values.val));
for (let i = 0; i < values.val.length; i++) {
const lutColor = lut.getColor(values.val[i]) ?? new THREE.Color(0, 0, 0);
color.copy(lutColor).convertSRGBToLinear();
color.multiplyScalar(0.6); // dim the color for better integration with mesh
colorMap.geometry.attributes.color.setXYZ(i, color.r, color.g, color.b);
}
});
return colorMap;
}