@tomorrowevening/hermes
Version:
An extendable set of Web Tools controlled via a separate window for non-intereference with content.
2 lines (1 loc) • 7.84 kB
JavaScript
"use strict";const s=require("three/webgpu"),h=require("three/src/math/MathUtils.js"),o=require("../../multiView/MultiView.cjs"),p=require("../Transform.cjs"),u=require("../../utils.cjs"),l=require("../../../utils/math.cjs"),g=require("../../../utils/three.cjs"),b=new s.BoxGeometry,c=new s.Vector2;class m extends s.Object3D{curve=new s.CatmullRomCurve3;line;draggable;curvePos;tension=.5;closed=!1;subdivide=50;curveType;offset=1;lineMaterial;_camera;_curvePercentage=0;_draggableScale=10;_transform;raycaster;draggedMat=new s.MeshBasicMaterial;parentGroup;group;constructor(e,t){const i=new s.Color(h.lerp(.5,1,Math.random()),h.lerp(.5,1,Math.random()),h.lerp(.5,1,Math.random()));super(),this.name=e,this.lineMaterial=new s.LineBasicMaterial({color:i}),this.line=new s.Line(new s.BufferGeometry,this.lineMaterial),this.line.name="line",this.line.visible=!1,this.add(this.line),this._camera=t,this.curveType="catmullrom",this.draggedMat.color=i,this.draggable=new s.Object3D,this.draggable.name="draggablePoints",this.add(this.draggable),this.curvePos=new s.Mesh(new s.SphereGeometry(1.5),new s.MeshBasicMaterial({color:i})),this.curvePos.name="curvePos",this.curvePos.scale.setScalar(this._draggableScale),this.curvePos.visible=!1,this.add(this.curvePos),this.raycaster=new s.Raycaster,this.raycaster.params.Line.threshold=3,this.enable()}enable(){document.addEventListener("pointerdown",this.onMouseClick)}disable(){document.removeEventListener("pointerdown",this.onMouseClick)}dispose=()=>{this._transform&&(this._transform.removeEventListener("objectChange",this.updateSpline),p.instance.remove(this.name)),this.disable(),this.parentGroup.removeGroup(this.name)};hideTransform=()=>{this._transform?.detach()};exportSpline=()=>{const e=[];this.draggable.children.forEach(t=>{e.push([l.roundTo(t.position.x,3),l.roundTo(t.position.y,3),l.roundTo(t.position.z,3)])}),u.copyToClipboard({name:this.name,points:e,tension:this.tension,closed:this.closed,subdivide:this.subdivide,type:this.curveType}),console.log("Spline copied!")};showPoints=(e=!0)=>{this.draggable.visible=e};addPoints=(e=[])=>{if(e.length>0){const t=e.length-1;for(let i=0;i<t;i++)this.addPoint(e[i],!1);this.addPoint(e[t])}};addPoint=(e,t=!0)=>{const i=this.draggable.children.length,n=new s.Mesh(b,this.draggedMat);n.name=`point_${i}`,n.position.copy(e),n.scale.setScalar(this._draggableScale),this.draggable.add(n),this._transform?.attach(n);const a=this.points.length>1;return a&&t&&this.updateSpline(),this.line.visible=a,this.updateCurrentPoint(),n};addNextPt=()=>{const e=this.draggable.children.length,t=e>1?this.draggable.children[e-1].position.clone():new s.Vector3,i=this.addPoint(t);this.updateField(i.position)};removePoint=e=>{if(this._transform?.object===e){this._transform?.detach();const t=this.draggable.children[this.draggable.children.length-1];this._transform?.attach(t),this.updateField(t.position)}g.dispose(e),this.updateSpline()};removePointAt=e=>{const t=this.draggable.children[e];this.removePoint(t)};removeSelectedPt=()=>{this._transform?.object!==void 0&&this.removePoint(this._transform?.object)};updateLastPoint(e){const t=this.draggable.children.length;t>0&&(this.draggable.children[t-1].position.copy(e),this.updateSpline())}updateSpline=()=>{this.points.length<2||(this.curve=new s.CatmullRomCurve3(this.points,this.closed,this.curveType,this.tension),this.line.geometry.dispose(),this.line.geometry=new s.BufferGeometry().setFromPoints(this.curve.getPoints(this.subdivide)),this.curvePos.position.copy(this.getPointAt(this._curvePercentage)))};updateField(e){this.group.current?.setField("Current Point",e)}onMouseClick=e=>{if(!o.instance||!o.instance.currentWindow||this._transform&&!this._transform.getHelper().visible)return;const i=o.instance.currentWindow.current.getBoundingClientRect();c.x=(e.clientX-i.x)/i.width*2-1,c.y=-((e.clientY-i.y)/i.height)*2+1,this.raycaster.setFromCamera(c,this.camera);const n=this.raycaster.intersectObjects(this.draggable.children,!1);if(n.length>0){const a=n[0].object;a!==this._transform?.object&&(this._transform?.attach(a),this.updateField(a.position))}};getPointAt(e){return this.curve.points.length>1?this.curve.getPointAt(e):this.curve.points.length===1?this.curve.points[0]:new s.Vector3}getTangentAt(e){return this.curve.getTangentAt(e)}get points(){const e=[];return this.draggable.children.forEach(t=>{e.push(t.position)}),e}get total(){return this.draggable.children.length}get draggableScale(){return this._draggableScale}set draggableScale(e){this._draggableScale=e,this.draggable.children.forEach(t=>t.scale.setScalar(e)),this.curvePos.scale.setScalar(e)}get camera(){return this._camera}set camera(e){this._camera=e,this._transform!==void 0&&(this._transform.camera=e)}get curvePercentage(){return this._curvePercentage}set curvePercentage(e){this._curvePercentage=e,this.curvePos.position.copy(this.getPointAt(e))}updateCurrentPoint(){if(this._transform?.object&&this.group){const e=this._transform?.object;e.name.search("point")>-1&&this.updateField(e.position)}}onUpdateTransform=()=>{this.updateCurrentPoint(),this.updateSpline()};initDebug(e,t){const i=this.draggable.children;this.visible=t,this.parentGroup=e,this._transform=p.instance.add(this.name),this._transform.camera=this._camera,this._transform.addEventListener("objectChange",this.onUpdateTransform),i.length>0&&this._transform.attach(i[i.length-1]),o.instance?.helpersContainer.add(this._transform.getHelper());const n=i.length>0?i[i.length-1].position:{x:0,y:0,z:0};this.group=e.addGroup({title:this.name,expanded:t,items:[{prop:"Closed",type:"boolean",value:this.closed},{prop:"Visible",type:"boolean",value:this.visible},{prop:"Show Position",type:"boolean",value:this.curvePos.visible},{prop:"Show Points",type:"boolean",value:this.draggable.visible},{prop:"Color",type:"color",value:`#${this.draggedMat.color.getHexString()}`},{prop:"Curve",type:"option",options:[{title:"Catmullrom",value:"catmullrom"},{title:"Centripetal",value:"centripetal"},{title:"Chordal",value:"chordal"}]},{prop:"Draggable Scale",type:"range",min:.01,max:100,step:.01,value:this._draggableScale},{prop:"Subdivide",type:"range",min:1,max:1e3,step:1,value:this.subdivide},{prop:"Tension",type:"range",min:0,max:1,step:.01,value:this.tension},{prop:"New Pt Offset",type:"range",min:0,max:10,value:this.offset},{prop:"Curve At",type:"range",min:0,max:1,step:.01,value:0},{prop:"Toggle Transform",type:"button"},{prop:"Add Point",type:"button"},{prop:"Remove Point",type:"button"},{prop:"Export",type:"button"},{prop:"Delete",type:"button"},{prop:"Current Point",type:"grid3",value:n}],onUpdate:(a,r)=>{switch(a){case"Closed":this.closed=r,this.updateSpline();break;case"Visible":this.visible=r;break;case"Color":this.lineMaterial.color.setStyle(r),this.draggedMat.color.setStyle(r);break;case"Curve":this.curveType=r,this.updateSpline();break;case"Draggable Scale":this.draggableScale=r;break;case"Subdivide":this.subdivide=r,this.updateSpline();break;case"Tension":this.tension=r,this.updateSpline();break;case"New Pt Offset":this.offset=r;break;case"Curve At":this.curvePos.position.copy(this.getPointAt(r));break;case"Show Position":this.curvePos.visible=r;break;case"Show Points":this.draggable.visible=r;break;case"Toggle Transform":this._transform&&(this._transform.getHelper().visible=!this._transform.getHelper().visible);break;case"Add Point":this.addNextPt();break;case"Remove Point":this.removeSelectedPt();break;case"Export":this.exportSpline();break;case"Delete":this.parent.currentSpline=null,g.dispose(this);break;case"Current Point":if(this.group.current&&this._transform?.object){const d=this._transform?.object;d.name.search("point")>-1&&(d.position.copy(r),this.updateSpline())}break}}}),this.draggable.children.forEach(a=>{this.debugPoint(a)})}debugPoint=e=>{e.name,e.visible=this.draggable.visible}}module.exports=m;