UNPKG

@onirix/camera-controls-module

Version:

Onirix helper library for camera controls.

2 lines (1 loc) 29.1 kB
function t(t){return t}const e=h(3),i=u(3),s=a(e,i),n=l(.25),o=c(.25),r=a(l(.5),c(.5));function a(t,e){return i=>i<.5?t(2*i)/2:(1+e(2*i-1))/2}function h(t){return e=>Math.pow(e,t)}function u(t){return e=>1-Math.pow(1-e,t)}function l(t){const e=1/(2*t-t*t-1),i=-2*e,s=e+1;return t=>{const n=t*t;return e*(n*t)+i*n+s*t}}function c(t){const e=1/(2*t-t*t-1),i=-e;return t=>{const s=t*t;return e*(s*t)+i*s+t}}const _=1e-8;var d,m;class p{get x(){return this._x}get y(){return this._y}get z(){return this._z}constructor(t,e,i){this._x=0,this._y=0,this._z=0,this._x=null==t?this._x:t,this._y=null==e?this._y:e,this._z=null==i?this._z:i}add(t){return"number"==typeof t?new p(this.x+t,this.y+t,this.z+t):new p(this.x+t.x,this.y+t.y,this.z+t.z)}sub(t){return"number"==typeof t?new p(this.x-t,this.y-t,this.z-t):new p(this.x-t.x,this.y-t.y,this.z-t.z)}prod(t){return"number"==typeof t?new p(this.x*t,this.y*t,this.z*t):new p(this.x*t.x,this.y*t.y,this.z*t.z)}div(t){return"number"==typeof t?new p(this.x/t,this.y/t,this.z/t):new p(this.x/t.x,this.y/t.y,this.z/t.z)}dot(t){return this.x*t.x+this.y*t.y+this.z*t.z}cross(t){return new p(this.y*t.z-this.z*t.y,this.z*t.x-this.x*t.z,this.x*t.y-this.y*t.x)}abs(){return Math.sqrt(this.dot(this))}normalized(){return 0===this.abs()?new p(0,0,0):this.div(this.abs())}angle(t){return Math.acos(this.dot(t)/(this.abs()*t.abs()))}projectAbs(t){return this.dot(t)/this.abs()}project(t){const e=this.normalized(),i=e.dot(t);return e.prod(i)}negate(){return new p(-this.x,-this.y,-this.z)}equals(t){return this===t||Math.abs(this.x-t.x)<_&&Math.abs(this.y-t.y)<_&&Math.abs(this.z-t.z)<_}orthonormal(){return Math.abs(this.x)>=_?[new p(-this.z,0,this.x),new p(this.y,-this.x,0)]:Math.abs(this.y)>=_?[new p(0,this.z,-this.y),new p(this.y,-this.x,0)]:Math.abs(this.z)>=_?[new p(0,this.z,-this.y),new p(-this.z,0,this.x)]:void 0}max(t){const e=Math.max(this.x,t.x),i=Math.max(this.y,t.y),s=Math.max(this.z,t.z);return new p(e,i,s)}min(t){const e=Math.min(this.x,t.x),i=Math.min(this.y,t.y),s=Math.min(this.z,t.z);return new p(e,i,s)}clamp(t,e){return this.min(e).max(t)}distance(t){return this.sub(t).abs()}}p.ZERO=new(d=p)(0,0,0),p.X=new d(1,0,0),p.Y=new d(0,1,0),p.Z=new d(0,0,1),p.UP=d.Y,p.DOWN=d.Y.negate(),p.LEFT=d.X.negate(),p.RIGHT=d.X,p.FRONT=d.Z.negate(),p.BACK=d.Z;class w{get x(){return this._x}get y(){return this._y}get z(){return this._z}get w(){return this._w}constructor(t,e,i,s){this._x=0,this._y=0,this._z=0,this._w=0,this._x=null==t?this._x:t,this._y=null==e?this._y:e,this._z=null==i?this._z:i,this._w=null==s?this._w:s}static betweenVectors(t,e,i=p.UP){return w.forDirection(e,t,i)}static forDirection(t,e=p.FRONT,i=p.UP){if(t.equals(p.ZERO)||e.equals(p.ZERO)||i.equals(p.ZERO))return w.IDENTITY;t=t.normalized(),e=e.normalized(),i=i.normalized();let s=e.cross(t);Math.abs(s.abs())<_&&(s=e.orthonormal()[0].normalized());const n=e.angle(t);let o=w.forRotationAroundAxis(s,n);const r=o.apply(i),a=r.sub(e.project(r)),h=i.sub(e.project(i));if(a.equals(p.ZERO)||h.equals(p.ZERO))return o;const u=h.angle(a),l=h.cross(a).normalized();return o=o.append(w.forRotationAroundAxis(l,u)),o}static forRotationAroundAxis(t,e){t=t.normalized();const i=Math.sin(e/2),s=i*t.x,n=i*t.y,o=i*t.z,r=Math.cos(e/2);return new w(s,n,o,r)}static forXRotation(t){return new w(Math.sin(t/2),0,0,Math.cos(t/2))}static forYRotation(t){return new w(0,Math.sin(t/2),0,Math.cos(t/2))}static forZRotation(t){return new w(0,0,Math.sin(t/2),Math.cos(t/2))}static forEuler(t,e,i){const s=Math.cos(t/2),n=Math.sin(t/2),o=Math.cos(e/2),r=Math.sin(e/2),a=Math.cos(i/2),h=Math.sin(i/2);return new w(n*o*a+s*r*h,s*r*a-n*o*h,s*o*h+n*r*a,s*o*a-n*r*h)}static sequence(...t){let e=t[0];for(let i=1;i<t.length;i++)e=e.append(t[i]);return e}static extractYaw(t){return Math.atan2(2*(t.w*t.y+t.x*t.z),1-2*(t.y*t.y+t.z*t.z))}conjugate(){return new w(-this.x,-this.y,-this.z,this.w)}inverse(){return this.conjugate().div(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)}add(t){return"number"==typeof t?new w(this.x+t,this.y+t,this.z+t,this.w+t):new w(this.x+t.x,this.y+t.y,this.z+t.z,this.w+t.w)}sub(t){return"number"==typeof t?new w(this.x-t,this.y-t,this.z-t,this.w-t):new w(this.x-t.x,this.y-t.y,this.z-t.z,this.w-t.w)}prod(t){return"number"==typeof t?new w(this.x*t,this.y*t,this.z*t,this.w*t):new w(this.w*t.x+this.x*t.w+this.y*t.z-this.z*t.y,this.w*t.y+this.y*t.w+this.z*t.x-this.x*t.z,this.w*t.z+this.z*t.w+this.x*t.y-this.y*t.x,this.w*t.w-this.x*t.x-this.y*t.y-this.z*t.z)}div(t){return"number"==typeof t?new w(this.x/t,this.y/t,this.z/t,this.w/t):this.prod(t.inverse())}negate(){return new w(-this.x,-this.y,-this.z,-this.w)}equals(t){return this===t||Math.abs(this.x-t.x)<_&&Math.abs(this.y-t.y)<_&&Math.abs(this.z-t.z)<_&&Math.abs(this.w-t.w)<_}prepend(t){return t.prod(this)}append(t){return this.prod(t)}axis(){const t=this.normalized(),e=Math.sqrt(1-t.w*t.w);return this.vector().div(e)}angle(){return 2*Math.atan2(this.vector().abs(),this.w)}vector(){return new p(this.x,this.y,this.z)}scalar(){return this.w}exp(){if(this.abs()<_)return w.IDENTITY;const t=this.scalar(),e=this.vector(),i=e.abs(),s=Math.exp(t),n=e.prod(s*Math.sin(i)/i),o=s*Math.cos(i);return new w(n.x,n.y,n.z,o)}log(){const t=this.scalar(),e=this.vector(),i=this.abs(),s=Math.log(i),n=e.normalized().prod(Math.acos(t/i));return new w(n.x,n.y,n.z,s)}pow(t){return this.log().prod(t).exp()}apply(t){t=new w(t.x,t.y,t.z,0);const e=this.normalized(),i=e.conjugate(),s=e.prod(t).prod(i);return new p(s.x,s.y,s.z)}abs(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)}normalized(){const t=this.abs();return new w(this.x/t,this.y/t,this.z/t,this.w/t)}distance(t){return this.inverse().prod(t).angle()}}function f(t,e){if(t instanceof p||t instanceof w){const i=e.sub(t);return e=>t.add(i.prod(e))}if("number"==typeof t){const i=e-t;return e=>t+i*e}throw new TypeError(`Linear interpolation is not defined for type '${typeof t}'`)}function v(t,e=void 0,i=p.UP){function s(t,e){if(t instanceof p){const s=v(w.IDENTITY,w.betweenVectors(t.negate(),e.negate(),i)),n=t.abs(),o=f(n,e.abs());return t=n<_?e.normalized():t.normalized(),e=>{const i=s(e),n=o(e);return i.apply(t).prod(n)}}if(t instanceof w){const i=t.inverse().prod(e);return e=>t.prod(i.pow(e))}throw new TypeError(`Spherical interpolation is not defined for type '${typeof t}'`)}if(null==e){const e=t;return(t,i)=>{const n=s(t.sub(e),i.sub(e));return t=>n(t).add(e)}}return s(t,e)}function y(t,e,i=null){return 0===e?b(()=>t(1))():b(s=>{const n=b(o=>{const r=Math.min((o-s)/e,1);if(t(r),o<s+e&&(null==i||!i.aborted))return n()});return n()})()}function g(t){let e=!1,i=null;const s=b((...i)=>(e=!1,t(...i)));return(...t)=>(e||(i=s(t),e=!0),i)}function b(t){return(...e)=>new Promise(i=>window.requestAnimationFrame(s=>i(t(s,...e))))}w.ZERO=new(m=w)(0,0,0,0),w.IDENTITY=new m(0,0,0,1);var x={__proto__:null,linear:t,cubicEaseIn:e,cubicEaseOut:i,cubicEaseInOut:s,bounceIn:n,bounceOut:o,bounceInOut:r,easeInOutFactory:a,polynomialEaseInFactory:h,polynomialEaseOutFactory:u,bounceInFactory:l,bounceOutFactory:c,linearInterpolator:f,sphericalInterpolator:v,animate:y,debounced:g,deferred:b};class E{get array(){return[...this._array]}constructor(t){this._array=void 0,null==t&&((t=Array(16).fill(0))[0]=1,t[5]=1,t[10]=1,t[15]=1),this._array=t}static identity(){const t=Array(16).fill(0);return t[0]=1,t[5]=1,t[10]=1,t[15]=1,new E(t)}static fromRotationTranslation(t,e){let i=t.x+t.x,s=t.y+t.y,n=t.z+t.z,o=t.x*i,r=t.x*s,a=t.x*n,h=t.y*s,u=t.y*n,l=t.z*n,c=t.w*i,_=t.w*s,d=t.w*n;const m=Array(16).fill(0);return m[0]=1-(h+l),m[1]=r-d,m[2]=a+_,m[3]=e.x,m[4]=r-d,m[5]=1-(o+l),m[6]=u-c,m[7]=e.y,m[8]=a-_,m[9]=u+c,m[10]=1-(o+h),m[11]=e.z,m[12]=0,m[13]=0,m[14]=0,m[15]=1,new E(m)}getPosition(){const t=this._array;return new p(t[3],t[7],t[11])}getQuaternion(){const t=this._array,e=t[0],i=t[1],s=t[2],n=t[4],o=t[5],r=t[6],a=t[8],h=t[9],u=t[10],l=e+o+u;let c,_,d,m,p;return l>0?(c=.5/Math.sqrt(l+1),p=.25/c,_=(h-r)*c,d=(s-a)*c,m=(n-i)*c):e>o&&e>u?(c=2*Math.sqrt(1+e-o-u),p=(h-r)/c,_=.25*c,d=(i+n)/c,m=(s+a)/c):o>u?(c=2*Math.sqrt(1+o-e-u),p=(s-a)/c,_=(i+n)/c,d=.25*c,m=(r+h)/c):(c=2*Math.sqrt(1+u-e-o),p=(n-i)/c,_=(s+a)/c,d=(r+h)/c,m=.25*c),new w(_,d,m,p)}static translate(t){return new E([1,0,0,t.x,0,1,0,t.y,0,0,1,t.z,0,0,0,1])}static rotate(t){const e=t.x,i=t.x*t.x,s=t.y,n=t.y*t.y,o=t.z,r=t.z*t.z,a=t.w;return new E([1-2*n-2*r,2*e*s-2*o*a,2*e*o+2*s*a,0,2*e*s+2*o*a,1-2*i-2*r,2*s*o-2*e*a,0,2*e*o-2*s*a,2*s*o+2*e*a,1-2*i-2*n,0,0,0,0,1])}static invert(t){const e=Array(16).fill(0),i=t._array;let s=i[0],n=i[1],o=i[2],r=i[3],a=i[4],h=i[5],u=i[6],l=i[7],c=i[8],_=i[9],d=i[10],m=i[11],p=i[12],w=i[13],f=i[14],v=i[15],y=s*h-n*a,g=s*u-o*a,b=s*l-r*a,x=n*u-o*h,z=n*l-r*h,T=o*l-r*u,M=c*w-_*p,O=c*f-d*p,P=c*v-m*p,R=_*f-d*w,A=_*v-m*w,I=d*v-m*f,N=y*I-g*A+b*R+x*P-z*O+T*M;return N?(N=1/N,e[0]=(h*I-u*A+l*R)*N,e[1]=(o*A-n*I-r*R)*N,e[2]=(w*T-f*z+v*x)*N,e[3]=(d*z-_*T-m*x)*N,e[4]=(u*P-a*I-l*O)*N,e[5]=(s*I-o*P+r*O)*N,e[6]=(f*b-p*T-v*g)*N,e[7]=(c*T-d*b+m*g)*N,e[8]=(a*A-h*P+l*M)*N,e[9]=(n*P-s*A-r*M)*N,e[10]=(p*z-w*b+v*y)*N,e[11]=(_*b-c*z-m*y)*N,e[12]=(h*O-a*R-u*M)*N,e[13]=(s*R-n*O+o*M)*N,e[14]=(w*g-p*x-f*y)*N,e[15]=(c*x-_*g+d*y)*N,new E(e)):null}static sequence(...t){if(0===t.length)return;let e=t[0];for(let i=1;i<t.length;i++)e=e.prepend(t[i]);return e}prod(t){const e=this._array,i=t._array;return new E([e[0]*i[0]+e[1]*i[4]+e[2]*i[8]+e[3]*i[12],e[0]*i[1]+e[1]*i[5]+e[2]*i[9]+e[3]*i[13],e[0]*i[2]+e[1]*i[6]+e[2]*i[10]+e[3]*i[14],e[0]*i[3]+e[1]*i[7]+e[2]*i[11]+e[3]*i[15],e[4]*i[0]+e[5]*i[4]+e[6]*i[8]+e[7]*i[12],e[4]*i[1]+e[5]*i[5]+e[6]*i[9]+e[7]*i[13],e[4]*i[2]+e[5]*i[6]+e[6]*i[10]+e[7]*i[14],e[4]*i[3]+e[5]*i[7]+e[6]*i[11]+e[7]*i[15],e[8]*i[0]+e[9]*i[4]+e[10]*i[8]+e[11]*i[12],e[8]*i[1]+e[9]*i[5]+e[10]*i[9]+e[11]*i[13],e[8]*i[2]+e[9]*i[6]+e[10]*i[10]+e[11]*i[14],e[8]*i[3]+e[9]*i[7]+e[10]*i[11]+e[11]*i[15],e[12]*i[0]+e[13]*i[4]+e[14]*i[8]+e[15]*i[12],e[12]*i[1]+e[13]*i[5]+e[14]*i[9]+e[15]*i[13],e[12]*i[2]+e[13]*i[6]+e[14]*i[10]+e[15]*i[14],e[12]*i[3]+e[13]*i[7]+e[14]*i[11]+e[15]*i[15]])}prepend(t){return t.prod(this)}append(t){return this.prod(t)}apply(t){const e=this._array;return new p(e[0]*t.x+e[1]*t.y+e[2]*t.z+e[3],e[4]*t.x+e[5]*t.y+e[6]*t.z+e[7],e[8]*t.x+e[9]*t.y+e[10]*t.z+e[11])}}class z{get abortSignal(){return this._abortController.signal}get isAnimating(){return this._animationsRunning>0}get position(){return this._position}set position(t){this._position=t,this._triggerEvent(z.events.POSITION_CHANGE,[t]),this.update()}get rotation(){return this._rotation}set rotation(t){this._rotation=t,this._triggerEvent(z.events.ROTATION_CHANGE,[t]),this.update()}constructor(t,e){this.up=p.UP,this.front=p.FRONT,this.orientation="horizontal",this._abortController=new AbortController,this._animationsRunning=0,this.defaultPreviewHorizontalPosition=new p(0,1,2).normalized().prod(5),this.defaultPreviewVerticalPosition=new p(0,0,5),this._position=p.ZERO,this.defaultPreviewHorizontalRotation=w.forDirection(new p(0,-1,-2).normalized()),this.defaultPreviewVerticalRotation=w.forXRotation(-Math.PI/2),this._rotation=w.IDENTITY,this._sdk=null,this._platform=null,this._lookAt=null,this._eventListeners={},this.update=g(()=>{this._update()}),this._sdk=t,this._platform=e,this._onSceneLoadEnd=this._onSceneLoadEnd.bind(this),this._registerSDKEvents(),this.reset()}_registerSDKEvents(){this._sdk.subscribe("SCENE_LOAD_END",this._onSceneLoadEnd),"AR"===this._platform&&this._sdk.subscribe("ON_POSE",this._onPose.bind(this))}_onSceneLoadEnd(t){if("AR"!==this._platform){if(this.orientation!==t.orientation){switch(this.orientation=t.orientation,this.orientation){case"horizontal":this.up=p.UP,this.front=p.FRONT;break;case"vertical":this.up=p.FRONT,this.front=p.DOWN}this._triggerEvent(z.events.ORIENTATION_CHANGE,[this.orientation])}}else{const e=t.transform.position,i=t.transform.quaternion,s=new p(e.x,e.y,e.z),n=new w(i.x,i.y,i.z,i.w);this._sceneTransformMatrix=E.fromRotationTranslation(n,s)}this.reset()}_onPose(t){const e=new p(t.position.x,t.position.y,t.position.z),i=new w(t.quaternion.x,t.quaternion.y,t.quaternion.z,t.quaternion.w);this._poseTransformMatrix=E.fromRotationTranslation(i,e)}dispose(){this._triggerEvent(z.events.DISPOSE),this._unregisterSDKEvents()}_unregisterSDKEvents(){this._sdk.unsubscribe("SCENE_LOAD_END",this._onSceneLoadEnd),"AR"===this._platform&&this._sdk.unsubscribe("ON_POSE",this._onPose)}reset(){if(this._sdk.disableCameraControls(),this.abortAnimations(),"AR"!==this._platform)switch(this.orientation){case"horizontal":this.position=this.defaultPreviewHorizontalPosition,this.rotation=this.defaultPreviewHorizontalRotation;break;case"vertical":this.position=this.defaultPreviewVerticalPosition,this.rotation=this.defaultPreviewVerticalRotation}else this.position=p.ZERO,this.rotation=w.IDENTITY;this.update(),this._triggerEvent(z.events.POSITION_CHANGE,[this.position]),this._triggerEvent(z.events.ROTATION_CHANGE,[this.rotation]),this._triggerEvent(z.events.RESET)}_triggerEvent(t,e=[]){if(t in this._eventListeners)for(const i of this._eventListeners[t])i(...e)}addEventListener(t,e){-1!==Object.values(z.events).indexOf(t)&&(t in this._eventListeners||(this._eventListeners[t]=[]),this._eventListeners[t].push(e))}removeEventListener(t,e){if(-1===Object.values(z.events).indexOf(t))return;if(!(t in this._eventListeners))return;const i=this._eventListeners[t].indexOf(e);-1!==i&&this._eventListeners[t].splice(i,1)}_update(){const t=E.translate(this._position),e=E.rotate(this._rotation),i=E.sequence(e,t);this._sdk.setCameraRigTransform(i.array)}startAnimation(){this._animationsRunning=this._animationsRunning+1}stopAnimation(){this._animationsRunning=this._animationsRunning-1}abortAnimations(){this._abortController.abort(),this._abortController=new AbortController}async translateTo(e,i=0,s=t,n=f){if(this._position.equals(e))return;const o=n(this._position,e,this.up);this.startAnimation(),await y(t=>{const e=s(t),i=o(e);this._position=i,this._update(),this._triggerEvent(z.events.POSITION_CHANGE,[i])},i,this.abortSignal),this.stopAnimation()}async rotateTo(e,i=0,s=t,n=v){if(this._rotation.equals(e))return;const o=n(this._rotation,e,this.up);this.startAnimation(),await y(t=>{const e=s(t),i=o(e);this._rotation=i,this._update(),this._triggerEvent(z.events.ROTATION_CHANGE,[i])},i,this.abortSignal),this.stopAnimation()}lookAt(e,i=0,s=t,n=v){const o=e.sub(this._position);if(o.equals(p.ZERO))return;const r=w.forDirection(o,this.front,this.up);return this.rotateTo(r,i,s,n)}async animateTo(e=void 0,i=void 0,s=0,n=t,o=v,r=v,a="local"){if(void 0===e&&(e=this.position),void 0===i){const t=this._poseTransformMatrix?this._poseTransformMatrix.getPosition():this.position,s=e.sub(t).normalized();i=e.add(s),this._lookAt=i}let h=e,u=i;"local"===a&&this._sceneTransformMatrix&&(h=this._sceneTransformMatrix.apply(e),u=this._sceneTransformMatrix.apply(i));const l=u.sub(h),c=w.forDirection(l,this.front,this.up);let _,d;if(this._poseTransformMatrix){const t=E.fromRotationTranslation(c,h),e=w.extractYaw(t.getQuaternion()),i=w.extractYaw(this._poseTransformMatrix.getQuaternion()),s=w.forYRotation(e-i),n=s.apply(this._poseTransformMatrix.getPosition()),a=t.getPosition().sub(n);_=o(this._position,a),d=r(this._rotation,s)}else _=o(this._position,h),d=r(this._rotation,c);this.startAnimation(),await y(t=>{const e=n(t),i=_(e);this._position=i,this._triggerEvent(z.events.POSITION_CHANGE,[i]);const s=d(e);this._rotation=s,this._triggerEvent(z.events.ROTATION_CHANGE,[s]),this._update()},s),this.stopAnimation()}}z.events={POSITION_CHANGE:"positionchange",ROTATION_CHANGE:"rotationchange",ORIENTATION_CHANGE:"orientationchange",RESET:"reset",DISPOSE:"dispose"};class T{get locked(){return this._camera.isAnimating||this._locked}set locked(t){this._locked=t}get target(){return this._target}set target(t){this._target=t,this.update()}get pan(){return this._pan}set pan(t){this._pan=t,this.update()}get rotation(){return this._rotation}set rotation(t){this._rotation=t,this.update()}get zoom(){return this._zoom}set zoom(t){this._zoom=t,this.update()}constructor(t,e=!1,i=document.querySelector("canvas")){this._camera=null,this._eventTarget=null,this._locked=!1,this.allowPan=!0,this.allowRotation=!0,this.allowZoom=!0,this.primaryAxis=p.UP,this.secondaryAxis=p.RIGHT,this._target=p.ZERO,this.defaultPan=p.ZERO,this._pan=this.defaultPan,this.panSpeed=new p(-2/Math.min(window.innerWidth,window.innerHeight),2/Math.min(window.innerWidth,window.innerHeight),0),this.minPan=new p(-Infinity,-Infinity,-Infinity),this.maxPan=new p(Infinity,Infinity,Infinity),this.defaultHorizontalRotation=w.forDirection(new p(0,-1,-2).normalized()),this.defaultVerticalRotation=w.forXRotation(-Math.PI/2),this._rotation=this.defaultHorizontalRotation,this.rotationSpeed=new p(Math.PI/(2*Math.min(window.innerWidth,window.innerHeight)),Math.PI/(2*Math.min(window.innerWidth,window.innerHeight)),0),this.minRotation=new p(-Infinity,-Infinity,-Infinity),this.maxRotation=new p(Infinity,Infinity,Infinity),this.defaultZoom=5,this._zoom=this.defaultZoom,this.zoomSpeed=.002,this.mouseWheelStep=10,this.minZoom=_,this.maxZoom=10,this._state=null,this._lastPointerPosition=null,this._lastTouchDistance=null,this.update=g(()=>{this._update()}),this._camera=t,this._eventTarget=i,this._onOrientationChange=this._onOrientationChange.bind(this),this._onCameraUpdated=this._onCameraUpdated.bind(this),this.reset=this.reset.bind(this),this.dispose=this.dispose.bind(this),this._onTouchStart=this._onTouchStart.bind(this),this._onTouchMove=this._onTouchMove.bind(this),this._onTouchEnd=this._onTouchEnd.bind(this),this._onMouseDown=this._onMouseDown.bind(this),this._onMouseMove=this._onMouseMove.bind(this),this._onMouseUp=this._onMouseUp.bind(this),this._onMouseLeave=this._onMouseLeave.bind(this),this._onWheel=this._onWheel.bind(this),this._onContextMenu=this._onContextMenu.bind(this),this._registerCameraEvents(),this._registerDOMEvents(),this._onOrientationChange(this._camera.orientation),e?this.reset():this._onCameraUpdated()}_registerCameraEvents(){this._camera.addEventListener(z.events.ORIENTATION_CHANGE,this._onOrientationChange),this._camera.addEventListener(z.events.POSITION_CHANGE,this._onCameraUpdated),this._camera.addEventListener(z.events.ROTATION_CHANGE,this._onCameraUpdated),this._camera.addEventListener(z.events.RESET,this.reset),this._camera.addEventListener(z.events.DISPOSE,this.dispose)}_onOrientationChange(t){const e=this._camera.up.cross(this._camera.front.negate());switch(t){case"horizontal":this.primaryAxis=this._camera.up,this.secondaryAxis=e;break;case"vertical":this.primaryAxis=this._camera.front,this.secondaryAxis=e}}_onCameraUpdated(){const t=this._camera.rotation,e=t.apply(this._camera.front).normalized(),i=new p(Math.abs(e.x)<_?0:e.x,Math.abs(e.y)<_?0:e.y,Math.abs(e.z)<_?0:e.z),s=this._camera.position.sub(this._target),n=s.div(i);let o=Math.max(Number.isFinite(n.x)?-n.x:_,Number.isFinite(n.y)?-n.y:_,Number.isFinite(n.z)?-n.z:_);Number.isFinite(o)||(o=_);const r=s.sub(i.prod(-o));this._rotation=t,this._zoom=o,this._pan=r}_registerDOMEvents(){this._eventTarget.addEventListener("touchstart",this._onTouchStart,{capture:!0,passive:!1}),this._eventTarget.addEventListener("touchmove",this._onTouchMove,{capture:!0,passive:!1}),this._eventTarget.addEventListener("touchend",this._onTouchEnd,{capture:!0,passive:!1}),this._eventTarget.addEventListener("mousedown",this._onMouseDown,{capture:!0,passive:!1}),this._eventTarget.addEventListener("mousemove",this._onMouseMove,{capture:!0,passive:!1}),this._eventTarget.addEventListener("mouseup",this._onMouseUp,{capture:!0,passive:!1}),this._eventTarget.addEventListener("mouseleave",this._onMouseLeave,{capture:!0,passive:!1}),this._eventTarget.addEventListener("wheel",this._onWheel,{capture:!0,passive:!1}),this._eventTarget.addEventListener("contextmenu",this._onContextMenu)}_onContextMenu(t){t.preventDefault()}dispose(){this._unregisterCameraEvents(),this._unregisterDOMEvents()}_unregisterCameraEvents(){this._camera.removeEventListener(z.events.ORIENTATION_CHANGE,this._onOrientationChange),this._camera.removeEventListener(z.events.POSITION_CHANGE,this._onCameraUpdated),this._camera.removeEventListener(z.events.ROTATION_CHANGE,this._onCameraUpdated),this._camera.removeEventListener(z.events.RESET,this.reset),this._camera.removeEventListener(z.events.DISPOSE,this.dispose)}_unregisterDOMEvents(){this._eventTarget.removeEventListener("touchstart",this._onTouchStart,!0),this._eventTarget.removeEventListener("touchmove",this._onTouchMove,!0),this._eventTarget.removeEventListener("touchend",this._onTouchEnd,!0),this._eventTarget.removeEventListener("mousedown",this._onMouseDown,!0),this._eventTarget.removeEventListener("mousemove",this._onMouseMove,!0),this._eventTarget.removeEventListener("mouseup",this._onMouseUp,!0),this._eventTarget.removeEventListener("mouseleave",this._onMouseLeave,!0),this._eventTarget.removeEventListener("wheel",this._onWheel,!0),this._eventTarget.removeEventListener("contextmenu",this._onContextMenu)}_onTouchStart(t){if(!this.locked)if(1===t.touches.length)this._state="rotate",this._lastPointerPosition=new p(t.touches[0].screenX,t.touches[0].screenY,0);else if(2===t.touches.length){this._state="pan + zoom";const e=new p(t.touches[0].screenX,t.touches[0].screenY,0),i=new p(t.touches[1].screenX,t.touches[1].screenY,0);this._lastPointerPosition=e.add(i).div(2),this._lastTouchDistance=e.distance(i)}}_onTouchMove(t){if(t.preventDefault(),!this.locked)if("rotate"===this._state&&t.touches.length>=1){const e=new p(t.touches[0].screenX,t.touches[0].screenY,0),i=e.sub(this._lastPointerPosition);this._doRotate(i),this._lastPointerPosition=e}else if("pan + zoom"===this._state&&t.touches.length>=2){const e=new p(t.touches[0].screenX,t.touches[0].screenY,0),i=new p(t.touches[1].screenX,t.touches[1].screenY,0),s=e.add(i).div(2),n=s.sub(this._lastPointerPosition);this._doPan(n);const o=e.distance(i);this._doZoom(this._lastTouchDistance-o),this._lastPointerPosition=s,this._lastTouchDistance=o}}_onTouchEnd(t){this.locked||1===t.touches.length&&(this._state=null,this._lastPointerPosition=null,this._lastTouchDistance=null)}_onMouseDown(t){this.locked||(1&t.buttons?this._state="rotate":6&t.buttons&&(this._state="pan"),this._state&&(this._lastPointerPosition=new p(t.screenX,t.screenY,0)))}_onMouseMove(t){if(t.preventDefault(),this.locked)return;const e=new p(t.screenX,t.screenY,0);if(this._state){const t=e.sub(this._lastPointerPosition);"rotate"===this._state?this._doRotate(t):"pan"===this._state&&this._doPan(t)}this._state=1&t.buttons?"rotate":6&t.buttons?"pan":null,this._lastPointerPosition=this._state?e:null}_onMouseUp(t){if(!this.locked){if(this._state){const e=new p(t.screenX,t.screenY,0).sub(this._lastPointerPosition);"rotate"===this._state?this._doRotate(e):"pan"===this._state&&this._doPan(e)}this._state=null,this._lastPointerPosition=null}}_onMouseLeave(){this.locked||(this._state=null,this._lastPointerPosition=null)}_onWheel(t){if(t.preventDefault(),!this.locked)if(t.wheelDeltaY?t.wheelDeltaY===-3*t.deltaY:0===t.deltaMode)this._doZoom(t.deltaY);else{const e=Math.sign(t.deltaY);this._doZoom(e*this.mouseWheelStep)}}_doRotate(t){if(!this.allowRotation)return;const e=this.rotationSpeed.negate().prod(t),i=w.sequence(w.forRotationAroundAxis(this.primaryAxis,e.x),this._rotation,w.forRotationAroundAxis(this.secondaryAxis,e.y));this._isValidRotation(i)&&(this._rotation=i,this.update())}_isValidRotation(t){const e=this._camera.up.cross(this._camera.front.negate()),i=Math.abs(t.apply(p.X).angle(e)),s=Math.abs(t.apply(p.Y).angle(this._camera.up)),n=Math.abs(t.apply(p.Z).angle(this._camera.front.negate()));return!(i<this.minRotation.x||i>this.maxRotation.x||s<this.minRotation.y||s>this.maxRotation.y||n<this.minRotation.z||n>this.maxRotation.z)}_doPan(t){if(!this.allowPan)return;const e=this._rotation.apply(t.prod(this.panSpeed));this._pan=this._pan.add(e).clamp(this.minPan,this.maxPan),this.update()}_doZoom(t){this.allowZoom&&(this._zoom=Math.max(Math.min(this._zoom+this.zoomSpeed*t,this.maxZoom),this.minZoom),this.update())}reset(){switch(this._camera.abortAnimations(),this._pan=this.defaultPan,this._camera.orientation){case"horizontal":this._rotation=this.defaultHorizontalRotation;break;case"vertical":this._rotation=this.defaultVerticalRotation}this._zoom=this.defaultZoom,this.update()}_update(){const t=this._rotation.apply(this._camera.front);this._camera._position=this._pan.add(this._target).add(t.prod(-this._zoom)),this._camera._rotation=this._rotation,this._camera._update()}async zoomTo(e,i=0,s=t,n=f){if(Math.abs(this._zoom-e)<_)return;const o=n(this._zoom,e,this.up);this._camera.startAnimation(),await y(t=>{const e=s(t);this._zoom=o(e),this._update()},i,this._camera.abortSignal),this._camera.stopAnimation()}async panTo(e,i=0,s=t,n=f){if(this._pan.equals(e))return;const o=n(this._pan,e,this.up);this._camera.startAnimation(),await y(t=>{const e=s(t);this._pan=o(e),this._update()},i,this._camera.abortSignal),this._camera.stopAnimation()}async targetTo(e,i=0,s=t,n=f){if(this._target.equals(e))return;const o=n(this._target,e,this.up);this._camera.startAnimation(),await y(t=>{const e=s(t);this._target=o(e),this._update()},i,this._camera.abortSignal),this._camera.stopAnimation()}async rotateTo(e,i=0,s=t,n=v){if(this._rotation.equals(e))return;const o=n(this._rotation,e,this.up);this._camera.startAnimation(),await y(t=>{const e=s(t);this._rotation=o(e),this._update()},i,this._camera.abortSignal),this._camera.stopAnimation()}}var M={__proto__:null,Matrix4:E,Quaternion:w,EPSILON:_,Vector3:p};class O{constructor(t,e=["PREVIEW"]){this._sdk=null,this._enabledPlatforms=["PREVIEW"],this._currentPlatform=null,this._enabled=!1,this.camera=null,this.controls=null,this._sdk=t,document.querySelector(".ox-webar-renderer--preview")&&(this._currentPlatform="PREVIEW"),document.querySelector(".ox-webar-renderer--ar")&&(this._currentPlatform="AR"),this._enabled=-1!==e.indexOf(this._currentPlatform),this._enabled&&(this.camera=new z(this._sdk,this._currentPlatform))}getEasingByName(t){if(t in O.easings)return O.easings[t];{const e=JSON.stringify(Object.keys(O.easings));throw new Error(`Invalid easing function. Expected one of ${e}, got '${t}'.`)}}getInterpolatorByName(t){if(t in O.interpolators)return O.interpolators[t];{const e=JSON.stringify(Object.keys(O.interpoators));throw new Error(`Invalid interpolator function. Expected one of ${e}, got '${t}'.`)}}parseMode(t){if(!t)return{};const e=t.split(" ");let i,s;if(1===e.length)e[0].includes("-in")||e[0].includes("-out")?i=this.getEasingByName(e[0]):s=this.getInterpolatorByName(e[0]);else{if(2!==e.length)throw new Error(`Invalid mode format. Expected '<transition> <easing>', '<easing>', or <transition>', got '${mode}'.`);s=this.getInterpolatorByName(e[0]),i=this.getEasingByName(e[1])}return{interpolator:s,easing:i}}disableControls(){this._enabled&&this.controls&&(this.controls.dispose(),this.controls=null)}async animateTo(t,e,i,s,n,o,r="linear linear-in-out",a=0,h=void 0,u=void 0,l=void 0){if(!this._enabled)return;let c,d;null!=t&&null!=e&&null!=i&&(c=new p(t,e,i)),null!=s&&null!=n&&null!=o&&(d=new p(s,n,o));const{easing:m,interpolator:w}=this.parseMode(r);let f=w,y=w;var g,b,x;f===v&&(null!=h&&null!=u&&null!=l?f=v(new p(h,u,l)):null!=(g=this.controls)&&g.target&&(f=v(this.controls.target))),await this.camera.animateTo(c,d,1e3*a,m,f,y),null!=this.controls&&(this.controls.target=null!=(b=d)?b:this.camera._lookAt,this.controls.pan=p.ZERO,this.controls.zoom=Math.max((null!=(x=d)?x:this.camera._lookAt).sub(c).abs(),_))}enableOrbitControls(){this._enabled&&"AR"!==this._currentPlatform&&(this.controls&&this.controls.dispose(),this.controls=new T(this.camera))}setOrbitControlsPanRange(t,e,i,s,n,o){if(this._enabled){if(!this.controls)throw new Error("The camera controls are currently disabled.");if(!(this.controls instanceof T))throw new Error("The camera controls are not orbit controls.");this.controls.minPan=new p(t,i,n),this.controls.maxPan=new p(e,s,o)}}setOrbitControlsRotateRange(t,e,i,s,n,o){if(this._enabled){if(!this.controls)throw new Error("The camera controls are currently disabled.");if(!(this.controls instanceof T))throw new Error("The camera controls are not orbit controls.");this.controls.minRotation=new p(t,i,n),this.controls.maxRotation=new p(e,s,o)}}setOrbitControlsZoomRange(t,e){if(this._enabled){if(!this.controls)throw new Error("The camera controls are currently disabled.");if(!(this.controls instanceof T))throw new Error("The camera controls are not orbit controls.");this.controls.minZoom=t,this.controls.maxZoom=e}}setOrbitControlsTarget(t,e,i){if(this._enabled){if(!this.controls)throw new Error("The camera controls are currently disabled.");if(!(this.controls instanceof T))throw new Error("The camera controls are not orbit controls.");this.controls.target=new p(t,e,i)}}}O.animation=x,O.math=M,O.Camera=z,O.OrbitControls=T,O.easings={"linear-in-out":t,"ease-in":e,"ease-out":i,"ease-in-out":s,"bounce-in":n,"bounce-out":o,"bounce-in-out":r},O.interpolators={linear:f,spherical:v};export{O as default};