2021-04-01 06:03:35 +08:00
|
|
|
import * as THREE from '../node_modules/three/src/Three';
|
2021-03-31 07:20:24 +08:00
|
|
|
|
2021-04-19 15:30:29 +08:00
|
|
|
import { Sketch } from './Sketch'
|
2021-04-16 08:05:40 +08:00
|
|
|
import { extrude, flipBufferGeometryNormals } from './extrude'
|
2021-04-17 17:54:41 +08:00
|
|
|
import { onHover, onPick, clearSelection } from './mouseEvents';
|
2021-04-23 05:14:26 +08:00
|
|
|
import { _vec2, _vec3, color, awaitSelection, setHover, custPtMat } from './shared'
|
2021-04-11 07:16:08 +08:00
|
|
|
import { AxesHelper } from './axes'
|
2021-04-08 15:33:18 +08:00
|
|
|
|
2021-04-07 03:46:16 +08:00
|
|
|
|
2021-04-20 09:31:32 +08:00
|
|
|
import { TrackballControls } from '../extlib/trackball'
|
|
|
|
import CSG from "../extlib/three-csg"
|
|
|
|
import { STLExporter } from '../extlib/stl'
|
2021-04-03 03:33:09 +08:00
|
|
|
|
2021-04-16 16:12:10 +08:00
|
|
|
|
2021-04-20 09:11:28 +08:00
|
|
|
let stats
|
|
|
|
if (process.env.NODE_ENV !== 'production') {
|
2021-04-20 09:31:32 +08:00
|
|
|
const { default: d } = require('../extlib/stats.module.js')
|
2021-04-20 09:11:28 +08:00
|
|
|
stats = new d();
|
2021-04-26 14:04:24 +08:00
|
|
|
// document.getElementById('stats').appendChild(stats.dom);
|
2021-04-20 09:11:28 +08:00
|
|
|
}
|
|
|
|
|
2021-03-31 07:20:24 +08:00
|
|
|
|
2021-04-01 13:35:08 +08:00
|
|
|
window.loader = new THREE.ObjectLoader();
|
2021-04-17 21:32:14 +08:00
|
|
|
window.STLexp = new STLExporter();
|
|
|
|
|
2021-04-07 05:10:07 +08:00
|
|
|
window.id = 0
|
2021-04-16 08:05:40 +08:00
|
|
|
|
|
|
|
|
2021-03-31 07:20:24 +08:00
|
|
|
|
2021-04-01 08:04:14 +08:00
|
|
|
export class Scene {
|
2021-03-31 07:20:24 +08:00
|
|
|
constructor(store) {
|
2021-04-16 08:05:40 +08:00
|
|
|
this.sid = 1
|
|
|
|
this.mid = 1
|
2021-03-31 07:20:24 +08:00
|
|
|
|
|
|
|
this.canvas = document.querySelector('#c');
|
2021-04-08 06:50:53 +08:00
|
|
|
|
|
|
|
this.rect = this.canvas.getBoundingClientRect().toJSON()
|
|
|
|
|
2021-04-11 07:16:08 +08:00
|
|
|
this.renderer = new THREE.WebGLRenderer({ canvas: this.canvas });
|
2021-04-19 11:53:02 +08:00
|
|
|
this.store = store
|
2021-03-31 07:20:24 +08:00
|
|
|
|
|
|
|
const size = 1;
|
2021-04-21 18:54:57 +08:00
|
|
|
const near = -1;
|
|
|
|
const far = 1000;
|
2021-03-31 07:20:24 +08:00
|
|
|
this.camera = new THREE.OrthographicCamera(-size, size, size, -size, near, far);
|
2021-04-21 18:54:57 +08:00
|
|
|
this.camera.zoom = 0.008;
|
|
|
|
const cameraDist = 500
|
2021-04-07 02:31:14 +08:00
|
|
|
const xzAngle = 30 * Math.PI / 180
|
|
|
|
this.camera.position.set(
|
|
|
|
cameraDist * Math.sin(xzAngle),
|
|
|
|
cameraDist * Math.tan(30 * Math.PI / 180),
|
|
|
|
cameraDist * Math.cos(xzAngle)
|
|
|
|
);
|
2021-03-31 07:20:24 +08:00
|
|
|
|
2021-04-22 12:39:23 +08:00
|
|
|
this.camera.layers.enable(3)
|
|
|
|
|
2021-04-23 05:14:26 +08:00
|
|
|
this.controls = new TrackballControls(this.camera, this.canvas);
|
|
|
|
this.controls.target.set(0, 0, 0);
|
|
|
|
this.controls.update();
|
2021-03-31 07:20:24 +08:00
|
|
|
|
2021-04-19 03:14:01 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.obj3d = new THREE.Scene() ///////
|
2021-03-31 07:20:24 +08:00
|
|
|
|
2021-04-11 07:16:08 +08:00
|
|
|
// this.obj3d.background = new THREE.Color(color.background);
|
2021-03-31 07:20:24 +08:00
|
|
|
const helpersGroup = new THREE.Group();
|
2021-04-11 07:16:08 +08:00
|
|
|
helpersGroup.name = "helpers";
|
2021-04-01 13:35:08 +08:00
|
|
|
this.obj3d.add(helpersGroup);
|
2021-03-31 07:20:24 +08:00
|
|
|
|
2021-04-07 02:31:14 +08:00
|
|
|
|
2021-04-11 07:16:08 +08:00
|
|
|
for (let i = 0; i < 4; i++) {
|
2021-04-16 08:05:40 +08:00
|
|
|
const freePt = new THREE.Points(
|
|
|
|
new THREE.BufferGeometry().setAttribute('position',
|
|
|
|
new THREE.Float32BufferAttribute(3, 3)
|
|
|
|
),
|
2021-04-23 05:14:26 +08:00
|
|
|
// pointMaterial.clone()
|
|
|
|
custPtMat.clone()
|
2021-04-16 08:05:40 +08:00
|
|
|
)
|
|
|
|
|
2021-04-10 16:45:15 +08:00
|
|
|
freePt.matrixAutoUpdate = false
|
|
|
|
freePt.visible = false
|
2021-04-23 05:26:46 +08:00
|
|
|
freePt.renderOrder=1
|
|
|
|
// freePt.depthTest = false
|
2021-04-11 07:16:08 +08:00
|
|
|
freePt.userData.type = 'selpoint'
|
2021-04-10 16:45:15 +08:00
|
|
|
helpersGroup.add(freePt);
|
|
|
|
}
|
2021-04-15 10:11:55 +08:00
|
|
|
this.selpoints = this.obj3d.children[0].children
|
2021-04-10 16:45:15 +08:00
|
|
|
this.fptIdx = 0;
|
|
|
|
this.fptObj = {}
|
2021-04-07 02:31:14 +08:00
|
|
|
|
|
|
|
|
2021-04-21 18:54:57 +08:00
|
|
|
const planeGeom = new THREE.PlaneGeometry(50, 50)
|
2021-03-31 07:20:24 +08:00
|
|
|
const pxy = new THREE.Mesh(
|
2021-04-07 02:31:14 +08:00
|
|
|
planeGeom,
|
2021-03-31 07:20:24 +08:00
|
|
|
new THREE.MeshBasicMaterial({
|
2021-04-05 11:52:17 +08:00
|
|
|
color: color.plane,
|
2021-04-11 07:16:08 +08:00
|
|
|
opacity: 0.02,
|
2021-03-31 07:20:24 +08:00
|
|
|
side: THREE.DoubleSide,
|
|
|
|
transparent: true,
|
|
|
|
depthWrite: false,
|
|
|
|
toneMapped: false
|
|
|
|
})
|
|
|
|
);
|
2021-04-07 02:31:14 +08:00
|
|
|
pxy.add(
|
|
|
|
new THREE.LineSegments(
|
|
|
|
new THREE.EdgesGeometry(planeGeom),
|
|
|
|
new THREE.LineBasicMaterial({ color: color.planeBorder })
|
|
|
|
)
|
|
|
|
)
|
2021-04-11 07:16:08 +08:00
|
|
|
pxy.userData.type = 'plane'
|
|
|
|
pxy.layers.enable(1)
|
|
|
|
pxy.children[0].layers.disable(1)
|
2021-03-31 07:20:24 +08:00
|
|
|
const pyz = pxy.clone().rotateY(Math.PI / 2);
|
|
|
|
const pxz = pxy.clone().rotateX(-Math.PI / 2);
|
2021-04-07 02:31:14 +08:00
|
|
|
helpersGroup.add(pxy);
|
2021-04-11 07:16:08 +08:00
|
|
|
[pxz, pyz].forEach(e => {
|
|
|
|
e.traverse(f => f.material = f.material.clone())
|
|
|
|
helpersGroup.add(e);
|
|
|
|
});
|
2021-03-31 07:20:24 +08:00
|
|
|
|
2021-04-11 07:16:08 +08:00
|
|
|
this.axes = new AxesHelper(this.camera.zoom)
|
|
|
|
this.axes.visible = false
|
|
|
|
helpersGroup.add(this.axes);
|
2021-03-31 07:20:24 +08:00
|
|
|
|
|
|
|
|
2021-04-21 18:54:57 +08:00
|
|
|
const dist = 500
|
2021-04-13 20:39:20 +08:00
|
|
|
const light1 = new THREE.PointLight(color.lighting, 0.7);
|
2021-04-11 07:16:08 +08:00
|
|
|
light1.position.set(dist, dist, dist);
|
2021-04-11 07:50:12 +08:00
|
|
|
helpersGroup.add(light1);
|
2021-04-13 20:39:20 +08:00
|
|
|
const light2 = new THREE.PointLight(color.lighting, 0.7);
|
2021-04-11 07:16:08 +08:00
|
|
|
light2.position.set(-dist, -dist, -dist);
|
2021-04-11 07:50:12 +08:00
|
|
|
helpersGroup.add(light2);
|
2021-03-31 07:20:24 +08:00
|
|
|
|
|
|
|
|
2021-04-26 14:04:24 +08:00
|
|
|
this.render = render.bind(this)
|
|
|
|
this.addSketch = addSketch.bind(this)
|
|
|
|
this.onHover = onHover.bind(this)
|
|
|
|
this.onPick = onPick.bind(this)
|
|
|
|
this.clearSelection = clearSelection.bind(this)
|
|
|
|
this.setHover = setHover.bind(this)
|
|
|
|
this.awaitSelection = awaitSelection.bind(this)
|
|
|
|
this.extrude = this.extrude.bind(this)
|
|
|
|
|
2021-03-31 07:20:24 +08:00
|
|
|
|
2021-04-01 13:35:08 +08:00
|
|
|
this.obj3d.addEventListener('change', this.render);
|
2021-04-23 05:14:26 +08:00
|
|
|
this.controls.addEventListener('change', this.render);
|
|
|
|
this.controls.addEventListener('start', this.render);
|
2021-03-31 07:20:24 +08:00
|
|
|
window.addEventListener('resize', this.render);
|
|
|
|
|
2021-04-20 09:11:28 +08:00
|
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
|
|
this.stats = stats
|
|
|
|
}
|
|
|
|
|
2021-03-31 07:20:24 +08:00
|
|
|
|
|
|
|
|
|
|
|
this.hovered = [];
|
2021-04-05 11:52:17 +08:00
|
|
|
this.activeSketch = null;
|
2021-03-31 07:20:24 +08:00
|
|
|
|
2021-04-26 14:04:24 +08:00
|
|
|
this.selected = [];
|
|
|
|
this.mode = '';
|
|
|
|
this.store.subscribe(this.reduxCallback.bind(this))
|
|
|
|
|
2021-03-31 07:20:24 +08:00
|
|
|
this.render();
|
|
|
|
}
|
2021-04-01 06:03:35 +08:00
|
|
|
|
2021-04-26 14:04:24 +08:00
|
|
|
reduxCallback() {
|
|
|
|
const currSelected = this.store.getState().ui.selectedList
|
|
|
|
const currMode = this.store.getState().ui.mode
|
|
|
|
if (currSelected !== this.selected) {
|
|
|
|
this.selected = currSelected
|
|
|
|
}
|
|
|
|
if (currMode !== this.mode) {
|
|
|
|
this.mode = currMode
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-04-19 06:05:33 +08:00
|
|
|
|
|
|
|
|
2021-04-01 06:03:35 +08:00
|
|
|
resizeCanvas(renderer) {
|
|
|
|
const canvas = renderer.domElement;
|
|
|
|
const width = canvas.clientWidth;
|
|
|
|
const height = canvas.clientHeight;
|
|
|
|
const needResize = canvas.width !== width || canvas.height !== height;
|
|
|
|
if (needResize) {
|
|
|
|
renderer.setSize(width, height, false);
|
|
|
|
}
|
|
|
|
return needResize;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-04-19 03:14:01 +08:00
|
|
|
clearScene() {
|
|
|
|
const deleted = this.obj3d.children.splice(1)
|
|
|
|
|
|
|
|
for (let i = 0; i < deleted.length; i++) {
|
|
|
|
deleted[i].traverse((obj) => {
|
|
|
|
if (obj.geometry) obj.geometry.dispose()
|
|
|
|
if (obj.material) obj.material.dispose()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-19 06:05:33 +08:00
|
|
|
newPart() {
|
|
|
|
this.clearScene()
|
|
|
|
window.id = 0
|
|
|
|
this.sid = 1
|
|
|
|
this.mid = 1
|
|
|
|
}
|
|
|
|
|
2021-04-19 03:14:01 +08:00
|
|
|
loadState(file) { //uglyyy
|
|
|
|
|
|
|
|
this.clearScene()
|
|
|
|
|
2021-04-16 08:05:40 +08:00
|
|
|
const [curid, cursid, curmid, state] = JSON.parse(
|
2021-04-19 03:14:01 +08:00
|
|
|
file
|
2021-04-01 06:03:35 +08:00
|
|
|
)
|
|
|
|
|
2021-04-07 05:10:07 +08:00
|
|
|
window.id = curid
|
2021-04-16 08:05:40 +08:00
|
|
|
this.sid = cursid
|
|
|
|
this.mid = curmid
|
2021-04-01 06:03:35 +08:00
|
|
|
|
2021-04-16 08:05:40 +08:00
|
|
|
const entries = state.byId
|
2021-04-01 13:35:08 +08:00
|
|
|
for (let k in entries) {
|
2021-04-01 06:03:35 +08:00
|
|
|
|
2021-04-04 12:54:27 +08:00
|
|
|
if (k[0] == 's') {
|
2021-04-01 13:35:08 +08:00
|
|
|
entries[k].obj3d = loader.parse(entries[k].obj3d)
|
|
|
|
this.obj3d.add(entries[k].obj3d)
|
2021-04-17 13:58:54 +08:00
|
|
|
entries[k] = new Sketch(this, entries[k])
|
2021-04-01 13:35:08 +08:00
|
|
|
entries[k].obj3d.addEventListener('change', this.render) // !! took 3 hours to realize
|
|
|
|
|
2021-04-16 08:05:40 +08:00
|
|
|
} else if (k[0] == 'e') {
|
|
|
|
|
|
|
|
entries[k] = loader.parse(state.byId[k])
|
2021-04-17 07:03:30 +08:00
|
|
|
|
2021-04-16 08:05:40 +08:00
|
|
|
if (entries[k].userData.inverted) {
|
|
|
|
flipBufferGeometryNormals(entries[k].geometry)
|
2021-04-17 07:03:30 +08:00
|
|
|
}
|
2021-04-16 08:05:40 +08:00
|
|
|
|
|
|
|
this.obj3d.add(entries[k])
|
|
|
|
|
|
|
|
} else {
|
|
|
|
entries[k] = loader.parse(state.byId[k])
|
2021-04-01 06:03:35 +08:00
|
|
|
|
2021-04-01 13:35:08 +08:00
|
|
|
this.obj3d.add(entries[k])
|
2021-04-01 06:03:35 +08:00
|
|
|
|
2021-04-01 13:35:08 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-16 08:05:40 +08:00
|
|
|
return state
|
2021-04-01 06:03:35 +08:00
|
|
|
}
|
|
|
|
|
2021-04-17 13:58:54 +08:00
|
|
|
loadSketch(string) {
|
|
|
|
let entry = JSON.parse(string)
|
|
|
|
entry.obj3d = loader.parse(entry.obj3d)
|
|
|
|
|
2021-04-17 21:32:14 +08:00
|
|
|
// this.obj3d.add(entry.obj3d)
|
2021-04-17 13:58:54 +08:00
|
|
|
|
|
|
|
entry = new Sketch(this, entry)
|
|
|
|
entry.obj3d.addEventListener('change', this.render)
|
2021-04-17 17:09:35 +08:00
|
|
|
|
2021-04-17 13:58:54 +08:00
|
|
|
return entry
|
|
|
|
}
|
|
|
|
|
2021-04-19 06:05:33 +08:00
|
|
|
extrude(sketch, depth) {
|
|
|
|
const mesh = extrude(sketch, depth)
|
|
|
|
mesh.name = 'e' + this.mid++
|
|
|
|
|
|
|
|
this.obj3d.add(mesh)
|
|
|
|
|
2021-04-19 11:53:02 +08:00
|
|
|
return mesh
|
2021-04-19 06:05:33 +08:00
|
|
|
}
|
2021-04-10 16:45:15 +08:00
|
|
|
|
2021-04-19 11:53:02 +08:00
|
|
|
boolOp(m1, m2, op) {
|
2021-04-10 16:45:15 +08:00
|
|
|
let bspA = CSG.fromMesh(m1)
|
|
|
|
let bspB = CSG.fromMesh(m2)
|
2021-04-11 15:57:39 +08:00
|
|
|
m1.visible = false
|
|
|
|
m2.visible = false
|
|
|
|
m1.traverse(e => e.layers.disable(1))
|
|
|
|
m2.traverse(e => e.layers.disable(1))
|
2021-04-11 07:16:08 +08:00
|
|
|
|
|
|
|
|
2021-04-13 09:37:16 +08:00
|
|
|
let bspResult, opChar;
|
|
|
|
switch (op) {
|
|
|
|
case 's':
|
|
|
|
bspResult = bspA.subtract(bspB)
|
|
|
|
opChar = "-"
|
|
|
|
break;
|
|
|
|
case 'u':
|
|
|
|
bspResult = bspA.union(bspB)
|
|
|
|
opChar = "\u222a"
|
|
|
|
break;
|
|
|
|
case 'i':
|
|
|
|
bspResult = bspA.intersect(bspB)
|
|
|
|
opChar = "\u2229"
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2021-04-11 07:16:08 +08:00
|
|
|
|
2021-04-10 16:45:15 +08:00
|
|
|
let mesh = CSG.toMesh(bspResult, m1.matrix, m1.material)
|
|
|
|
mesh.userData.type = 'mesh'
|
2021-04-16 08:05:40 +08:00
|
|
|
mesh.userData.featureInfo = [m1.name, m2.name, op]
|
2021-04-13 09:37:16 +08:00
|
|
|
|
2021-04-16 08:05:40 +08:00
|
|
|
mesh.name = `(${m1.name} ${opChar} ${m2.name})`
|
2021-04-10 18:53:44 +08:00
|
|
|
mesh.layers.enable(1)
|
2021-04-11 07:16:08 +08:00
|
|
|
|
2021-04-23 18:54:55 +08:00
|
|
|
const vertices = new THREE.Points(mesh.geometry, new THREE.PointsMaterial());
|
|
|
|
vertices.visible = false
|
2021-04-10 16:45:15 +08:00
|
|
|
vertices.userData.type = 'point'
|
|
|
|
vertices.layers.enable(1)
|
2021-04-11 07:16:08 +08:00
|
|
|
|
2021-04-10 16:45:15 +08:00
|
|
|
mesh.add(vertices)
|
2021-04-11 07:16:08 +08:00
|
|
|
|
2021-04-19 11:53:02 +08:00
|
|
|
return mesh
|
2021-04-17 07:03:30 +08:00
|
|
|
|
|
|
|
}
|
2021-04-11 15:57:39 +08:00
|
|
|
|
2021-04-19 11:53:02 +08:00
|
|
|
refreshNode(id, { byId, tree }) {
|
2021-04-17 07:03:30 +08:00
|
|
|
let curId
|
|
|
|
let que = [id]
|
|
|
|
let idx = 0
|
2021-04-19 06:05:33 +08:00
|
|
|
// let newNodes = {}
|
2021-04-17 07:03:30 +08:00
|
|
|
|
|
|
|
while (idx < que.length) {
|
|
|
|
curId = que[idx++]
|
2021-04-11 15:57:39 +08:00
|
|
|
|
2021-04-19 06:05:33 +08:00
|
|
|
if (byId[curId].userData) { // if it is a mesh
|
2021-04-17 17:54:41 +08:00
|
|
|
const info = byId[curId].userData.featureInfo
|
|
|
|
let newNode
|
|
|
|
if (info.length == 2) {
|
2021-04-19 06:05:33 +08:00
|
|
|
newNode = extrude(byId[info[0]], info[1])
|
2021-04-17 17:54:41 +08:00
|
|
|
} else if (info.length == 3) {
|
2021-04-19 11:53:02 +08:00
|
|
|
newNode = this.boolOp(byId[info[0]], byId[info[1]], info[2])
|
2021-04-17 17:54:41 +08:00
|
|
|
}
|
|
|
|
byId[curId].geometry.copy(newNode.geometry)
|
2021-04-19 06:05:33 +08:00
|
|
|
byId[curId].geometry.parameters = newNode.geometry.parameters // took 2 hours to figure out
|
|
|
|
|
2021-04-17 17:54:41 +08:00
|
|
|
}
|
2021-04-17 07:03:30 +08:00
|
|
|
|
|
|
|
for (let k in tree[curId]) {
|
|
|
|
que.push(k)
|
|
|
|
}
|
|
|
|
}
|
2021-04-19 06:05:33 +08:00
|
|
|
|
2021-04-10 16:45:15 +08:00
|
|
|
}
|
2021-04-17 07:03:30 +08:00
|
|
|
|
2021-03-31 07:20:24 +08:00
|
|
|
}
|
|
|
|
|
2021-04-05 11:52:17 +08:00
|
|
|
|
|
|
|
let idx, x, y, ele, pos, dims, matrix;
|
2021-03-31 07:20:24 +08:00
|
|
|
function render() {
|
2021-04-20 09:11:28 +08:00
|
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
|
|
this.stats.begin();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-03-31 07:20:24 +08:00
|
|
|
if (this.resizeCanvas(this.renderer)) {
|
|
|
|
const canvas = this.renderer.domElement;
|
|
|
|
this.camera.left = -canvas.clientWidth / canvas.clientHeight;
|
|
|
|
this.camera.right = canvas.clientWidth / canvas.clientHeight;
|
|
|
|
this.camera.updateProjectionMatrix();
|
2021-04-08 06:50:53 +08:00
|
|
|
|
2021-04-23 05:14:26 +08:00
|
|
|
this.controls.handleResize()
|
2021-04-08 06:50:53 +08:00
|
|
|
Object.assign(this.rect, this.canvas.getBoundingClientRect().toJSON())
|
|
|
|
|
2021-03-31 07:20:24 +08:00
|
|
|
}
|
2021-04-08 15:33:18 +08:00
|
|
|
|
|
|
|
|
2021-04-11 07:16:08 +08:00
|
|
|
if (this.axes) this.axes.resize(this.camera.zoom)
|
2021-04-08 15:33:18 +08:00
|
|
|
|
2021-04-01 13:35:08 +08:00
|
|
|
this.renderer.render(this.obj3d, this.camera);
|
2021-04-05 11:52:17 +08:00
|
|
|
|
|
|
|
if (this.activeSketch) {
|
2021-04-16 08:05:40 +08:00
|
|
|
dims = this.activeSketch.dimGroup.children
|
2021-04-05 11:52:17 +08:00
|
|
|
matrix = this.activeSketch.obj3d.matrix
|
|
|
|
|
|
|
|
for (idx = 1; idx < dims.length; idx += 2) {
|
|
|
|
ele = dims[idx]
|
|
|
|
|
|
|
|
pos = _vec3.set(
|
|
|
|
...ele.geometry.attributes.position.array
|
|
|
|
).applyMatrix4(matrix).project(this.camera)
|
|
|
|
|
2021-04-09 07:05:52 +08:00
|
|
|
x = (pos.x * .5 + .5) * this.canvas.clientWidth + 10 + this.rect.left;
|
|
|
|
y = (pos.y * -.5 + .5) * this.canvas.clientHeight + this.rect.top;
|
2021-04-07 02:31:14 +08:00
|
|
|
|
2021-04-05 11:52:17 +08:00
|
|
|
ele.label.style.transform = `translate(0%, -50%) translate(${x}px,${y}px)`;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-04-20 09:11:28 +08:00
|
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
|
|
this.stats.end();
|
|
|
|
}
|
2021-03-31 07:20:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-04-19 15:30:29 +08:00
|
|
|
function addSketch() {
|
2021-04-03 03:33:09 +08:00
|
|
|
|
2021-04-04 12:54:27 +08:00
|
|
|
let sketch;
|
2021-03-31 07:20:24 +08:00
|
|
|
|
2021-04-20 09:11:28 +08:00
|
|
|
if (this.selected.length == 3 && this.selected.every(e => e.userData.type == 'selpoint')) {
|
2021-04-08 06:50:53 +08:00
|
|
|
sketch = new Sketch(this)
|
2021-04-04 17:36:41 +08:00
|
|
|
this.obj3d.add(sketch.obj3d)
|
2021-04-01 13:35:08 +08:00
|
|
|
sketch.align(
|
2021-04-19 15:30:29 +08:00
|
|
|
...this.selected.map(
|
2021-04-07 03:46:16 +08:00
|
|
|
el => new THREE.Vector3(...el.geometry.attributes.position.array).applyMatrix4(el.matrixWorld)
|
2021-03-31 07:20:24 +08:00
|
|
|
)
|
|
|
|
)
|
2021-04-19 15:30:29 +08:00
|
|
|
} else if (this.selected.length && this.selected[0].userData.type == 'plane') {
|
|
|
|
sketch = new Sketch(this)
|
|
|
|
sketch.obj3d.matrix = this.selected[0].matrix
|
|
|
|
sketch.plane.applyMatrix4(sketch.obj3d.matrix)
|
|
|
|
sketch.obj3d.inverse = sketch.obj3d.matrix.clone().invert()
|
|
|
|
this.obj3d.add(sketch.obj3d)
|
|
|
|
|
|
|
|
} else {
|
|
|
|
return
|
2021-03-31 07:20:24 +08:00
|
|
|
}
|
|
|
|
|
2021-04-19 15:30:29 +08:00
|
|
|
this.newSketch = true
|
2021-04-04 12:54:27 +08:00
|
|
|
|
2021-04-07 02:31:14 +08:00
|
|
|
this.clearSelection()
|
2021-04-01 13:35:08 +08:00
|
|
|
sketch.obj3d.addEventListener('change', this.render);
|
2021-04-19 11:53:02 +08:00
|
|
|
return sketch
|
2021-03-31 07:20:24 +08:00
|
|
|
}
|
|
|
|
|
2021-04-24 04:13:49 +08:00
|
|
|
// window.sc = new Scene(store)
|