chkpt
parent
1a602c5f58
commit
6e9359138f
|
@ -40,7 +40,7 @@
|
||||||
<canvas id="c"></canvas>
|
<canvas id="c"></canvas>
|
||||||
<div id="stats"></div>
|
<div id="stats"></div>
|
||||||
<script src="index.bundle.js"></script>
|
<script src="index.bundle.js"></script>
|
||||||
<script src="renderer.bundle.js"></script>
|
<script src="scene.bundle.js"></script>
|
||||||
<script src="solver.js"></script>
|
<script src="solver.js"></script>
|
||||||
<script src="lz-string.min.js"></script>
|
<script src="lz-string.min.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
143
src/Renderer.js
143
src/Renderer.js
|
@ -1,143 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import * as THREE from '../node_modules/three/src/Three';
|
|
||||||
// import { OrbitControls } from './utils/OrbitControls'
|
|
||||||
import { TrackballControls } from './utils/trackball'
|
|
||||||
import { Sketcher } from './sketcher/Sketcher'
|
|
||||||
import Stats from './utils/stats.module.js';
|
|
||||||
|
|
||||||
import { add3DPoint } from './datums'
|
|
||||||
import { extrude } from './sketcher/extrude'
|
|
||||||
import { onHover } from './mouseEvents';
|
|
||||||
|
|
||||||
|
|
||||||
// class Scene extends THREE.Scene {
|
|
||||||
|
|
||||||
|
|
||||||
// constructor() {
|
|
||||||
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
export function Renderer(store) {
|
|
||||||
this.store = store
|
|
||||||
this.stats = new Stats();
|
|
||||||
this.stats.showPanel(0); // 0: fps, 1: ms, 2: mb, 3+: custom
|
|
||||||
document.getElementById('stats').appendChild(this.stats.dom);
|
|
||||||
|
|
||||||
this.canvas = document.querySelector('#c');
|
|
||||||
this.renderer = new THREE.WebGLRenderer({ canvas: this.canvas });
|
|
||||||
|
|
||||||
this.scene = new THREE.Scene();
|
|
||||||
this.raycaster = new THREE.Raycaster();
|
|
||||||
|
|
||||||
window.scene = this.scene;
|
|
||||||
this.scene.background = new THREE.Color(0x888888);
|
|
||||||
// this.scene.background = new THREE.Color(0xffffff);
|
|
||||||
|
|
||||||
const helpersGroup = new THREE.Group();
|
|
||||||
helpersGroup.name = "helpersGroup"
|
|
||||||
this.scene.add(helpersGroup);
|
|
||||||
const axesHelper = new THREE.AxesHelper(5);
|
|
||||||
helpersGroup.add(axesHelper);
|
|
||||||
|
|
||||||
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(0, 0, 50);
|
|
||||||
|
|
||||||
// const controls = new OrbitControls(camera, view1Elem);
|
|
||||||
const controls = new TrackballControls(this.camera, this.canvas);
|
|
||||||
controls.target.set(0, 0, 0);
|
|
||||||
controls.update()
|
|
||||||
|
|
||||||
const color = 0xFFFFFF;
|
|
||||||
const intensity = 1;
|
|
||||||
const light1 = new THREE.DirectionalLight(color, intensity);
|
|
||||||
light1.position.set(10, 10, 10);
|
|
||||||
this.scene.add(light1);
|
|
||||||
|
|
||||||
const light2 = new THREE.DirectionalLight(color, intensity);
|
|
||||||
light2.position.set(-10, -10, -5);
|
|
||||||
this.scene.add(light2);
|
|
||||||
const ambient = new THREE.AmbientLight(color, intensity);
|
|
||||||
this.scene.add(ambient);
|
|
||||||
|
|
||||||
|
|
||||||
this.hovered = []
|
|
||||||
this.selected = new Set()
|
|
||||||
|
|
||||||
this.render = render.bind(this)
|
|
||||||
this.resizeCanvas = resizeCanvas.bind(this)
|
|
||||||
this.addSketch = addSketch.bind(this)
|
|
||||||
this.extrude = extrude.bind(this)
|
|
||||||
|
|
||||||
this.onHover = onHover.bind(this);
|
|
||||||
|
|
||||||
controls.addEventListener('change', this.render);
|
|
||||||
controls.addEventListener('start', this.render);
|
|
||||||
window.addEventListener('resize', this.render);
|
|
||||||
this.render()
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
this.renderer.render(scene, this.camera);
|
|
||||||
this.stats.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
function 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
async function addSketch() {
|
|
||||||
|
|
||||||
const result = []
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
const pt = await new Promise((res, rej) => {
|
|
||||||
this.canvas.addEventListener('pointerdown', (e) => res(getPoint(e, this.camera)), { once: true })
|
|
||||||
})
|
|
||||||
result.push(pt)
|
|
||||||
}
|
|
||||||
|
|
||||||
const sketcher = new Sketcher(this.camera, this.canvas, this.store)
|
|
||||||
this.scene.add(sketcher)
|
|
||||||
|
|
||||||
sketcher.align(...result)
|
|
||||||
|
|
||||||
sketcher.activate()
|
|
||||||
sketcher.addEventListener('change', this.render);
|
|
||||||
|
|
||||||
window.sketcher = sketcher
|
|
||||||
|
|
||||||
this.render()
|
|
||||||
this.store.dispatch({ type: 'rx-sketch', obj: sketcher })
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function getPoint(e, camera) {
|
|
||||||
const mouse = new THREE.Vector2(
|
|
||||||
(e.clientX / window.innerWidth) * 2 - 1,
|
|
||||||
- (e.clientY / window.innerHeight) * 2 + 1
|
|
||||||
)
|
|
||||||
return new THREE.Vector3(mouse.x, mouse.y, 0).unproject(camera)
|
|
||||||
}
|
|
||||||
|
|
||||||
window.renderInst = new Renderer(store);
|
|
|
@ -0,0 +1,201 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import * as THREE from 'three/src/Three';
|
||||||
|
// import { OrbitControls } from './utils/OrbitControls'
|
||||||
|
import { TrackballControls } from './utils/trackball'
|
||||||
|
import { Sketcher } from './sketcher/Sketcher'
|
||||||
|
import Stats from './utils/stats.module.js';
|
||||||
|
|
||||||
|
import { add3DPoint } from './datums'
|
||||||
|
import { extrude } from './extrude'
|
||||||
|
import { onHover, onPick } from './utils/mouseEvents';
|
||||||
|
import { _vec2, _vec3 } from './utils/static'
|
||||||
|
import { Vector3 } from 'three/src/Three';
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export class Scene extends THREE.Scene {
|
||||||
|
constructor(store) {
|
||||||
|
super()
|
||||||
|
this.name = 'Scene'
|
||||||
|
this.store = store;
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
|
||||||
|
this.background = new THREE.Color(0x888888);
|
||||||
|
const helpersGroup = new THREE.Group();
|
||||||
|
helpersGroup.name = "helpersGroup";
|
||||||
|
this.add(helpersGroup);
|
||||||
|
const axesHelper = new THREE.AxesHelper(0.4);
|
||||||
|
helpersGroup.add(axesHelper);
|
||||||
|
|
||||||
|
const pxy = new THREE.Mesh(
|
||||||
|
new THREE.PlaneGeometry(5, 5),
|
||||||
|
new THREE.MeshBasicMaterial({
|
||||||
|
color: 0xff0000,
|
||||||
|
opacity: 0.2,
|
||||||
|
side: THREE.DoubleSide,
|
||||||
|
transparent: true,
|
||||||
|
depthWrite: false,
|
||||||
|
toneMapped: false
|
||||||
|
})
|
||||||
|
);
|
||||||
|
pxy.name = "Plane"
|
||||||
|
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 color = 0xFFFFFF;
|
||||||
|
const intensity = 1;
|
||||||
|
const light1 = new THREE.DirectionalLight(color, intensity);
|
||||||
|
light1.position.set(10, 10, 10);
|
||||||
|
this.add(light1);
|
||||||
|
|
||||||
|
const light2 = new THREE.DirectionalLight(color, intensity);
|
||||||
|
light2.position.set(-10, -10, -5);
|
||||||
|
this.add(light2);
|
||||||
|
const ambient = new THREE.AmbientLight(color, intensity);
|
||||||
|
this.add(ambient);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
this.render = render.bind(this);
|
||||||
|
this.resizeCanvas = resizeCanvas.bind(this);
|
||||||
|
this.addSketch = addSketch.bind(this);
|
||||||
|
this.extrude = extrude.bind(this);
|
||||||
|
this.onHover = onHover.bind(this);
|
||||||
|
this.onPick = onPick.bind(this);
|
||||||
|
|
||||||
|
this.addEventListener('change', this.render);
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
this.renderer.render(this, this.camera);
|
||||||
|
this.stats.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
function 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function addSketch() {
|
||||||
|
let references = this.selected.slice()
|
||||||
|
|
||||||
|
if (references.length == 0) {
|
||||||
|
while (references.length < 3) {
|
||||||
|
let pt;
|
||||||
|
try {
|
||||||
|
pt = await new Promise((res, rej) => {
|
||||||
|
this.canvas.addEventListener('pointerdown', () => res(this.hovered[0]), { once: true })
|
||||||
|
window.addEventListener('keydown', (e) => rej(e), { once: true })
|
||||||
|
})
|
||||||
|
|
||||||
|
if (pt.type == 'Points') {
|
||||||
|
references.push(pt)
|
||||||
|
} else if (pt.name == 'Plane') {
|
||||||
|
references = [pt]
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
if (e.key == 'Escape') {
|
||||||
|
console.log('cancelled')
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const sketcher = new Sketcher(this.camera, this.canvas, this.store)
|
||||||
|
|
||||||
|
if (references.length == 1 && references[0].name == 'Plane') {
|
||||||
|
this.add(sketcher)
|
||||||
|
sketcher.matrix = references[0].matrix
|
||||||
|
sketcher.plane.applyMatrix4(sketcher.matrix)
|
||||||
|
sketcher.inverse = sketcher.matrix.clone().invert()
|
||||||
|
|
||||||
|
} else if (references.length == 3) {
|
||||||
|
this.add(sketcher)
|
||||||
|
sketcher.align(
|
||||||
|
...references.map(
|
||||||
|
el => new Vector3(...el.geometry.attributes.position.array).applyMatrix4(el.matrixWorld)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
console.log('cancelled')
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sketcher.activate()
|
||||||
|
sketcher.addEventListener('change', this.render);
|
||||||
|
this.render()
|
||||||
|
this.store.dispatch({ type: 'rx-sketch', obj: sketcher })
|
||||||
|
|
||||||
|
window.sketcher = sketcher
|
||||||
|
}
|
||||||
|
|
||||||
|
window.sc = new Scene(store);
|
||||||
|
|
17
src/app.jsx
17
src/app.jsx
|
@ -4,7 +4,7 @@ import React, { useEffect, useState } from 'react';
|
||||||
import './app.scss'
|
import './app.scss'
|
||||||
|
|
||||||
import { Provider, useDispatch, useSelector } from 'react-redux'
|
import { Provider, useDispatch, useSelector } from 'react-redux'
|
||||||
// import { renderInst } from './index'
|
// import { sc } from './index'
|
||||||
|
|
||||||
export const Root = ({ store }) => (
|
export const Root = ({ store }) => (
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
|
@ -15,7 +15,8 @@ export const Root = ({ store }) => (
|
||||||
|
|
||||||
|
|
||||||
function treeId2Obj(id) {
|
function treeId2Obj(id) {
|
||||||
return renderInst.scene.getObjectById(parseInt(id.slice(1)))
|
// return sc.scene.getObjectById(parseInt(id.slice(1)))
|
||||||
|
return sc.getObjectById(parseInt(id.slice(1)))
|
||||||
}
|
}
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
|
@ -30,8 +31,12 @@ const App = () => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!activeSketch) {
|
if (!activeSketch) {
|
||||||
renderInst.canvas.addEventListener('pointermove', renderInst.onHover)
|
sc.canvas.addEventListener('pointermove', sc.onHover)
|
||||||
return () => renderInst.canvas.removeEventListener('pointermove', renderInst.onHover)
|
sc.canvas.addEventListener('pointerdown', sc.onPick)
|
||||||
|
return () => {
|
||||||
|
sc.canvas.removeEventListener('pointermove', sc.onHover)
|
||||||
|
sc.canvas.removeEventListener('pointerdown', sc.onPick)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [activeSketch])
|
}, [activeSketch])
|
||||||
|
|
||||||
|
@ -42,9 +47,9 @@ const App = () => {
|
||||||
<button onClick={() => treeId2Obj(activeSketch).deactivate()}>
|
<button onClick={() => treeId2Obj(activeSketch).deactivate()}>
|
||||||
Exit sketch
|
Exit sketch
|
||||||
</button> :
|
</button> :
|
||||||
<button onClick={renderInst.addSketch}> addsketch </button>
|
<button onClick={sc.addSketch}> addsketch </button>
|
||||||
}
|
}
|
||||||
<button onClick={() => renderInst.extrude(treeId2Obj(activeSketch))}> extrude </button>
|
<button onClick={() => sc.extrude(treeId2Obj(activeSketch))}> extrude </button>
|
||||||
{/* <button onClick={() => setState('')}> test </button> */}
|
{/* <button onClick={() => setState('')}> test </button> */}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ export function add3DPoint(e) {
|
||||||
if (hoverPts[idx[0]].object != this.hovered[0]) {
|
if (hoverPts[idx[0]].object != this.hovered[0]) {
|
||||||
|
|
||||||
for (let ob of this.hovered) {
|
for (let ob of this.hovered) {
|
||||||
if (ob && !this.selected.has(ob)) {
|
if (ob && !this.selected.includes(ob)) {
|
||||||
ob.material.color.set(0x555555)
|
ob.material.color.set(0x555555)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ export function add3DPoint(e) {
|
||||||
} else {
|
} else {
|
||||||
if (this.hovered.length) {
|
if (this.hovered.length) {
|
||||||
for (let ob of this.hovered) {
|
for (let ob of this.hovered) {
|
||||||
if (ob && !this.selected.has(ob)) {
|
if (ob && !this.selected.includes(ob)) {
|
||||||
ob.material.color.set(0x555555)
|
ob.material.color.set(0x555555)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import * as THREE from '../../node_modules/three/src/Three';
|
import * as THREE from 'three/src/Three';
|
||||||
import { pointMaterial } from '../utils/static'
|
import { color, ptObj } from './utils/static'
|
||||||
export function extrude(sketch) {
|
export function extrude(sketch) {
|
||||||
|
|
||||||
let constraints = sketch.constraints;
|
let constraints = sketch.constraints;
|
||||||
|
@ -8,13 +8,13 @@ export function extrude(sketch) {
|
||||||
let objIdx = sketch.objIdx;
|
let objIdx = sketch.objIdx;
|
||||||
let visited = new Set()
|
let visited = new Set()
|
||||||
let v2s = []
|
let v2s = []
|
||||||
|
let offSetPts = []
|
||||||
|
|
||||||
function findPair(node) {
|
function findPair(node) {
|
||||||
visited.add(node)
|
visited.add(node)
|
||||||
let linkedObj = linkedObjs.get(node.l_id)
|
let linkedObj = linkedObjs.get(node.l_id)
|
||||||
let arr;
|
let arr;
|
||||||
if (linkedObj[0] == 'line') {
|
if (linkedObj[0] == 'line') {
|
||||||
// console.log(children, objIdx, linkedObj)
|
|
||||||
arr = children[objIdx.get(linkedObj[1][2])].geometry.attributes.position.array
|
arr = children[objIdx.get(linkedObj[1][2])].geometry.attributes.position.array
|
||||||
} else if (linkedObj[0] == 'arc') {
|
} else if (linkedObj[0] == 'arc') {
|
||||||
arr = children[objIdx.get(linkedObj[1][3])].geometry.attributes.position.array
|
arr = children[objIdx.get(linkedObj[1][3])].geometry.attributes.position.array
|
||||||
|
@ -23,6 +23,9 @@ export function extrude(sketch) {
|
||||||
v2s.push(new THREE.Vector2(arr[i], arr[i + 1]))
|
v2s.push(new THREE.Vector2(arr[i], arr[i + 1]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
offSetPts.push(arr[0], arr[1])
|
||||||
|
offSetPts.push(arr[arr.length - 3], arr[arr.length - 2])
|
||||||
|
|
||||||
for (let i = 0; i < 2; i++) {
|
for (let i = 0; i < 2; i++) {
|
||||||
// let d = linkedObj[1][i]
|
// let d = linkedObj[1][i]
|
||||||
let d = children[objIdx.get(linkedObj[1][i])]
|
let d = children[objIdx.get(linkedObj[1][i])]
|
||||||
|
@ -60,21 +63,28 @@ export function extrude(sketch) {
|
||||||
const shape = new THREE.Shape(v2s);
|
const shape = new THREE.Shape(v2s);
|
||||||
const extrudeSettings = { depth: 8, bevelEnabled: false };
|
const extrudeSettings = { depth: 8, bevelEnabled: false };
|
||||||
const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
|
const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
|
||||||
const phong = new THREE.MeshPhongMaterial({ color: 0x156289, emissive: 0x072534, side: THREE.DoubleSide, flatShading: true });
|
const phong = new THREE.MeshPhongMaterial({
|
||||||
|
color: color.extrude,
|
||||||
|
emissive: color.emissive,
|
||||||
|
flatShading: true
|
||||||
|
});
|
||||||
const mesh = new THREE.Mesh(geometry, phong)
|
const mesh = new THREE.Mesh(geometry, phong)
|
||||||
// mesh.applyMatrix4(sketch.inverse)
|
|
||||||
// mesh.matrix.premultiply(sketch.matrix).multiply(sketch.inverse)
|
for (let i = 0; i < offSetPts.length; i += 2) {
|
||||||
|
if (
|
||||||
|
offSetPts[i] == offSetPts[i - 2] &&
|
||||||
|
offSetPts[i + 1] == offSetPts[i - 1]
|
||||||
|
) continue;
|
||||||
|
mesh.add(
|
||||||
|
ptObj([offSetPts[i], offSetPts[i + 1], 8])
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
mesh.matrixAutoUpdate = false;
|
mesh.matrixAutoUpdate = false;
|
||||||
mesh.matrix.multiply(sketch.matrix)
|
mesh.matrix.multiply(sketch.matrix)
|
||||||
this.scene.add(mesh)
|
this.add(mesh)
|
||||||
|
|
||||||
const wireframe = new THREE.WireframeGeometry(geometry);
|
|
||||||
|
|
||||||
const pts = new THREE.Points(wireframe, pointMaterial);
|
|
||||||
// pts.matrixAutoUpdate = false;
|
|
||||||
// pts.matrix.multiply(sketch.matrix)
|
|
||||||
mesh.add(pts)
|
|
||||||
|
|
||||||
this.render()
|
this.render()
|
||||||
|
|
|
@ -1,120 +0,0 @@
|
||||||
import * as THREE from 'three/src/Three';
|
|
||||||
import {raycaster} from './utils/static';
|
|
||||||
|
|
||||||
export function onHover(e) {
|
|
||||||
if (this.mode || e.buttons) return
|
|
||||||
raycaster.setFromCamera(
|
|
||||||
new THREE.Vector2(
|
|
||||||
(e.clientX / window.innerWidth) * 2 - 1,
|
|
||||||
- (e.clientY / window.innerHeight) * 2 + 1
|
|
||||||
),
|
|
||||||
this.camera
|
|
||||||
);
|
|
||||||
|
|
||||||
const hoverPts = raycaster.intersectObjects(this.scene.children)
|
|
||||||
|
|
||||||
|
|
||||||
let idx = []
|
|
||||||
if (hoverPts.length) {
|
|
||||||
|
|
||||||
let minDist = Infinity;
|
|
||||||
for (let i = 0; i < hoverPts.length; i++) {
|
|
||||||
if (!hoverPts[i].distanceToRay) continue;
|
|
||||||
if (hoverPts[i].distanceToRay < minDist) {
|
|
||||||
minDist = hoverPts[i].distanceToRay
|
|
||||||
idx = [i]
|
|
||||||
} else if (hoverPts[i].distanceToRay == minDist) {
|
|
||||||
idx.push(i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!idx.length) idx.push(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (idx.length) {
|
|
||||||
if (hoverPts[idx[0]].object != this.hovered[0]) {
|
|
||||||
|
|
||||||
for (let x = 0; x < this.hovered.length; x++) {
|
|
||||||
const obj = this.hovered[x]
|
|
||||||
if (obj && !this.selected.has(obj)) {
|
|
||||||
obj.material.color.set(0x555555)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.hovered = []
|
|
||||||
|
|
||||||
for (let x = 0; x < idx.length; x++) {
|
|
||||||
const i = idx[x]
|
|
||||||
hoverPts[i].object.material.color.set(0x00ff00)
|
|
||||||
this.hovered.push(hoverPts[i].object)
|
|
||||||
}
|
|
||||||
|
|
||||||
// console.log('render1')
|
|
||||||
this.render()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (this.hovered.length) {
|
|
||||||
|
|
||||||
for (let x = 0; x < this.hovered.length; x++) {
|
|
||||||
const obj = this.hovered[x]
|
|
||||||
if (obj && !this.selected.has(obj)) {
|
|
||||||
obj.material.color.set(0x555555)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.hovered = []
|
|
||||||
|
|
||||||
// console.log('render2')
|
|
||||||
this.render()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export function onPick(e) {
|
|
||||||
if (this.mode || e.buttons != 1) return
|
|
||||||
|
|
||||||
if (this.hovered.length) {
|
|
||||||
|
|
||||||
for (let x = 0; x < this.hovered.length; x++) {
|
|
||||||
const obj = this.hovered[x]
|
|
||||||
this.selected.add(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.hovered[0].type == "Points") {
|
|
||||||
this.domElement.addEventListener('pointermove', this.onDrag);
|
|
||||||
this.domElement.addEventListener('pointerup', this.onRelease)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (let obj of this.selected) {
|
|
||||||
obj.material.color.set(0x555555)
|
|
||||||
}
|
|
||||||
this.dispatchEvent({ type: 'change' })
|
|
||||||
this.selected.clear()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function onDrag(e) {
|
|
||||||
const mouseLoc = this.getLocation(e);
|
|
||||||
|
|
||||||
for (let x = 0; x < this.hovered.length; x++) {
|
|
||||||
const obj = this.hovered[x]
|
|
||||||
this.ptsBuf.set(
|
|
||||||
mouseLoc,
|
|
||||||
this.objIdx.get(obj.id) * 3
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.solve()
|
|
||||||
this.dispatchEvent({ type: 'change' })
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export function onRelease() {
|
|
||||||
this.domElement.removeEventListener('pointermove', this.onDrag)
|
|
||||||
this.domElement.removeEventListener('pointerup', this.onRelease)
|
|
||||||
|
|
||||||
for (let x = 0; x < this.hovered.length; x++) {
|
|
||||||
const obj = this.hovered[x]
|
|
||||||
obj.geometry.computeBoundingSphere()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,10 +3,9 @@
|
||||||
import * as THREE from '../../node_modules/three/src/Three';
|
import * as THREE from '../../node_modules/three/src/Three';
|
||||||
|
|
||||||
import { drawOnClick1, drawOnClick2, drawPreClick2, drawClear } from './drawEvents'
|
import { drawOnClick1, drawOnClick2, drawPreClick2, drawClear } from './drawEvents'
|
||||||
import { onHover, onDrag, onPick, onRelease } from './sketchMouseEvents'
|
import { onHover, onDrag, onPick, onRelease } from '../utils/mouseEvents'
|
||||||
import { addDimension, setCoincident } from './constraintEvents'
|
import { addDimension, setCoincident } from './constraintEvents'
|
||||||
import { get3PtArc } from './sketchArc'
|
import { get3PtArc } from './sketchArc'
|
||||||
import { extrude } from './extrude'
|
|
||||||
import { _vec2, _vec3, raycaster } from '../utils/static'
|
import { _vec2, _vec3, raycaster } from '../utils/static'
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,12 +14,12 @@ import { _vec2, _vec3, raycaster } from '../utils/static'
|
||||||
class Sketcher extends THREE.Group {
|
class Sketcher extends THREE.Group {
|
||||||
|
|
||||||
|
|
||||||
constructor(camera, domElement, store) {
|
constructor(camera, canvas, store) {
|
||||||
super()
|
super()
|
||||||
this.name = "sketch"
|
this.name = "Sketch"
|
||||||
this.matrixAutoUpdate = false;
|
this.matrixAutoUpdate = false;
|
||||||
this.camera = camera;
|
this.camera = camera;
|
||||||
this.domElement = domElement;
|
this.canvas = canvas;
|
||||||
this.store = store;
|
this.store = store;
|
||||||
|
|
||||||
this.sub = new THREE.Group();
|
this.sub = new THREE.Group();
|
||||||
|
@ -28,8 +27,12 @@ class Sketcher extends THREE.Group {
|
||||||
const axesHelper = new THREE.AxesHelper(2);
|
const axesHelper = new THREE.AxesHelper(2);
|
||||||
this.sub.add(axesHelper);
|
this.sub.add(axesHelper);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
this.plane = new THREE.Plane(new THREE.Vector3(0, 0, 1), 0);
|
this.plane = new THREE.Plane(new THREE.Vector3(0, 0, 1), 0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// [0]:x, [1]:y, [2]:z
|
// [0]:x, [1]:y, [2]:z
|
||||||
this.objIdx = new Map()
|
this.objIdx = new Map()
|
||||||
this.ptsBuf = new Float32Array(this.max_pts * 3).fill(NaN)
|
this.ptsBuf = new Float32Array(this.max_pts * 3).fill(NaN)
|
||||||
|
@ -47,7 +50,8 @@ class Sketcher extends THREE.Group {
|
||||||
this.bindHandlers()
|
this.bindHandlers()
|
||||||
|
|
||||||
|
|
||||||
this.selected = new Set()
|
// this.selected = new Set()
|
||||||
|
this.selected = []
|
||||||
this.hovered = []
|
this.hovered = []
|
||||||
this.mode = ""
|
this.mode = ""
|
||||||
this.subsequent = false;
|
this.subsequent = false;
|
||||||
|
@ -70,27 +74,25 @@ class Sketcher extends THREE.Group {
|
||||||
|
|
||||||
activate() {
|
activate() {
|
||||||
window.addEventListener('keydown', this.onKeyPress)
|
window.addEventListener('keydown', this.onKeyPress)
|
||||||
this.domElement.addEventListener('pointerdown', this.onPick)
|
this.canvas.addEventListener('pointerdown', this.onPick)
|
||||||
this.domElement.addEventListener('pointermove', this.onHover)
|
this.canvas.addEventListener('pointermove', this.onHover)
|
||||||
this.store.dispatch({ type: 'set-active-sketch', sketch: this })
|
this.store.dispatch({ type: 'set-active-sketch', sketch: this })
|
||||||
}
|
}
|
||||||
|
|
||||||
deactivate() {
|
deactivate() {
|
||||||
window.removeEventListener('keydown', this.onKeyPress)
|
window.removeEventListener('keydown', this.onKeyPress)
|
||||||
this.domElement.removeEventListener('pointerdown', this.onPick)
|
this.canvas.removeEventListener('pointerdown', this.onPick)
|
||||||
this.domElement.removeEventListener('pointermove', this.onHover)
|
this.canvas.removeEventListener('pointermove', this.onHover)
|
||||||
this.store.dispatch({ type: 'exit-sketch' })
|
this.store.dispatch({ type: 'exit-sketch' })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
align(origin, x_dir, y_dir) {
|
align(origin, x_dir, y_dir) {
|
||||||
// this.updateWorldMatrix(true, false);
|
const up = _vec3.subVectors(y_dir, origin).normalize();
|
||||||
const up = new THREE.Vector3().subVectors(y_dir, origin).normalize();
|
|
||||||
const _m1 = new THREE.Matrix4()
|
|
||||||
const te = _m1.elements;
|
const te = _m1.elements;
|
||||||
const _x = new THREE.Vector3().subVectors(x_dir, origin).normalize();
|
_x.subVectors(x_dir, origin).normalize();
|
||||||
const _z = new THREE.Vector3().crossVectors(_x, up).normalize();
|
_z.crossVectors(_x, up).normalize();
|
||||||
const _y = new THREE.Vector3().crossVectors(_z, _x);
|
_y.crossVectors(_z, _x);
|
||||||
|
|
||||||
te[0] = _x.x; te[4] = _y.x; te[8] = _z.x;
|
te[0] = _x.x; te[4] = _y.x; te[8] = _z.x;
|
||||||
te[1] = _x.y; te[5] = _y.y; te[9] = _z.y;
|
te[1] = _x.y; te[5] = _y.y; te[9] = _z.y;
|
||||||
|
@ -99,11 +101,11 @@ class Sketcher extends THREE.Group {
|
||||||
this.quaternion.setFromRotationMatrix(_m1);
|
this.quaternion.setFromRotationMatrix(_m1);
|
||||||
const parent = this.parent;
|
const parent = this.parent;
|
||||||
_m1.extractRotation(parent.matrixWorld);
|
_m1.extractRotation(parent.matrixWorld);
|
||||||
const _q1 = new THREE.Quaternion().setFromRotationMatrix(_m1);
|
_q1.setFromRotationMatrix(_m1);
|
||||||
this.quaternion.premultiply(_q1.invert());
|
this.quaternion.premultiply(_q1.invert());
|
||||||
|
|
||||||
this.updateMatrix();
|
this.updateMatrix();
|
||||||
this.matrix.setPosition(origin)
|
this.matrix.setPosition(origin)
|
||||||
|
|
||||||
this.plane.applyMatrix4(this.matrix)
|
this.plane.applyMatrix4(this.matrix)
|
||||||
this.inverse = this.matrix.clone().invert()
|
this.inverse = this.matrix.clone().invert()
|
||||||
}
|
}
|
||||||
|
@ -120,11 +122,11 @@ class Sketcher extends THREE.Group {
|
||||||
if (this.mode == 'line') {
|
if (this.mode == 'line') {
|
||||||
drawClear.bind(this)()
|
drawClear.bind(this)()
|
||||||
}
|
}
|
||||||
this.domElement.addEventListener('pointerdown', this.drawOnClick1)
|
this.canvas.addEventListener('pointerdown', this.drawOnClick1)
|
||||||
this.mode = "line"
|
this.mode = "line"
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
this.domElement.addEventListener('pointerdown', this.drawOnClick1)
|
this.canvas.addEventListener('pointerdown', this.drawOnClick1)
|
||||||
this.mode = "arc"
|
this.mode = "arc"
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
|
@ -136,9 +138,7 @@ class Sketcher extends THREE.Group {
|
||||||
|
|
||||||
this.mode = ""
|
this.mode = ""
|
||||||
break;
|
break;
|
||||||
case 'e':
|
|
||||||
extrude.call(this)
|
|
||||||
break;
|
|
||||||
case 'z':
|
case 'z':
|
||||||
var string = JSON.stringify(this.toJSON());
|
var string = JSON.stringify(this.toJSON());
|
||||||
window.string = string;
|
window.string = string;
|
||||||
|
@ -167,7 +167,7 @@ class Sketcher extends THREE.Group {
|
||||||
this.updatePointsBuffer(toDelete[toDelete.length - 1])
|
this.updatePointsBuffer(toDelete[toDelete.length - 1])
|
||||||
this.updateOtherBuffers()
|
this.updateOtherBuffers()
|
||||||
|
|
||||||
this.selected.clear()
|
this.selected = []
|
||||||
this.dispatchEvent({ type: 'change' })
|
this.dispatchEvent({ type: 'change' })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,7 +328,11 @@ class Sketcher extends THREE.Group {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const _m1 = new THREE.Matrix4()
|
||||||
|
const _q1 = new THREE.Quaternion()
|
||||||
|
const _x = new THREE.Vector3();
|
||||||
|
const _y = new THREE.Vector3();
|
||||||
|
const _z = new THREE.Vector3();
|
||||||
|
|
||||||
|
|
||||||
Object.assign(Sketcher.prototype,
|
Object.assign(Sketcher.prototype,
|
||||||
|
|
|
@ -18,41 +18,6 @@ export function addDimension(ent1, ent2, distance) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// function findTouching(node) {
|
|
||||||
// const res = [node]
|
|
||||||
// for (let t of node.constraints) {
|
|
||||||
// if (this.constraints.get(t)[0] != 'coincident') continue
|
|
||||||
// for (let i = 0; i < 2; i++) {
|
|
||||||
// let d = this.constraints.get(t)[2][i]
|
|
||||||
// if (d != node) res.push(d)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return res
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// export function setCoincident(ent1, ent2) {
|
|
||||||
|
|
||||||
// for (let n1 of findTouching.call(this,ent1)) {
|
|
||||||
// for (let n2 of findTouching.call(this,ent2)) {
|
|
||||||
// this.constraints.set(++this.c_id,
|
|
||||||
// [
|
|
||||||
// 'coincident', -1,
|
|
||||||
// [n1, n2, -1, -1]
|
|
||||||
// ]
|
|
||||||
// )
|
|
||||||
// n1.constraints.add(this.c_id)
|
|
||||||
// n2.constraints.add(this.c_id)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export function setCoincident() {
|
export function setCoincident() {
|
||||||
const s = new Set()
|
const s = new Set()
|
||||||
const toComb = []
|
const toComb = []
|
||||||
|
@ -83,6 +48,6 @@ export function setCoincident() {
|
||||||
obj.geometry.computeBoundingSphere()
|
obj.geometry.computeBoundingSphere()
|
||||||
obj.material.color.set(0x555555)
|
obj.material.color.set(0x555555)
|
||||||
}
|
}
|
||||||
this.selected.clear()
|
this.selected = []
|
||||||
this.dispatchEvent({ type: 'change' })
|
this.dispatchEvent({ type: 'change' })
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { sketchLine, sketchLine2 } from './sketchLine'
|
||||||
|
|
||||||
export function drawOnClick1(e) {
|
export function drawOnClick1(e) {
|
||||||
if (e.buttons !== 1) return
|
if (e.buttons !== 1) return
|
||||||
this.domElement.removeEventListener('pointerdown', this.drawOnClick1)
|
this.canvas.removeEventListener('pointerdown', this.drawOnClick1)
|
||||||
const mouseLoc = this.getLocation(e);
|
const mouseLoc = this.getLocation(e);
|
||||||
|
|
||||||
if (this.mode == "line") {
|
if (this.mode == "line") {
|
||||||
|
@ -22,8 +22,8 @@ export function drawOnClick1(e) {
|
||||||
}
|
}
|
||||||
this.l_id += 1
|
this.l_id += 1
|
||||||
|
|
||||||
this.domElement.addEventListener('pointermove', this.drawPreClick2)
|
this.canvas.addEventListener('pointermove', this.drawPreClick2)
|
||||||
this.domElement.addEventListener('pointerdown', this.drawOnClick2)
|
this.canvas.addEventListener('pointerdown', this.drawOnClick2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,8 +41,8 @@ export function drawPreClick2(e) {
|
||||||
|
|
||||||
export function drawOnClick2(e) {
|
export function drawOnClick2(e) {
|
||||||
if (e.buttons !== 1) return;
|
if (e.buttons !== 1) return;
|
||||||
this.domElement.removeEventListener('pointermove', this.drawPreClick2);
|
this.canvas.removeEventListener('pointermove', this.drawPreClick2);
|
||||||
this.domElement.removeEventListener('pointerdown', this.drawOnClick2);
|
this.canvas.removeEventListener('pointerdown', this.drawOnClick2);
|
||||||
|
|
||||||
this.updatePointsBuffer(this.updatePoint)
|
this.updatePointsBuffer(this.updatePoint)
|
||||||
this.updateOtherBuffers()
|
this.updateOtherBuffers()
|
||||||
|
@ -53,7 +53,7 @@ export function drawOnClick2(e) {
|
||||||
this.drawOnClick1(e)
|
this.drawOnClick1(e)
|
||||||
|
|
||||||
} else if (this.mode == "arc") {
|
} else if (this.mode == "arc") {
|
||||||
// this.domElement.addEventListener('pointermove', this.beforeClick_3)
|
// this.canvas.addEventListener('pointermove', this.beforeClick_3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,9 +61,9 @@ export function drawClear() {
|
||||||
if (this.mode == "") return
|
if (this.mode == "") return
|
||||||
|
|
||||||
if (this.mode == "line") {
|
if (this.mode == "line") {
|
||||||
this.domElement.removeEventListener('pointerdown', this.drawOnClick1)
|
this.canvas.removeEventListener('pointerdown', this.drawOnClick1)
|
||||||
this.domElement.removeEventListener('pointermove', this.drawPreClick2);
|
this.canvas.removeEventListener('pointermove', this.drawPreClick2);
|
||||||
this.domElement.removeEventListener('pointerdown', this.drawOnClick2);
|
this.canvas.removeEventListener('pointerdown', this.drawOnClick2);
|
||||||
|
|
||||||
this.delete(this.children[this.updatePoint])
|
this.delete(this.children[this.updatePoint])
|
||||||
|
|
||||||
|
|
|
@ -2,41 +2,24 @@
|
||||||
import * as THREE from '../../node_modules/three/src/Three';
|
import * as THREE from '../../node_modules/three/src/Three';
|
||||||
import {lineMaterial, pointMaterial} from '../utils/static'
|
import {lineMaterial, pointMaterial} from '../utils/static'
|
||||||
|
|
||||||
|
import {ptObj, lineObj} from '../utils/static'
|
||||||
|
|
||||||
|
const n = 30
|
||||||
|
|
||||||
export function sketchArc(mouseLoc) {
|
export function sketchArc(mouseLoc) {
|
||||||
const p1Geom = new THREE.BufferGeometry().setAttribute('position',
|
|
||||||
new THREE.BufferAttribute(new Float32Array(mouseLoc), 3)
|
const p1 = ptObj(mouseLoc)
|
||||||
)
|
|
||||||
const p1 = new THREE.Points(p1Geom,
|
|
||||||
new THREE.PointsMaterial().copy(pointMaterial)
|
|
||||||
);
|
|
||||||
p1.matrixAutoUpdate = false;
|
p1.matrixAutoUpdate = false;
|
||||||
p1.constraints = new Set()
|
p1.constraints = new Set()
|
||||||
|
|
||||||
const p2Geom = new THREE.BufferGeometry().setAttribute('position',
|
const p2 = ptObj()
|
||||||
new THREE.BufferAttribute(new Float32Array(3), 3)
|
|
||||||
)
|
|
||||||
const p2 = new THREE.Points(
|
|
||||||
p2Geom,
|
|
||||||
new THREE.PointsMaterial().copy(pointMaterial)
|
|
||||||
);
|
|
||||||
p2.matrixAutoUpdate = false;
|
p2.matrixAutoUpdate = false;
|
||||||
p2.constraints = new Set()
|
p2.constraints = new Set()
|
||||||
|
|
||||||
const arcGeom = new THREE.BufferGeometry().setAttribute('position',
|
const arc = lineObj(n)
|
||||||
new THREE.BufferAttribute(new Float32Array(3 * 37), 3)
|
|
||||||
)
|
|
||||||
|
|
||||||
const arc = new THREE.Line(arcGeom,
|
|
||||||
new THREE.LineBasicMaterial().copy(lineMaterial)
|
|
||||||
);
|
|
||||||
arc.frustumCulled = false;
|
arc.frustumCulled = false;
|
||||||
|
|
||||||
const p3Geom = new THREE.BufferGeometry().setAttribute('position',
|
const p3 = ptObj()
|
||||||
new THREE.BufferAttribute(new Float32Array(3), 3)
|
|
||||||
)
|
|
||||||
const p3 = new THREE.Points(p3Geom,
|
|
||||||
new THREE.PointsMaterial().copy(pointMaterial)
|
|
||||||
);
|
|
||||||
|
|
||||||
return [p1, p2, p3, arc]
|
return [p1, p2, p3, arc]
|
||||||
}
|
}
|
||||||
|
@ -61,7 +44,7 @@ export function sketchArc2(mouseLoc, toPush) {
|
||||||
p3.geometry.computeBoundingSphere()
|
p3.geometry.computeBoundingSphere()
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get2PtArc(p1, p2, divisions = 36) {
|
export function get2PtArc(p1, p2, divisions = n) {
|
||||||
|
|
||||||
const dx = p2[0] - p1[0]
|
const dx = p2[0] - p1[0]
|
||||||
const dy = p2[1] - p1[1]
|
const dy = p2[1] - p1[1]
|
||||||
|
@ -90,7 +73,7 @@ export function get2PtArc(p1, p2, divisions = 36) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function get3PtArc(p1, p2, c, divisions = 36) {
|
export function get3PtArc(p1, p2, c, divisions = n) {
|
||||||
|
|
||||||
const v1 = [p1[0] - c[0], p1[1] - c[1]]
|
const v1 = [p1[0] - c[0], p1[1] - c[1]]
|
||||||
const v2 = [p2[0] - c[0], p2[1] - c[1]]
|
const v2 = [p2[0] - c[0], p2[1] - c[1]]
|
||||||
|
|
|
@ -1,40 +1,25 @@
|
||||||
import * as THREE from '../../node_modules/three/src/Three';
|
import * as THREE from '../../node_modules/three/src/Three';
|
||||||
import {lineMaterial, pointMaterial} from '../utils/static'
|
import {ptObj, lineObj} from '../utils/static'
|
||||||
|
|
||||||
export function sketchLine(mouseLoc) {
|
export function sketchLine(mouseLoc) {
|
||||||
|
|
||||||
const p1Geom = new THREE.BufferGeometry().setAttribute('position',
|
const p1 = ptObj()
|
||||||
new THREE.BufferAttribute(new Float32Array(3), 3)
|
|
||||||
)
|
|
||||||
const p1 = new THREE.Points(p1Geom,
|
|
||||||
new THREE.PointsMaterial().copy(pointMaterial)
|
|
||||||
);
|
|
||||||
p1.matrixAutoUpdate = false;
|
p1.matrixAutoUpdate = false;
|
||||||
p1.constraints = new Set()
|
p1.constraints = new Set()
|
||||||
|
|
||||||
const p2Geom = new THREE.BufferGeometry().setAttribute('position',
|
const p2 = ptObj()
|
||||||
new THREE.BufferAttribute(new Float32Array(3), 3)
|
|
||||||
)
|
|
||||||
const p2 = new THREE.Points(
|
|
||||||
p2Geom,
|
|
||||||
new THREE.PointsMaterial().copy(pointMaterial)
|
|
||||||
);
|
|
||||||
p2.matrixAutoUpdate = false;
|
p2.matrixAutoUpdate = false;
|
||||||
p2.constraints = new Set()
|
p2.constraints = new Set()
|
||||||
|
|
||||||
const lineGeom = new THREE.BufferGeometry().setAttribute('position',
|
const line = lineObj()
|
||||||
new THREE.BufferAttribute(new Float32Array(6), 3)
|
|
||||||
);
|
|
||||||
const line = new THREE.Line(lineGeom,
|
|
||||||
new THREE.LineBasicMaterial().copy(lineMaterial)
|
|
||||||
);
|
|
||||||
line.matrixAutoUpdate = false;
|
line.matrixAutoUpdate = false;
|
||||||
line.frustumCulled = false;
|
line.frustumCulled = false;
|
||||||
line.constraints = new Set()
|
line.constraints = new Set()
|
||||||
|
|
||||||
|
|
||||||
lineGeom.attributes.position.set(mouseLoc)
|
line.geometry.attributes.position.set(mouseLoc)
|
||||||
p1Geom.attributes.position.set(mouseLoc)
|
p1.geometry.attributes.position.set(mouseLoc)
|
||||||
|
|
||||||
if (this.subsequent) {
|
if (this.subsequent) {
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import * as THREE from 'three/src/Three';
|
import * as THREE from 'three/src/Three';
|
||||||
import {raycaster} from '../utils/static';
|
import { raycaster, color } from './static';
|
||||||
|
|
||||||
export function onHover(e) {
|
export function onHover(e) {
|
||||||
if (this.mode || e.buttons) return
|
if (this.mode || e.buttons) return
|
||||||
|
@ -12,10 +12,16 @@ export function onHover(e) {
|
||||||
this.camera
|
this.camera
|
||||||
);
|
);
|
||||||
|
|
||||||
const hoverPts = raycaster.intersectObjects(this.children)
|
let hoverPts;
|
||||||
|
if (this.name == 'Scene') {
|
||||||
|
hoverPts = raycaster.intersectObjects(this.children, true)
|
||||||
|
} else {
|
||||||
|
hoverPts = raycaster.intersectObjects(this.children)
|
||||||
|
}
|
||||||
|
|
||||||
let idx = []
|
let idx = []
|
||||||
if (hoverPts.length) {
|
if (hoverPts.length) {
|
||||||
|
// console.log(hoverPts)
|
||||||
let minDist = Infinity;
|
let minDist = Infinity;
|
||||||
for (let i = 0; i < hoverPts.length; i++) {
|
for (let i = 0; i < hoverPts.length; i++) {
|
||||||
if (!hoverPts[i].distanceToRay) continue;
|
if (!hoverPts[i].distanceToRay) continue;
|
||||||
|
@ -34,7 +40,7 @@ export function onHover(e) {
|
||||||
|
|
||||||
for (let x = 0; x < this.hovered.length; x++) {
|
for (let x = 0; x < this.hovered.length; x++) {
|
||||||
const obj = this.hovered[x]
|
const obj = this.hovered[x]
|
||||||
if (obj && !this.selected.has(obj)) {
|
if (obj && !this.selected.includes(obj)) {
|
||||||
obj.material.color.set(0x555555)
|
obj.material.color.set(0x555555)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +48,7 @@ export function onHover(e) {
|
||||||
|
|
||||||
for (let x = 0; x < idx.length; x++) {
|
for (let x = 0; x < idx.length; x++) {
|
||||||
const i = idx[x]
|
const i = idx[x]
|
||||||
hoverPts[i].object.material.color.set(0x00ff00)
|
hoverPts[i].object.material.color.set(color.hover)
|
||||||
this.hovered.push(hoverPts[i].object)
|
this.hovered.push(hoverPts[i].object)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +60,8 @@ export function onHover(e) {
|
||||||
|
|
||||||
for (let x = 0; x < this.hovered.length; x++) {
|
for (let x = 0; x < this.hovered.length; x++) {
|
||||||
const obj = this.hovered[x]
|
const obj = this.hovered[x]
|
||||||
if (obj && !this.selected.has(obj)) {
|
if (obj && !this.selected.includes(obj)) {
|
||||||
|
// console.log(obj)
|
||||||
obj.material.color.set(0x555555)
|
obj.material.color.set(0x555555)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,21 +79,18 @@ export function onPick(e) {
|
||||||
|
|
||||||
if (this.hovered.length) {
|
if (this.hovered.length) {
|
||||||
|
|
||||||
for (let x = 0; x < this.hovered.length; x++) {
|
this.selected.push(this.hovered[this.hovered.length-1])
|
||||||
const obj = this.hovered[x]
|
|
||||||
this.selected.add(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.hovered[0].type == "Points") {
|
if (this.hovered[0].type == "Points") {
|
||||||
this.domElement.addEventListener('pointermove', this.onDrag);
|
this.canvas.addEventListener('pointermove', this.onDrag);
|
||||||
this.domElement.addEventListener('pointerup', this.onRelease)
|
this.canvas.addEventListener('pointerup', this.onRelease)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (let obj of this.selected) {
|
for (let obj of this.selected) {
|
||||||
obj.material.color.set(0x555555)
|
obj.material.color.set(0x555555)
|
||||||
}
|
}
|
||||||
this.dispatchEvent({ type: 'change' })
|
this.dispatchEvent({ type: 'change' })
|
||||||
this.selected.clear()
|
this.selected = []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,8 +111,8 @@ export function onDrag(e) {
|
||||||
|
|
||||||
|
|
||||||
export function onRelease() {
|
export function onRelease() {
|
||||||
this.domElement.removeEventListener('pointermove', this.onDrag)
|
this.canvas.removeEventListener('pointermove', this.onDrag)
|
||||||
this.domElement.removeEventListener('pointerup', this.onRelease)
|
this.canvas.removeEventListener('pointerup', this.onRelease)
|
||||||
|
|
||||||
for (let x = 0; x < this.hovered.length; x++) {
|
for (let x = 0; x < this.hovered.length; x++) {
|
||||||
const obj = this.hovered[x]
|
const obj = this.hovered[x]
|
|
@ -1,16 +1,7 @@
|
||||||
import * as THREE from '../../node_modules/three/src/Three';
|
import * as THREE from '../../node_modules/three/src/Three';
|
||||||
|
|
||||||
const lineMaterial = new THREE.LineBasicMaterial({
|
|
||||||
linewidth: 2,
|
|
||||||
color: 0x555555,
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
const pointMaterial = new THREE.PointsMaterial({
|
|
||||||
color: 0x555555,
|
|
||||||
size: 4,
|
|
||||||
})
|
|
||||||
|
|
||||||
const _vec2 = new THREE.Vector2()
|
const _vec2 = new THREE.Vector2()
|
||||||
const _vec3 = new THREE.Vector3()
|
const _vec3 = new THREE.Vector3()
|
||||||
|
|
||||||
|
@ -20,4 +11,40 @@ raycaster.params.Line.threshold = 0.8;
|
||||||
raycaster.params.Points.threshold = 1.5;
|
raycaster.params.Points.threshold = 1.5;
|
||||||
|
|
||||||
|
|
||||||
export { lineMaterial, pointMaterial, _vec2, _vec3, raycaster }
|
const color = {
|
||||||
|
dark1: 0x555555,
|
||||||
|
hover: 0x00ff00,
|
||||||
|
extrude: 0x156289,
|
||||||
|
emissive: 0x072534
|
||||||
|
}
|
||||||
|
|
||||||
|
const lineMaterial = new THREE.LineBasicMaterial({
|
||||||
|
linewidth: 2,
|
||||||
|
color: color.dark1,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const pointMaterial = new THREE.PointsMaterial({
|
||||||
|
color: color.dark1,
|
||||||
|
size: 4,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const ptObj = (n) => new THREE.Points(
|
||||||
|
new THREE.BufferGeometry().setAttribute('position',
|
||||||
|
new THREE.Float32BufferAttribute(n || 3, 3)
|
||||||
|
),
|
||||||
|
pointMaterial.clone()
|
||||||
|
);
|
||||||
|
|
||||||
|
const lineObj = (n=1) => new THREE.Line(
|
||||||
|
new THREE.BufferGeometry().setAttribute('position',
|
||||||
|
new THREE.Float32BufferAttribute(3 * (n+1), 3)
|
||||||
|
),
|
||||||
|
lineMaterial.clone()
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
export { lineMaterial, pointMaterial, _vec2, _vec3, raycaster, color, ptObj, lineObj }
|
|
@ -3,7 +3,7 @@ const path = require('path');
|
||||||
module.exports = {
|
module.exports = {
|
||||||
entry: {
|
entry: {
|
||||||
index: './src/index.js',
|
index: './src/index.js',
|
||||||
renderer: './src/Renderer.js',
|
scene: './src/Scene.js',
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: '[name].bundle.js',
|
filename: '[name].bundle.js',
|
||||||
|
|
Loading…
Reference in New Issue