import * as THREE from 'three'; const EPSILON = 0.001; class TaperedLink extends THREE.Group { constructor(baseMaterial, n1, n2, r1, r2) { super(); const geometry = new THREE.ConeGeometry( 1, 1, 16, true ); const cplane = new THREE.Plane(new THREE.Vector3(0, -1, 0), 0.5); this.material = baseMaterial.clone(); this.material.clippingPlanes = [ cplane ]; this.object = new THREE.Mesh( geometry, this.material ); this.add( this.object ); this.update(n1, n2, r1, r2); } update(n1, n2, r1, r2) { const kraw = r1 - r2; let k = ( Math.abs(kraw) < EPSILON ) ? EPSILON : kraw; let nbase = n1.v3; let napex = n2.v3; let rbase = r1; let rapex = r2; if( k < 0 ) { nbase = n2.v3; napex = n1.v3; rbase = r2; rapex = r1; k = -k; } const l = nbase.distanceTo(napex); const lapex = l * rapex / k; const h = l + lapex; this.scale.copy(new THREE.Vector3(rbase, rbase, h)); const h_offset = 0.5 * h / l; const pos = new THREE.Vector3(); pos.lerpVectors(nbase, napex, h_offset); this.position.copy(pos); // the group, not the cone!! this.lookAt(nbase); this.children[0].rotation.x = 3 * Math.PI / 2.0; this.visible = true; const clipnorm = new THREE.Vector3(); clipnorm.copy(napex); clipnorm.sub(nbase); clipnorm.negate(); clipnorm.normalize(); this.material.clippingPlanes[0].setFromNormalAndCoplanarPoint( clipnorm, napex ); } } export { TaperedLink };