@animech-public/playcanvas
Version:
PlayCanvas WebGL game engine
2 lines (1 loc) • 6.35 kB
JavaScript
import{math as s}from"../../core/math/math.js";import{Color as t}from"../../core/math/color.js";import{Quat as e}from"../../core/math/quat.js";import{Vec3 as o}from"../../core/math/vec3.js";import{Ray as i}from"../../core/shape/ray.js";import{Plane as r}from"../../core/shape/plane.js";import{PROJECTION_PERSPECTIVE as h}from"../../scene/constants.js";import{COLOR_RED as a,COLOR_GREEN as n,COLOR_BLUE as _,COLOR_YELLOW as l,COLOR_GRAY as c,color4from3 as p,color3from4 as m}from"./color.js";import{GIZMOAXIS_X as d,GIZMOAXIS_Y as g,GIZMOAXIS_Z as x,GIZMOAXIS_FACE as S,GIZMOAXIS_XYZ as f}from"./constants.js";import{Gizmo as u}from"./gizmo.js";const y=new o,A=new o,E=new e,T=new i,C=new r,P=Object.keys(y);class v extends u{constructor(s,i){super(s,i),this._colorAlpha=.6,this._meshColors={axis:{x:this._colorSemi(a),y:this._colorSemi(n),z:this._colorSemi(_),xyz:this._colorSemi(t.WHITE),f:this._colorSemi(t.WHITE)},hover:{x:a.clone(),y:n.clone(),z:_.clone(),xyz:t.WHITE.clone(),f:l.clone()},disabled:c.clone()},this._guideColors={x:a.clone(),y:n.clone(),z:_.clone(),f:l.clone()},this._rootStartPos=new o,this._rootStartRot=new e,this._shading=!1,this._shapes={},this._shapeMap=new Map,this._hoverShape=null,this._hoverAxis="",this._hoverIsPlane=!1,this._noSelection=!1,this._selectedAxis="",this._selectedIsPlane=!1,this._selectionStartPoint=new o,this._dragging=!1,this._snap=!1,this.snapIncrement=1,this._app.on("prerender",(()=>{this.root.enabled&&this._drawGuideLines()})),this.on(u.EVENT_POINTERDOWN,((s,t,e)=>{const o=this._shapeMap.get(e);if(null!=o&&o.disabled)return;if(this._dragging)return;if(!e)return void(this._noSelection=!0);this._selectedAxis=this._getAxis(e),this._selectedIsPlane=this._getIsPlane(e),this._rootStartPos.copy(this.root.getPosition()),this._rootStartRot.copy(this.root.getRotation());const i=this._screenToPoint(s,t);this._selectionStartPoint.copy(i),this._dragging=!0,this.fire(v.EVENT_TRANSFORMSTART,i,s,t)})),this.on(u.EVENT_POINTERMOVE,((s,t,e)=>{const o=this._shapeMap.get(e);if(null!=o&&o.disabled)return;if(this._noSelection||this._hover(e),!this._dragging)return;const i=this._screenToPoint(s,t);this.fire(v.EVENT_TRANSFORMMOVE,i,s,t),this._hoverAxis="",this._hoverIsPlane=!1})),this.on(u.EVENT_POINTERUP,((s,t,e)=>{this._noSelection=!1,this._hover(e),this._dragging&&(this._dragging=!1,this.fire(v.EVENT_TRANSFORMEND),this._selectedAxis="",this._selectedIsPlane=!1)})),this.on(u.EVENT_NODESDETACH,(()=>{this.snap=!1,this._hoverAxis="",this._hoverIsPlane=!1,this._hover(),this.fire(u.EVENT_POINTERUP)}))}set shading(s){this._shading=this.root.enabled&&s;for(const s in this._shapes)this._shapes[s].shading=this._shading}get shading(){return this._shading}set snap(s){this._snap=this.root.enabled&&s}get snap(){return this._snap}set xAxisColor(s){this._updateAxisColor(d,s)}get xAxisColor(){return this._meshColors.axis.x}set yAxisColor(s){this._updateAxisColor(g,s)}get yAxisColor(){return this._meshColors.axis.y}set zAxisColor(s){this._updateAxisColor(x,s)}get zAxisColor(){return this._meshColors.axis.z}set colorAlpha(t){this._colorAlpha=s.clamp(t,0,1),this._meshColors.axis.x.copy(this._colorSemi(this._meshColors.axis.x)),this._meshColors.axis.y.copy(this._colorSemi(this._meshColors.axis.y)),this._meshColors.axis.z.copy(this._colorSemi(this._meshColors.axis.z)),this._meshColors.axis.xyz.copy(this._colorSemi(this._meshColors.axis.xyz)),this._meshColors.axis.f.copy(this._colorSemi(this._meshColors.axis.f));for(const s in this._shapes)this._shapes[s].hover(!!this._hoverAxis)}get colorAlpha(){return this._colorAlpha}_colorSemi(s){return p(s,this._colorAlpha)}_updateAxisColor(s,t){const e=m(t),o=this._colorSemi(t);this._guideColors[s].copy(e),this._meshColors.axis[s].copy(o),this._meshColors.hover[s].copy(e);for(const s in this._shapes)this._shapes[s].hover(!!this._hoverAxis)}_getAxis(s){return s?s.node.name.split(":")[1]:""}_getIsPlane(s){return!!s&&-1!==s.node.name.indexOf("plane")}_hover(s){var t;if(this._dragging)return;this._hoverAxis=this._getAxis(s),this._hoverIsPlane=this._getIsPlane(s);const e=s&&null!=(t=this._shapeMap.get(s))?t:null;e!==this._hoverShape&&(this._hoverShape&&(this._hoverShape.hover(!1),this._hoverShape=null),e&&(e.hover(!0),this._hoverShape=e),this.fire(u.EVENT_RENDERUPDATE))}_createRay(s){if(this._camera.projection===h)return T.origin.copy(this._camera.entity.getPosition()),T.direction.sub2(s,T.origin).normalize(),T;const t=this._camera.farClip-this._camera.nearClip;return T.origin.sub2(s,y.copy(this._camera.entity.forward).mulScalar(t)),T.direction.copy(this._camera.entity.forward),T}_createPlane(s,t,e){const o=y.copy(this.facing),i=C.normal.set(0,0,0);return t?i.copy(o):(i[s]=1,this._rootStartRot.transformVector(i,i),e&&(A.cross(i,o).normalize(),i.cross(A,i).normalize())),C.setFromPointNormal(this._rootStartPos,i)}_dirFromAxis(s,t){return s===S?t.copy(this._camera.entity.forward).mulScalar(-1):(t.set(0,0,0),t[s]=1),t}_projectToAxis(s,t){y.set(0,0,0),y[t]=1,s.copy(y.mulScalar(y.dot(s)));const e=s[t];s.set(0,0,0),s[t]=e}_screenToPoint(s,t,e=!1,i=!1){const r=this._camera.screenToWorld(s,t,1),h=this._selectedAxis,a=this._createRay(r),n=this._createPlane(h,e,i),_=new o;return n.intersectsRay(a,_),_}_drawGuideLines(){const s=this.root.getPosition(),t=E.copy(this.root.getRotation()),e=this._hoverAxis||this._selectedAxis,o=this._hoverIsPlane||this._selectedIsPlane;for(let i=0;i<P.length;i++){const r=P[i];e!==f?o?r!==e&&this._drawSpanLine(s,t,r):r===e&&this._drawSpanLine(s,t,r):this._drawSpanLine(s,t,r)}}_drawSpanLine(s,t,e){y.set(0,0,0),y[e]=1,y.mulScalar(this._camera.farClip-this._camera.nearClip),A.copy(y).mulScalar(-1),t.transformVector(y,y),t.transformVector(A,A),this._app.drawLine(y.add(s),A.add(s),this._guideColors[e],!0)}_createTransform(){for(const s in this._shapes){const t=this._shapes[s];this.root.addChild(t.entity),this.intersectShapes.push(t);for(let s=0;s<t.meshInstances.length;s++)this._shapeMap.set(t.meshInstances[s],t)}}enableShape(s,t){this._shapes.hasOwnProperty(s)&&(this._shapes[s].disabled=!t)}isShapeEnabled(s){return!!this._shapes.hasOwnProperty(s)&&!this._shapes[s].disabled}destroy(){super.destroy();for(const s in this._shapes)this._shapes[s].destroy()}}v.EVENT_TRANSFORMSTART="transform:start",v.EVENT_TRANSFORMMOVE="transform:move",v.EVENT_TRANSFORMEND="transform:end";export{v as TransformGizmo};