UNPKG

mlightcad

Version:

A highly customizable standalone view cube addon for three.js

146 lines (124 loc) 3.85 kB
import * as THREE from 'three' import { createTextSprite } from './viewCubeData' import { FixedPosGizmo, ObjectPosition } from './fixedPosGizmo' /** * Options to customize axes */ export interface AxesOptions { /** * Position of axes */ pos?: ObjectPosition /** * Size of area ocupied by view cube. Because width and height of this area is same, it is single value. * The real size of view cube will be calculated automatically considering rotation. */ size?: number /** * Flag to show z-axis */ hasZAxis?: boolean } /** * Default axes option values */ export const DEFAULT_AXES_OPTIONS: AxesOptions = { pos: ObjectPosition.LEFT_BOTTOM, size: 100, hasZAxis: true } /** * An axis gizmo to visualize the axes in a simple way. * The X axis is red, the Y axis is green, and the Z axis is blue by default */ export class AxesGizmo extends FixedPosGizmo { private axes: THREE.LineSegments private xText: THREE.Sprite private yText: THREE.Sprite private zText?: THREE.Sprite private hasZAxis: boolean constructor( camera: THREE.PerspectiveCamera | THREE.OrthographicCamera, renderer: THREE.WebGLRenderer, options: AxesOptions ) { const mergedOptions: AxesOptions = { ...DEFAULT_AXES_OPTIONS, ...options } super(camera, renderer, mergedOptions.size, options.pos) this.hasZAxis = mergedOptions.hasZAxis! const vertices = [0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0] const colors = [1, 0, 0, 1, 0.6, 0, 0, 1, 0, 0.6, 1, 0] if (this.hasZAxis) { vertices.push(0, 0, 0, 0, 0, 2) colors.push(0, 0, 1, 0, 0.6, 1) } const geometry = new THREE.BufferGeometry() geometry.setAttribute( 'position', new THREE.Float32BufferAttribute(vertices, 3) ) geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3)) const material = new THREE.LineBasicMaterial({ vertexColors: true, toneMapped: false }) this.axes = new THREE.LineSegments(geometry, material) this.axes.position.set(-1, -1, -1) this.add(this.axes) this.xText = createTextSprite('X') this.xText.position.set(1.5, -1, -1) this.add(this.xText) this.yText = createTextSprite('Y') this.yText.position.set(-1, 1.5, -1) this.add(this.yText) if (this.hasZAxis) { this.zText = createTextSprite('Z') this.zText.position.set(-1, -1, 1.5) this.add(this.zText) } } /** * Set color of x-axis and y-axis * @param xAxisColor color of x-axis * @param yAxisColor color of y-axis */ setLineColors(xAxisColor: THREE.Color, yAxisColor: THREE.Color) { const color = new THREE.Color() const array = this.axes.geometry.attributes.color.array color.set(xAxisColor) color.toArray(array, 0) color.toArray(array, 3) color.set(yAxisColor) color.toArray(array, 6) color.toArray(array, 9) this.axes.geometry.attributes.color.needsUpdate = true return this } /** * Set text color * @param color text color */ setTextColor(color: THREE.Color) { this.xText.material.color = color this.yText.material.color = color } /** * Free the GPU-related resources allocated by this instance. Call this method whenever this instance * is no longer used in your app. */ dispose() { this.axes.geometry.dispose() const material = this.axes.material as THREE.LineBasicMaterial material.dispose() this.xText.geometry.dispose() this.xText.material.dispose() this.yText.geometry.dispose() this.yText.material.dispose() if (this.hasZAxis) { this.zText?.geometry.dispose() this.zText?.material.dispose() } } }