From b910181628806a376d2e5b91c09038dd01aa801d Mon Sep 17 00:00:00 2001 From: howard Date: Thu, 22 Apr 2021 14:14:26 -0700 Subject: [PATCH] checkpoint --- extlib/trackball.js | 3 ++- src/Scene.js | 16 +++++++------ src/Sketch.js | 20 +++++++++++++---- src/drawEvents.js | 30 ++++++++++++++++++++----- src/extrude.js | 4 ++-- src/mouseEvents.js | 33 ++++++++++++++++++++++++--- src/shared.js | 55 ++++++++++++++++++++++++++++++++++++++++++++- 7 files changed, 138 insertions(+), 23 deletions(-) diff --git a/extlib/trackball.js b/extlib/trackball.js index 5e8e3f8..ae263f9 100644 --- a/extlib/trackball.js +++ b/extlib/trackball.js @@ -271,7 +271,8 @@ var TrackballControls = function ( object, domElement ) { } - mouseChange.multiplyScalar( _eye.length() * scope.panSpeed ); + // mouseChange.multiplyScalar( _eye.length() * scope.panSpeed ); + mouseChange.multiplyScalar( _eye.length() * 1/577*scope.domElement.clientWidth); pan.copy( _eye ).cross( scope.object.up ).setLength( mouseChange.x ); pan.add( objectUp.copy( scope.object.up ).setLength( mouseChange.y ) ); diff --git a/src/Scene.js b/src/Scene.js index c122a1d..af11243 100644 --- a/src/Scene.js +++ b/src/Scene.js @@ -3,7 +3,7 @@ import * as THREE from '../node_modules/three/src/Three'; import { Sketch } from './Sketch' import { extrude, flipBufferGeometryNormals } from './extrude' import { onHover, onPick, clearSelection } from './mouseEvents'; -import { _vec2, _vec3, color, awaitSelection, setHover } from './shared' +import { _vec2, _vec3, color, awaitSelection, setHover, custPtMat } from './shared' import { AxesHelper } from './axes' @@ -58,9 +58,9 @@ export class Scene { this.camera.layers.enable(3) - const controls = new TrackballControls(this.camera, this.canvas); - controls.target.set(0, 0, 0); - controls.update(); + this.controls = new TrackballControls(this.camera, this.canvas); + this.controls.target.set(0, 0, 0); + this.controls.update(); @@ -82,7 +82,8 @@ export class Scene { new THREE.BufferGeometry().setAttribute('position', new THREE.Float32BufferAttribute(3, 3) ), - pointMaterial.clone() + // pointMaterial.clone() + custPtMat.clone() ) freePt.matrixAutoUpdate = false @@ -149,8 +150,8 @@ export class Scene { this.awaitSelection = awaitSelection.bind(this); this.obj3d.addEventListener('change', this.render); - controls.addEventListener('change', this.render); - controls.addEventListener('start', this.render); + this.controls.addEventListener('change', this.render); + this.controls.addEventListener('start', this.render); window.addEventListener('resize', this.render); if (process.env.NODE_ENV !== 'production') { @@ -353,6 +354,7 @@ function render() { this.camera.right = canvas.clientWidth / canvas.clientHeight; this.camera.updateProjectionMatrix(); + this.controls.handleResize() Object.assign(this.rect, this.canvas.getBoundingClientRect().toJSON()) } diff --git a/src/Sketch.js b/src/Sketch.js index 53d75b7..4e80bbe 100644 --- a/src/Sketch.js +++ b/src/Sketch.js @@ -2,7 +2,7 @@ import * as THREE from '../node_modules/three/src/Three'; -import { _vec2, _vec3, raycaster, awaitSelection, ptObj, setHover } from './shared' +import { _vec2, _vec3, raycaster, awaitSelection, ptObj, setHover,custPtMat } from './shared' import { drawOnClick1, drawOnClick2, drawPreClick2, drawOnClick3, drawPreClick3, drawClear, drawPoint } from './drawEvents' import { onHover, onDrag, onPick, onRelease, clearSelection } from './mouseEvents' @@ -47,8 +47,20 @@ class Sketch { this.constraints = new Map() this.c_id = 1; - this.obj3d.add(new THREE.Group()); + this.helpersGroup = new THREE.Group() + this.obj3d.add(this.helpersGroup); + // this.freePt = new THREE.Points( + // new THREE.BufferGeometry().setAttribute('position', + // new THREE.Float32BufferAttribute(3, 3) + // ), + // custPtMat.clone() + // ) + // this.freePt.matrixAutoUpdate = false + // this.freePt.visible = false + // this.freePt.userData.type = 'selpoint' + // this.helpersGroup.add(this.freePt); + this.obj3d.add(new THREE.Group()); this.geomStartIdx = this.obj3d.children.length this.obj3d.userData.geomStartIdx = this.geomStartIdx this.dimGroup = this.obj3d.children[this.geomStartIdx - 1] @@ -258,7 +270,7 @@ class Sketch { case 'p': this.mode = "point" this.snap = true - this.canvas.addEventListener('pointerdown', (e)=> { + this.canvas.addEventListener('pointerdown', (e) => { if (this.mode !== 'point') return const pt = ptObj() @@ -271,7 +283,7 @@ class Sketch { pt.layers.enable(2) this.obj3d.add(pt) - this.updatePointsBuffer(this.obj3d.children.length-1) + this.updatePointsBuffer(this.obj3d.children.length - 1) this.scene.render() }) break; diff --git a/src/drawEvents.js b/src/drawEvents.js index 8de788d..06b4030 100644 --- a/src/drawEvents.js +++ b/src/drawEvents.js @@ -3,15 +3,26 @@ import { drawArc, drawArc2, drawArc3, drawArc4 } from './drawArc' import { drawLine, drawLine2 } from './drawLine' import { ptObj } from './shared' -export function drawOnClick1(e) { - if (e.buttons !== 1) return +export function drawOnClick1(e, loc) { + if (!loc && e.buttons !== 1) return // this.canvas.removeEventListener('pointerdown', this.drawOnClick1) this.canvas.addEventListener('pointermove', this.drawPreClick2) this.canvas.addEventListener('pointerdown', this.drawOnClick2, { once: true }) - const mouseLoc = this.getLocation(e).toArray(); + + let mouseLoc + + if (loc) { + mouseLoc = loc + } else if (this.hovered.length && !this.subsequent) { + mouseLoc = this.hovered[this.hovered.length - 1].geometry.attributes.position.array + } else { + mouseLoc = this.getLocation(e).toArray(); + } + + // this.mode allow alow following modes to create new obj3ds if (this.mode == "line") { @@ -83,6 +94,7 @@ export function drawOnClick2(e) { element.layers.enable(2) }); + let modLoc if (this.hovered.length) { this.constraints.set(++this.c_id, [ @@ -94,14 +106,22 @@ export function drawOnClick2(e) { this.toPush[1].userData.constraints.push(this.c_id) this.updateOtherBuffers() + modLoc = this.hovered[this.hovered.length - 1].geometry.attributes.position.array } if (this.mode == "line") { - this.subsequent = true - this.drawOnClick1(e) + if (modLoc) { + drawLine2(modLoc, this.toPush) + this.drawOnClick1(null, modLoc) + } else { + this.drawOnClick1(e) + } } else if (this.mode == "arc") { + if (modLoc) { + drawArc2(modLoc, this.toPush) + } drawArc3(this.toPush[0], this.toPush[1]) diff --git a/src/extrude.js b/src/extrude.js index dbf4192..3d856ac 100644 --- a/src/extrude.js +++ b/src/extrude.js @@ -41,7 +41,7 @@ export function extrude(sketch, depth) { linkedObj[1][nextIdx] ) ] - if (d == children[2]) { + if (d == children[sketch.geomStartIdx + 1]) { // console.log('pair found') }; findTouching(d) @@ -58,7 +58,7 @@ export function extrude(sketch, depth) { if (c == -1) continue; const d = children[objIdx.get(c)] if (d == node) continue; - if (d == children[2]) { + if (d == children[sketch.geomStartIdx + 1]) { // console.log('loop found') } else { // if (!visited.has(d)) { diff --git a/src/mouseEvents.js b/src/mouseEvents.js index 28bf27c..f74eaa1 100644 --- a/src/mouseEvents.js +++ b/src/mouseEvents.js @@ -22,8 +22,10 @@ export function onHover(e) { 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) + hoverPts = raycaster.intersectObjects(this.obj3d.children, true) } else { + // this.freePt.visible = false // hide freept before each redraw + this.scene.selpoints[0].visible = false // hide selpoint[0] before each redraw raycaster.layers.set(2) // intersectObjects has side effect of updating bounding spheres // which may lead to unexpected results if you leave boundspheres un-updated @@ -77,7 +79,7 @@ export function onHover(e) { if (this.obj3d.userData.type != 'sketch' && obj.userData.type == 'point') { ptLoc = obj.geometry.attributes.position.array .slice( - 3 * hoverts[idx[x]].index, + 3 * hoverPts[idx[x]].index, 3 * hoverPts[idx[x]].index + 3 ) this.selpoints[0].geometry.attributes.position.array.set(ptLoc) @@ -88,6 +90,28 @@ export function onHover(e) { obj = hoverPts[idx[x]].index } + 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.freePt.geometry.attributes.position.array.set(ptLoc) + // this.freePt.matrix = obj.parent.matrix + // this.freePt.geometry.attributes.position.needsUpdate = true + // this.freePt.visible = true + ptLoc = obj.geometry.attributes.position.array + .slice( + 3 * hoverPts[idx[x]].index, + 3 * hoverPts[idx[x]].index + 3 + ) + this.scene.selpoints[0].geometry.attributes.position.array.set(ptLoc) + this.scene.selpoints[0].matrix = obj.parent.matrix + this.scene.selpoints[0].geometry.attributes.position.needsUpdate = true + this.scene.selpoints[0].visible = true + } + + this.hovered.push(obj) } @@ -125,6 +149,7 @@ export function onPick(e) { let obj = this.hovered[this.hovered.length - 1] // if (sc.selected.includes(obj3d)) continue + console.log(obj, 'heere') if (typeof obj != 'object') { // special sketchplace define pts in feature mode const pp = this.selpoints[this.fptIdx % 3 + 1] @@ -205,10 +230,12 @@ export function onPick(e) { 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 + } else { + setHover(obj, 0) + } // dont think this would have been possible without redux diff --git a/src/shared.js b/src/shared.js index bd26895..6226e1e 100644 --- a/src/shared.js +++ b/src/shared.js @@ -179,8 +179,61 @@ function setHover(obj, state, meshHover = true) { } +const vertexShader = ` + uniform float edgeSize; + uniform float pointWidth; + void main() { + vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); + gl_PointSize = (pointWidth + edgeSize); + gl_Position = projectionMatrix * mvPosition; + } +` + +const fragmentShader = ` + uniform vec3 color; + uniform vec3 edgeColor; + uniform float edgeSize; + uniform float pointWidth; + void main() { + gl_FragColor = vec4(color, 1.0); + // distance = len(x: [-1, 1], y: [-1, 1]) + float distance = length(2.0 * gl_PointCoord - 1.0); + // pixels [0, ~15/20] + float totalWidth = pointWidth + edgeSize; + float edgeStart = pointWidth; + float edgeEnd = pointWidth + 2.0; + // [edgeStart, edgeEnd] -> [0, 1] + float sEdge = smoothstep(edgeStart, edgeEnd, distance * totalWidth); + // transition from edgeColor to color along the edge + gl_FragColor = ( vec4(edgeColor, 1.0) * sEdge) + ((1.0 - sEdge) * gl_FragColor); + + if (distance > 1.0) { + discard; + } + } +` +const pixelRatio = 2 +const custPtMat = new THREE.ShaderMaterial({ + uniforms: { + color: { value: new THREE.Color(0xff0000) }, + edgeColor: { value: new THREE.Color(0x990000) }, + pointWidth: { value: 4 * pixelRatio }, + edgeSize: { value: 4 * pixelRatio }, + }, + vertexShader, + fragmentShader, + // depthTest:false +}); + + + + + + + + window.rc = raycaster -export { lineMaterial, pointMaterial, _vec2, _vec3, raycaster, color, hoverColor, ptObj, lineObj, awaitSelection, setHover } \ No newline at end of file +export { lineMaterial, pointMaterial, custPtMat, _vec2, _vec3, raycaster, color, hoverColor, ptObj, lineObj, awaitSelection, setHover } \ No newline at end of file