UNPKG

awv3

Version:
156 lines (138 loc) 6 kB
import * as THREE from 'three'; import Plugin from '../../session/plugin'; import { buildFeaturePath, normalizeName } from '../../session/helpers'; import { Slider, Spacer, Group, Button, Input, Label, Selection, Checkbox, Dropdown, Console } from '../../session/elements'; const resources = ['csys'].reduce((prev, item) => ({ ...prev, [item]: require('!!url-loader!awv3-icons/32x32/' + item + '.png') }), {}); export default class Csys extends Plugin { static persistent = true; constructor(session, args) { super(session, { type: 'Csys', icon: 'csys', resources, ...args }); this.origin = new Selection(this, { name: 'Origin', types: ['Point'] }); this.axis = new Selection(this, { name: 'Axis', types: ['Mesh', 'LineSegments'] }); this.secondary = new Selection(this, { name: 'Secondary', types: ['Mesh', 'LineSegments'] }); this.refsGroup = new Group(this, { format: Group.Format.Table, children: [this.origin, this.axis, this.secondary] }); this.collapse = new Group(this, { name: 'References', children: [this.refsGroup], format: Group.Format.Collapse }); this.addElement(this.collapse); this.offsetInput = new Input(this, { name: 'Offset', value: '0,0,0', format: Input.Format.Vector }); this.sliderX = new Slider(this, { name: 'Rotation X', max: 360, step: 10, positions: { 0: '0°', 90: '90°', 180: '180°', 270: '270°', 360: '360°' } }); this.sliderY = new Slider(this, { name: 'Rotation Y', max: 360, step: 10, positions: { 0: '0°', 90: '90°', 180: '180°', 270: '270°', 360: '360°' } }); this.sliderZ = new Slider(this, { name: 'Rotation Z', max: 360, step: 10, positions: { 0: '0°', 90: '90°', 180: '180°', 270: '270°', 360: '360°' } }); this.main = new Group(this, { format: Group.Format.Table, children: [this.offsetInput, this.sliderX, this.sliderY, this.sliderZ] }); this.addElement(this.main); let coords = args.feature.coordinateSystem; this.position = new THREE.Vector3(...coords[0]); this.rotation = new THREE.Euler(); let x = new THREE.Vector3(...coords[1]); let y = new THREE.Vector3(...coords[2]); let m = new THREE.Matrix4().makeBasis(x, y, x.clone().cross(y)); this.xAxis = m; this.yAxis = new THREE.Matrix4(); this.offset = new THREE.Vector3(); this.csys = new THREE.AxisHelper(this.pool.getRadius() / 5); this.csys.interactive = false; this.csys.matrixAutoUpdate = false; this.pool.add(this.csys); this.translate(); } onEnabled() { this.apply.observe(state => state.lastEvent, async event => { let feature = this.tree[this.feature]; let xAxis = new THREE.Vector3(), yAxis = new THREE.Vector3(), zAxis = new THREE.Vector3(); this.csys.matrix.extractBasis(xAxis, yAxis, zAxis); let pos = new THREE.Vector3().setFromMatrixPosition(this.csys.matrix); let path = buildFeaturePath(this.tree, feature.id); await this.connection.execute(`${path}.SetName("${feature.name}");`); path = buildFeaturePath(this.tree, feature.id); this.connection.execute( `${path}.OBJ_SetCoordSystem({${pos.toArray().join(',')}},{${xAxis .toArray() .join(',')}},{${yAxis.toArray().join(',')}});` ); this.connection.recalc(); }); this.origin.observe(state => state.children, selection => { if (selection.length) { this.position = this.session.selector.getSelectedElements()[0].meta.position; this.translate(); } }); this.sliderX.observe(state => state.value, value => { this.rotation.x = value * Math.PI / 180; this.translate(); }); this.sliderY.observe(state => state.value, value => { this.rotation.y = value * Math.PI / 180; this.translate(); }); this.sliderZ.observe(state => state.value, value => { this.rotation.z = value * Math.PI / 180; this.translate(); }); this.offsetInput.observe(state => state.value, value => { this.offset = new THREE.Vector3(...value.split(',')); this.translate(); }); this.axis.observe(state => state.children, selection => this.rotate(selection, 'x')); this.secondary.observe(state => state.children, selection => this.rotate(selection, 'y')); } onDestroyed() { this.csys.destroy(); } translate() { this.csys.matrix = new THREE.Matrix4() .setPosition(this.position) .multiply(this.xAxis) .multiply(this.yAxis) .multiply(new THREE.Matrix4().makeRotationFromEuler(this.rotation)) .multiply(new THREE.Matrix4().makeTranslation(...this.offset.toArray())); this.pool.view.invalidate(); } rotate(selection, whichAxis) { if (selection.length) { let meta = this.session.selector.getSelectedElements()[0].meta; if (meta.type === 'line') var dir = meta.end.clone().sub(meta.start.clone()).normalize(); else if (meta.type === 'plane') var dir = meta.normal.clone(); let axis = whichAxis === 'x' ? new THREE.Vector3(1, 0, 0) : new THREE.Vector3(0, 1, 0); let rotAxis = axis.clone().cross(dir).normalize(); let angle = axis.angleTo(dir); this[`${whichAxis}Axis`] = new THREE.Matrix4().makeRotationAxis(rotAxis, angle); this.translate(); } } }