three.cad/src/mouseEvents.js
2021-04-21 21:39:23 -07:00

282 lines
7.0 KiB
JavaScript

import * as THREE from '../node_modules/three/src/Three';
import { raycaster, setHover } from './shared';
import { onDimMoveEnd } from './drawDimension'
let ptLoc
export function onHover(e) {
// if ((this.mode && this.mode != 'dimension' && !this.snap) || e.buttons) return
if (e.buttons) return
raycaster.setFromCamera(
new THREE.Vector2(
(e.clientX - this.rect.left) / this.rect.width * 2 - 1,
- (e.clientY - this.rect.top) / this.rect.height * 2 + 1
),
this.camera
);
let hoverPts;
if (this.obj3d.userData.type != 'sketch') {
this.selpoints[0].visible = false // hide selpoint[0] before each redraw
raycaster.layers.set(1)
hoverPts = raycaster.intersectObjects(this.obj3d.children, true)
} else {
raycaster.layers.set(2)
// intersectObjects has side effect of updating bounding spheres
// which may lead to unexpected results if you leave boundspheres un-updated
hoverPts = raycaster.intersectObjects([...this.dimGroup.children, ...this.obj3d.children])
}
let idx = []
const thresh = this.snap ? 1 : 0.0001
if (hoverPts.length) {
// console.log('here', hoverPts)
let minDist = Infinity;
for (let i = 0; i < hoverPts.length; i++) {
if (!hoverPts[i].distanceToRay) continue;
if (hoverPts[i].distanceToRay < minDist - thresh) {
idx = [i]
if (this.obj3d.userData.type != 'sketch') break
minDist = hoverPts[i].distanceToRay
} else if (hoverPts[i].distanceToRay < minDist + thresh) {
idx.push(i)
}
}
if (!idx.length && !this.snap) {
idx.push(0)
}
}
if (idx.length) { // after filtering, if hovered objs still exists
// console.log(idx)
if (hoverPts[idx[0]].object != this.hovered[0]) { // if the previous hovered obj is not the same as current
for (let x = 0; x < this.hovered.length; x++) { // first clear old hovers that are not selected
const obj = this.hovered[x]
if (typeof obj == 'object' && !this.selected.includes(obj)) {
setHover(obj, 0)
}
}
this.hovered = []
for (let x = 0; x < idx.length; x++) {
let obj = hoverPts[idx[x]].object
setHover(obj, 1, false)
if (this.obj3d.userData.type != 'sketch' && obj.userData.type == 'point') {
ptLoc = obj.geometry.attributes.position.array
.slice(
3 * hoverPts[idx[x]].index,
3 * hoverPts[idx[x]].index + 3
)
this.selpoints[0].geometry.attributes.position.array.set(ptLoc)
this.selpoints[0].matrix = obj.parent.matrix
this.selpoints[0].geometry.attributes.position.needsUpdate = true
this.selpoints[0].visible = true
obj = hoverPts[idx[x]].index
}
this.hovered.push(obj)
}
// console.log('render1')
this.obj3d.dispatchEvent({ type: 'change' })
}
} else { // no hovered object after filtering
if (this.hovered.length) { // if previously something was hovered, then we need to clear it
for (let x = 0; x < this.hovered.length; x++) {
const obj = this.hovered[x]
if (typeof obj == 'object' && !this.selected.includes(obj)) {
setHover(obj, 0)
}
}
this.hovered = []
// console.log('render2')
this.obj3d.dispatchEvent({ type: 'change' })
}
}
}
let draggedLabel;
export function onPick(e) {
if ((this.mode && this.mode != 'dimension') || e.buttons != 1) return
if (this.hovered.length) {
let obj = this.hovered[this.hovered.length - 1]
// if (sc.selected.includes(obj3d)) continue
if (typeof obj != 'object') { // special sketchplace define pts in feature mode
const pp = this.selpoints[this.fptIdx % 3 + 1]
const p0 = this.selpoints[0]
pp.geometry.attributes.position.array.set(p0.geometry.attributes.position.array)
pp.matrix = p0.matrix
pp.geometry.attributes.position.needsUpdate = true
pp.visible = true
obj = pp
this.fptIdx++
const idx = this.selected.indexOf(obj)
if (idx == -1) {
this.selected.push(
obj
)
} else {
this.selected.splice(idx, 1, obj)
}
} else {
const idx = this.selected.indexOf(obj)
if (idx == -1) {
this.selected.push(
obj
)
this.setHover(obj, 1)
} else {
this.setHover(this.selected[idx], 0)
this.selected.splice(idx, 1)
}
}
this.obj3d.dispatchEvent({ type: 'change' })
if (this.obj3d.userData.type != 'sketch') {
return;
}
switch (obj.userData.type) {
case 'dimension':
const idx = this.dimGroup.children.indexOf(this.hovered[0])
if (idx % 2) { // we only allow tag point (odd idx) to be dragged
this.onDragDim = this._onMoveDimension(
this.dimGroup.children[idx],
this.dimGroup.children[idx - 1],
)
this.canvas.addEventListener('pointermove', this.onDragDim);
this.canvas.addEventListener('pointerup', () => {
onDimMoveEnd(this.dimGroup.children[idx])
this.onRelease()
})
}
draggedLabel = this.dimGroup.children[idx].label
draggedLabel.style.zIndex = -1;
break;
case 'point':
this.canvas.addEventListener('pointermove', this.onDrag);
this.canvas.addEventListener('pointerup', this.onRelease)
break;
default:
break;
}
} else {
for (let x = 0; x < this.selected.length; x++) {
const obj = this.selected[x]
setHover(obj, 0)
if (obj.userData.type == 'selpoint') {
obj.visible = false
}
// dont think this would have been possible without redux
if (obj.userData.type == 'sketch' && !sc.store.getState().treeEntries.visible[obj.name]) {
obj.visible = false
}
}
this.obj3d.dispatchEvent({ type: 'change' })
this.selected = []
}
}
export function onDrag(e) {
// const obj = this.hovered[this.hovered.length-1]
// this.ptsBuf.set(
// this.getLocation(e).toArray(),
// this.objIdx.get(obj.name) * 3
// )
for (let x = 0; x < this.hovered.length; x++) {
const obj = this.hovered[x]
this.ptsBuf.set(
this.getLocation(e).toArray(),
this.objIdx.get(obj.name) * 3
)
}
this.solve()
this.scene.render()
}
export function onRelease(e) {
this.canvas.removeEventListener('pointermove', this.onDrag)
this.canvas.removeEventListener('pointermove', this.onDragDim)
this.canvas.removeEventListener('pointerup', this.onRelease)
this.updateBoundingSpheres()
if (draggedLabel) {
draggedLabel.style.zIndex = 0;
}
}
export function clearSelection() {
for (let x = 0, obj; x < this.selected.length; x++) {
obj = this.selected[x]
if (obj.userData.type == 'selpoint') {
obj.visible = false
} else {
setHover(obj, 0)
}
}
this.selected = []
for (let x = 0; x < this.hovered.length; x++) {
const obj = this.hovered[x]
setHover(obj, 0)
}
}