three.cad/src/shared.js

244 lines
5.2 KiB
JavaScript
Raw Normal View History

2021-04-07 03:46:16 +08:00
import * as THREE from '../node_modules/three/src/Three';
2021-03-29 18:27:34 +08:00
2021-03-31 07:20:24 +08:00
const _vec2 = new THREE.Vector2()
const _vec3 = new THREE.Vector3()
const raycaster = new THREE.Raycaster();
2021-04-21 18:54:57 +08:00
raycaster.params.Line.threshold = 1;
raycaster.params.Points.threshold = 1;
2021-03-31 07:20:24 +08:00
const color = {
2021-04-11 07:16:08 +08:00
background: 0x18181B,
2021-03-31 16:07:34 +08:00
lighting: 0xFFFFFF,
emissive: 0x072534,
2021-04-11 07:16:08 +08:00
meshTempHover: 0x9DCFED,
2021-04-15 10:11:55 +08:00
point: 0xffffff,
selpoint: 0xff0000,
line: 0xffffff,
mesh: 0x9DCFED,
dimension: 0x0000ff,
plane: 0xffff00,
planeBorder: 0x2e2e00,
2021-04-11 15:57:39 +08:00
opacity: 0.02
2021-03-31 07:20:24 +08:00
}
2021-04-07 02:31:14 +08:00
const hoverColor = {
2021-04-11 15:57:39 +08:00
emissive: 0x343407,
2021-04-26 14:04:24 +08:00
point: 0x10B981,
2021-04-11 07:16:08 +08:00
selpoint: 0xff0000,
2021-04-26 14:04:24 +08:00
line: 0x10B981,
2021-04-15 10:11:55 +08:00
mesh: 0xFAB601,
2021-04-26 14:04:24 +08:00
dimension: 0x10B981,
2021-04-11 15:57:39 +08:00
2021-04-15 10:11:55 +08:00
plane: 0xffff00,
2021-04-11 07:16:08 +08:00
planeBorder: 0x919100,
2021-04-11 15:57:39 +08:00
opacity: 0.06
2021-04-07 02:31:14 +08:00
}
2021-03-29 18:27:34 +08:00
const lineMaterial = new THREE.LineBasicMaterial({
2021-04-08 15:33:18 +08:00
linewidth: 1,
2021-04-05 11:52:17 +08:00
color: color.line,
2021-04-23 10:31:30 +08:00
depthTest: false
2021-03-29 18:27:34 +08:00
})
const pointMaterial = new THREE.PointsMaterial({
2021-04-05 11:52:17 +08:00
color: color.point,
2021-03-29 18:27:34 +08:00
size: 4,
2021-04-23 10:31:30 +08:00
depthTest: false
2021-03-29 18:27:34 +08:00
})
2021-04-10 16:45:15 +08:00
const ptObj = (n, visibility = true) => {
2021-03-31 16:07:34 +08:00
const ret = new THREE.Points(
new THREE.BufferGeometry().setAttribute('position',
new THREE.Float32BufferAttribute(n || 3, 3)
),
pointMaterial.clone()
);
2021-04-07 05:10:07 +08:00
ret.name = "p" + id++
2021-04-05 11:52:17 +08:00
ret.userData.type = 'point'
2021-04-10 16:45:15 +08:00
ret.visible = visibility
2021-04-23 10:31:30 +08:00
ret.renderOrder = 1
2021-03-31 16:07:34 +08:00
return ret
}
2021-03-29 18:27:34 +08:00
2021-03-31 16:07:34 +08:00
const lineObj = (n = 1) => {
const ret = new THREE.Line(
new THREE.BufferGeometry().setAttribute('position',
new THREE.Float32BufferAttribute(3 * (n + 1), 3)
),
lineMaterial.clone()
);
2021-04-07 05:10:07 +08:00
ret.name = 'l' + id++
2021-04-05 11:52:17 +08:00
ret.userData.type = 'line'
2021-04-23 10:31:30 +08:00
ret.renderOrder = 1
2021-03-31 16:07:34 +08:00
return ret
}
2021-03-29 18:27:34 +08:00
2021-04-09 07:05:52 +08:00
async function awaitSelection(...criteria) {
2021-04-04 17:36:41 +08:00
function fullfilled() {
for (let i = criteria.length - 1; i >= 0; i--) {
const crit = criteria[i]
let nfilled = 0;
for (let k in counter) {
if (!crit[k] || counter[k] > crit[k]) {
criteria.splice(i, 1)
break;
} else if (counter[k] == crit[k]) {
nfilled += 1
}
}
if (nfilled == Object.keys(crit).length) return true
}
return false
}
const counter = {}
2021-04-26 14:04:24 +08:00
let references = (this.selected || this.scene.selected).slice()
2021-04-04 17:36:41 +08:00
for (let ob of references) {
2021-04-05 11:52:17 +08:00
const type = ob.userData.type
2021-04-04 17:36:41 +08:00
if (counter[type]) {
counter[type] += 1;
} else {
counter[type] = 1;
}
}
if (fullfilled()) return references
2021-04-04 08:59:14 +08:00
let end = false;
2021-04-04 17:36:41 +08:00
while (criteria.length && !end) {
2021-04-04 08:59:14 +08:00
let pt;
let onEnd, onKey;
try {
2021-04-04 17:36:41 +08:00
2021-04-04 08:59:14 +08:00
pt = await new Promise((res, rej) => {
2021-04-04 10:08:19 +08:00
onKey = (e) => e.key == 'Escape' && rej()
2021-04-04 17:36:41 +08:00
onEnd = (e) => this.hovered.length && res(this.hovered[0])
this.canvas.addEventListener('pointerdown', onEnd)
window.addEventListener('keydown', onKey)
2021-04-04 08:59:14 +08:00
})
2021-04-04 17:36:41 +08:00
references.push(pt)
2021-04-05 11:52:17 +08:00
const type = pt.userData.type
2021-04-19 15:30:29 +08:00
2021-04-04 17:36:41 +08:00
if (counter[type]) {
counter[type] += 1;
} else {
counter[type] = 1;
}
if (fullfilled()) return references
2021-04-04 08:59:14 +08:00
} catch (e) {
end = true;
2021-04-03 03:33:09 +08:00
}
2021-04-04 08:59:14 +08:00
this.canvas.removeEventListener('pointerdown', onEnd)
2021-04-04 10:08:19 +08:00
window.removeEventListener('keydown', onKey)
2021-04-03 03:33:09 +08:00
}
2021-04-05 11:52:17 +08:00
2021-04-26 14:04:24 +08:00
console.log('fail')
2021-04-04 17:36:41 +08:00
return null
2021-04-03 03:33:09 +08:00
}
2021-04-15 10:11:55 +08:00
function setHover(obj, state, meshHover = true) {
let colObj = state == 1 ? hoverColor : color
switch (obj.userData.type) {
case 'plane':
obj.material.opacity = colObj.opacity
obj.children[0].material.color.set(colObj['planeBorder'])
break;
case 'sketch':
obj.traverse(ele => {
if (ele.userData.type == 'line') {
ele.material.color.set(colObj['line'])
}
})
break;
case 'mesh':
if (meshHover) {
2021-04-17 07:03:30 +08:00
obj.material.emissive.set(colObj.emissive)
2021-04-15 10:11:55 +08:00
} else {
break
}
2021-04-23 10:31:30 +08:00
case 'point':
obj.material.color.set(colObj[obj.userData.type])
obj.material.size = state ? 8 : 4
2021-04-15 10:11:55 +08:00
default:
obj.material.color.set(colObj[obj.userData.type])
break;
}
}
2021-04-23 05:14:26 +08:00
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);
float distance = length(2.0 * gl_PointCoord - 1.0);
float totalWidth = pointWidth + edgeSize;
float edgeStart = pointWidth;
float edgeEnd = pointWidth + 2.0;
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;
}
}
`
2021-04-23 11:50:24 +08:00
const sz = 4
2021-04-23 05:14:26 +08:00
const custPtMat = new THREE.ShaderMaterial({
uniforms: {
color: { value: new THREE.Color(0xff0000) },
2021-04-23 11:50:24 +08:00
edgeColor: { value: new THREE.Color(0x770000) },
pointWidth: { value: sz },
edgeSize: { value: sz },
2021-04-23 05:14:26 +08:00
},
vertexShader,
fragmentShader,
2021-04-23 10:31:30 +08:00
depthTest: false
2021-04-23 05:26:46 +08:00
// depthWrite:false
2021-04-23 05:14:26 +08:00
});
2021-04-15 10:11:55 +08:00
2021-04-10 16:45:15 +08:00
window.rc = raycaster
2021-04-03 03:33:09 +08:00
2021-04-23 05:14:26 +08:00
export { lineMaterial, pointMaterial, custPtMat, _vec2, _vec3, raycaster, color, hoverColor, ptObj, lineObj, awaitSelection, setHover }