@inweb/viewer-three
Version:
JavaScript library for rendering CAD and BIM files in a browser using Three.js
123 lines (101 loc) • 3.72 kB
text/typescript
import {
Camera,
CylinderGeometry,
CanvasTexture,
Color,
Mesh,
MeshBasicMaterial,
Object3D,
OrthographicCamera,
Sprite,
SpriteMaterial,
SRGBColorSpace,
Vector4,
WebGLRenderer,
} from "three";
export class WCSHelper extends Object3D {
private camera: Camera;
private orthoCamera: OrthographicCamera;
public size: number;
constructor(camera: Camera) {
super();
this.camera = camera;
this.size = 160;
this.orthoCamera = new OrthographicCamera(-2, 2, 2, -2, 0, 4);
this.orthoCamera.position.set(0, 0, 2);
const matRed = new MeshBasicMaterial({ toneMapped: false, color: "#aa0000" });
const matGreen = new MeshBasicMaterial({ toneMapped: false, color: "#00aa00" });
const matBlue = new MeshBasicMaterial({ toneMapped: false, color: "#0000aa" });
const spriteRed = this.getSpriteMaterial(matRed.color, "X");
const spriteGreen = this.getSpriteMaterial(matGreen.color, "Y");
const spriteBlue = this.getSpriteMaterial(matBlue.color, "Z");
const lineGeometry = new CylinderGeometry(0.01, 0.01, 1, 3);
lineGeometry.translate(0, 0.5, 0);
const arrowGeometry = new CylinderGeometry(0, 0.1, 0.25, 12);
arrowGeometry.translate(0, 0.625, 0);
const axesMap = {
X: [
[new Mesh(arrowGeometry, matRed), [0.5, 0, 0], [0, 0, -Math.PI / 2]],
[new Mesh(lineGeometry, matRed), [0, 0, 0], [0, 0, -Math.PI / 2]],
[new Sprite(spriteRed), [1.55, 0, 0]],
],
Y: [
[new Mesh(arrowGeometry, matGreen), [0, 0.5, 0], null],
[new Mesh(lineGeometry, matGreen), null, null],
[new Sprite(spriteGreen), [0, 1.55, 0]],
],
Z: [
[new Mesh(arrowGeometry, matBlue), [0, 0, 0.5], [Math.PI / 2, 0, 0]],
[new Mesh(lineGeometry, matBlue), null, [Math.PI / 2, 0, 0]],
[new Sprite(spriteBlue), [0, 0, 1.55]],
],
};
Object.keys(axesMap).forEach((key) => {
axesMap[key].forEach((objects: any) => {
const object = objects[0];
const position = objects[1];
const rotation = objects[2];
object.name = key;
if (position) object.position.set(position[0], position[1], position[2]);
if (rotation) object.rotation.set(rotation[0], rotation[1], rotation[2]);
object.updateMatrixWorld();
this.add(object);
});
});
}
dispose() {
this.traverse((object: any) => {
if (object.geometry) object.geometry.dispose();
if (object.material) object.material.dispose();
});
}
getSpriteMaterial(color: Color, text: string) {
const canvas = document.createElement("canvas");
canvas.width = 64;
canvas.height = 64;
const context = canvas.getContext("2d");
context.clearRect(0, 0, 64, 64);
context.font = "24px Arial";
context.textAlign = "center";
context.fillStyle = color.getStyle();
context.fillText(text, 32, 41);
const texture = new CanvasTexture(canvas);
texture.colorSpace = SRGBColorSpace;
return new SpriteMaterial({ map: texture, toneMapped: false });
}
render(renderer: WebGLRenderer) {
this.quaternion.copy(this.camera.quaternion).invert();
this.updateMatrixWorld();
const oldAutoClear = renderer.autoClear;
const oldClippingPlanes = renderer.clippingPlanes;
const oldViewport = renderer.getViewport(new Vector4());
renderer.autoClear = false;
renderer.clippingPlanes = [];
renderer.setViewport(this.position.x, this.position.y, this.size, this.size);
renderer.clearDepth();
renderer.render(this, this.orthoCamera);
renderer.setViewport(oldViewport);
renderer.clippingPlanes = oldClippingPlanes;
renderer.autoClear = oldAutoClear;
}
}