awv3
Version:
⚡ AWV3 embedded CAD
140 lines (123 loc) • 4.92 kB
JavaScript
import * as THREE from 'three';
import Object3 from '../../../three/object3';
import Ccref from '../ccref';
import Snapper from '../snapper';
export default class BaseHandler {
constructor(sketcher, name) {
this.sketcher = sketcher;
this.sketch = sketcher.activeSketch;
this.name = name;
this.interactions = new Map();
this.destroyed = false;
// bind this.on* to this and don't trigger event callbacks after destruction
const onKeyUp = this.onKeyUp, onKeyDown = this.onKeyDown, onMouseMove = this.onMouseMove;
this.onKeyUp = event => this.destroyed || onKeyUp.call(this, event);
this.onKeyDown = event => this.destroyed || onKeyDown.call(this, event);
if (this.onMouseMove) this.onMouseMove = event => this.destroyed || onMouseMove.call(this, event);
}
destroy(options) {
this.destroyed = true;
this.removeInteractions(options);
}
filterObjectsWithInteraction(object) {
return false;
}
addInteraction(object) {
if (!this.filterObjectsWithInteraction(object)) return;
const interactionListeners = {};
for (let event of Object.values(Object3.Events.Interaction))
if (this[event]) interactionListeners[event] = this[event].bind(this, object);
this.interactions.set(object.id, interactionListeners);
object.graphics
.createInteraction({ recursive: true, first: false, types: ['InfinitePlane', 'SketcherMesh'] })
.on(interactionListeners, {sync: true});
// prioritize sketch points in interaction if there is overlapping
if (object.isPoint()) object.graphics.interaction.priority = 1;
}
addInteractions() {
for (let object of this.sketch.descendants)
this.addInteraction(object);
this.sketcher.view.input.on('keyup', this.onKeyUp);
this.sketcher.view.input.on('keydown', this.onKeyDown);
if (this.onMouseMove) this.sketcher.view.input.on('mousemove', this.onMouseMove);
}
removeInteraction(object) {
const interactionListeners = this.interactions.get(object.id);
this.interactions.delete(object.id);
if (object.graphics) {
object.graphics.removeListener(interactionListeners);
object.graphics.removeInteraction();
}
}
removeInteractions() {
if (this.onMouseMove) this.sketcher.view.input.removeListener('mousemove', this.onMouseMove);
this.sketcher.view.input.removeListener('keydown', this.onKeyDown);
this.sketcher.view.input.removeListener('keyup', this.onKeyUp);
for (let id of this.interactions.keys())
this.removeInteraction(new Ccref(this.sketcher, id));
}
cancel() {
// switch to drag handler by default
this.sketcher.namedElements.handlers.drag.value = true;
}
onKeyUp(event) {
switch (event.which) {
case 27: // escape
this.cancel();
break;
case 46: // delete
this.sketcher.deleteSelected({ onlyIfConsoleIsEmpty: true });
break;
}
}
onKeyDown(event) {}
createSnapper() {
return new Snapper({
sketch: this.sketch,
gridStep: this.sketcher.gridStep,
pointRadius: this.sketcher.graphicScale,
});
}
//note: can be called in (view.input.on + 'mousemove') callback
//in order to get current sketch coordinates of the mouse
getRecentMousePosition() {
const mousemove = this.sketcher.view.input.recent.mousemove;
const point2 = new THREE.Vector2(mousemove.offsetX, mousemove.offsetY);
const line3 = this.sketcher.view.getViewLine3(point2);
const ray = new THREE.Ray(line3.start, line3.end.sub(line3.start).normalize());
ray.applyMatrix4(new THREE.Matrix4().getInverse(this.sketch.matrixWorld));
const plane = new THREE.Plane(new THREE.Vector3(0, 0, 1));
const result = new THREE.Vector3();
ray.intersectPlane(plane, result);
ray.direction.negate();
ray.intersectPlane(plane, result);
return result;
}
consoleComplete(cmd) {
return Object.keys(commands);
}
consoleExecute(cmd) {
// watch out for cmd === '__proto__' which could access the prototype
if (commands.hasOwnProperty(cmd)) {
this.sketcher.namedElements.handlers[commands[cmd]].value = true;
return true;
} else {
return false;
}
}
parseRestrictions(cmd) {}
}
const commands = Object.freeze({
point: 'point',
pt: 'point',
line: 'line',
ln: 'line',
arccenter: 'arccenter',
ac: 'arccenter',
arcmiddle: 'arcmiddle',
am: 'arcmiddle',
arctangent: 'arctangent',
at: 'arctangent',
circle: 'circle',
cr: 'circle',
});