three.cad/src/Scene.js

237 lines
5.8 KiB
JavaScript
Raw Normal View History

2021-03-31 07:20:24 +08:00
2021-04-01 06:03:35 +08:00
// import * as THREE from 'three/src/Three';
import * as THREE from '../node_modules/three/src/Three';
2021-03-31 07:20:24 +08:00
// import { OrbitControls } from './utils/OrbitControls'
import { TrackballControls } from './utils/trackball'
2021-04-01 13:35:08 +08:00
import { Sketch } from './sketcher/Sketch'
2021-03-31 07:20:24 +08:00
import Stats from './utils/stats.module.js';
import { add3DPoint } from './datums'
import { extrude } from './extrude'
import { onHover, onPick } from './utils/mouseEvents';
2021-04-03 03:33:09 +08:00
import { _vec2, _vec3, color, awaitPts } from './utils/shared'
2021-03-31 07:20:24 +08:00
import { Vector3 } from 'three/src/Three';
2021-04-04 12:54:27 +08:00
import { AxesHelper } from './utils/axes'
2021-03-31 07:20:24 +08:00
2021-03-31 16:07:34 +08:00
import CSG from "./utils/three-csg.js"
2021-04-03 03:33:09 +08:00
window.BoolOp = CSG
2021-03-31 07:20:24 +08:00
const eq = (a1, a2) => {
if (a1.length != a2.length) return false
for (let i = 0; i < a1.length; i++) {
if (a1[i] != a2[i]) return false
}
return true
}
2021-04-01 13:35:08 +08:00
window.loader = new THREE.ObjectLoader();
2021-04-01 06:03:35 +08:00
window.nid = 0
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-01 06:03:35 +08:00
this.store = store;
2021-03-31 07:20:24 +08:00
this.canvas = document.querySelector('#c');
this.renderer = new THREE.WebGLRenderer({ canvas: this.canvas });
const size = 1;
const near = 0;
const far = 100;
this.camera = new THREE.OrthographicCamera(-size, size, size, -size, near, far);
this.camera.zoom = 0.1;
this.camera.position.set(50, 50, 50);
// const controls = new OrbitControls(camera, view1Elem);
const controls = new TrackballControls(this.camera, this.canvas);
controls.target.set(0, 0, 0);
controls.update();
2021-04-01 13:35:08 +08:00
this.obj3d = new THREE.Scene()
2021-03-31 07:20:24 +08:00
2021-04-01 13:35:08 +08:00
this.obj3d.background = new THREE.Color(0x888888);
2021-03-31 07:20:24 +08:00
const helpersGroup = new THREE.Group();
helpersGroup.name = "helpersGroup";
2021-04-01 13:35:08 +08:00
this.obj3d.add(helpersGroup);
const axesHelper = new AxesHelper(0.4);
2021-03-31 07:20:24 +08:00
helpersGroup.add(axesHelper);
2021-03-31 16:07:34 +08:00
// console.log(color)
2021-03-31 07:20:24 +08:00
const pxy = new THREE.Mesh(
new THREE.PlaneGeometry(5, 5),
new THREE.MeshBasicMaterial({
2021-04-01 06:03:35 +08:00
color: color.d,
2021-03-31 07:20:24 +08:00
opacity: 0.2,
side: THREE.DoubleSide,
transparent: true,
depthWrite: false,
toneMapped: false
})
);
2021-04-01 06:03:35 +08:00
pxy.name = 'd' + nid++
2021-03-31 07:20:24 +08:00
helpersGroup.add(pxy);
const pyz = pxy.clone().rotateY(Math.PI / 2);
pyz.material = pyz.material.clone();
const pxz = pxy.clone().rotateX(-Math.PI / 2);
pxz.material = pxz.material.clone();
helpersGroup.add(pyz);
helpersGroup.add(pxz);
const intensity = 1;
2021-03-31 16:07:34 +08:00
const light1 = new THREE.DirectionalLight(color.lighting, intensity);
2021-03-31 07:20:24 +08:00
light1.position.set(10, 10, 10);
2021-04-01 13:35:08 +08:00
this.obj3d.add(light1);
2021-03-31 07:20:24 +08:00
2021-03-31 16:07:34 +08:00
const light2 = new THREE.DirectionalLight(color.lighting, intensity);
2021-03-31 07:20:24 +08:00
light2.position.set(-10, -10, -5);
2021-04-01 13:35:08 +08:00
this.obj3d.add(light2);
2021-03-31 16:07:34 +08:00
const ambient = new THREE.AmbientLight(color.lighting, intensity);
2021-04-01 13:35:08 +08:00
this.obj3d.add(ambient);
2021-03-31 07:20:24 +08:00
this.render = render.bind(this);
this.addSketch = addSketch.bind(this);
this.extrude = extrude.bind(this);
this.onHover = onHover.bind(this);
this.onPick = onPick.bind(this);
2021-04-03 03:33:09 +08:00
this.awaitPts = awaitPts.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-03-31 07:20:24 +08:00
controls.addEventListener('change', this.render);
controls.addEventListener('start', this.render);
window.addEventListener('resize', this.render);
this.stats = new Stats();
this.stats.showPanel(0); // 0: fps, 1: ms, 2: mb, 3+: custom
document.getElementById('stats').appendChild(this.stats.dom);
this.hovered = [];
this.selected = [];
this.render();
}
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;
}
saveState() {
localStorage.setItem(
2021-04-01 13:35:08 +08:00
'sv', JSON.stringify([nid, this.store.getState()])
2021-04-01 06:03:35 +08:00
)
}
2021-04-01 13:35:08 +08:00
loadState() { //uglyyy
const [curNid, state] = JSON.parse(
2021-04-01 06:03:35 +08:00
localStorage.getItem('sv')
)
2021-04-01 13:35:08 +08:00
window.nid = curNid
2021-04-01 06:03:35 +08:00
2021-04-01 13:35:08 +08:00
const entries = state.treeEntries.byNid
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)
entries[k] = new Sketch(this.camera, this.canvas, this.store, state.treeEntries.byNid[k])
entries[k].obj3d.addEventListener('change', this.render) // !! took 3 hours to realize
} else if (k[0] == 'm') {
2021-04-01 06:03:35 +08:00
2021-04-01 13:35:08 +08:00
entries[k] = loader.parse(state.treeEntries.byNid[k])
this.obj3d.add(entries[k])
2021-04-01 06:03:35 +08:00
2021-04-01 13:35:08 +08:00
}
}
this.store.dispatch({ type: 'restore-state', state })
2021-04-01 06:03:35 +08:00
}
2021-03-31 07:20:24 +08:00
}
function render() {
this.stats.begin();
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-01 13:35:08 +08:00
this.renderer.render(this.obj3d, this.camera);
2021-03-31 07:20:24 +08:00
this.stats.end();
}
2021-04-03 03:33:09 +08:00
2021-03-31 07:20:24 +08:00
async 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-04 17:36:41 +08:00
const references = await this.awaitPts({ p: 3 }, { d: 1 });
if (!references) return;
if (references[0].name[0] == 'd') {
2021-04-04 12:54:27 +08:00
sketch = new Sketch(this.camera, this.canvas, this.store)
2021-04-04 17:36:41 +08:00
sketch.obj3d.matrix = references[0].matrix
2021-04-01 13:35:08 +08:00
sketch.plane.applyMatrix4(sketch.obj3d.matrix)
sketch.obj3d.inverse = sketch.obj3d.matrix.clone().invert()
2021-04-04 17:36:41 +08:00
this.obj3d.add(sketch.obj3d)
2021-04-04 12:54:27 +08:00
} else {
sketch = new Sketch(this.camera, this.canvas, this.store)
2021-04-04 17:36:41 +08:00
this.obj3d.add(sketch.obj3d)
2021-04-01 13:35:08 +08:00
sketch.align(
2021-03-31 07:20:24 +08:00
...references.map(
el => new Vector3(...el.geometry.attributes.position.array).applyMatrix4(el.matrixWorld)
)
)
}
2021-04-04 12:54:27 +08:00
2021-04-01 13:35:08 +08:00
sketch.activate()
2021-04-04 12:54:27 +08:00
2021-04-01 13:35:08 +08:00
sketch.obj3d.addEventListener('change', this.render);
2021-03-31 07:20:24 +08:00
this.render()
2021-04-04 12:54:27 +08:00
console.log('render')
2021-04-01 13:35:08 +08:00
this.store.dispatch({ type: 'rx-sketch', obj: sketch })
2021-03-31 07:20:24 +08:00
}
2021-04-02 08:19:14 +08:00
window.sc = new Scene(store)
2021-04-03 03:33:09 +08:00
// sc.loadState()
2021-03-31 16:07:34 +08:00
2021-04-01 06:03:35 +08:00
2021-03-31 16:07:34 +08:00
2021-04-01 06:03:35 +08:00
2021-03-31 16:07:34 +08:00
2021-03-31 07:20:24 +08:00