diff --git a/index.html b/index.html
index 26114a3..7486a68 100644
--- a/index.html
+++ b/index.html
@@ -4,14 +4,8 @@
skinview3d examples
@@ -30,9 +24,9 @@
Animation Mouse Control:
-
-
-
+
+
+
Width:
@@ -64,91 +58,8 @@
+
diff --git a/js/example.js b/js/example.js
new file mode 100644
index 0000000..f39679e
--- /dev/null
+++ b/js/example.js
@@ -0,0 +1,87 @@
+// Use pure ES5 for max browser compatibility
+
+var skinViewer, control, handles = {}, globalAnimationSpeed = 1;
+
+function el(id) {
+ return document.getElementById(id);
+}
+
+function initSkinViewer() {
+ if (skinViewer instanceof skinview3d.SkinViewer) {
+ skinViewer.dispose();
+ handles = {};
+ control = undefined;
+ }
+
+ // Reset animation speed
+ el('speed').value = globalAnimationSpeed = 1;
+
+ skinViewer = new skinview3d.SkinViewer({
+ domElement: el("skin_container"),
+ slim: el('alex').checked,
+ width: el('width').value,
+ height: el('height').value,
+ skinUrl: el('skin_url').value,
+ capeUrl: el('cape_url').value
+ });
+
+ skinViewer.camera.position.z = 70;
+ skinViewer.animation = new skinview3d.CompositeAnimation();
+
+ control = skinview3d.createOrbitControls(skinViewer);
+}
+
+function hotReloadTextures() {
+ skinViewer.skinUrl = el('skin_url').value;
+ skinViewer.capeUrl = el('cape_url').value;
+}
+
+function resizeSkinViewer() {
+ skinViewer.width = el('width').value;
+ skinViewer.height = el('height').value;
+}
+
+function pause() {
+ skinViewer.animationPaused = !skinViewer.animationPaused;
+}
+
+function walk() {
+ if (handles.run) {
+ handles.run.remove();
+ delete handles.run;
+ }
+
+ handles.walk = handles.walk || skinViewer.animation.add(skinview3d.WalkingAnimation);
+ handles.walk.speed = globalAnimationSpeed;
+}
+
+function run() {
+ if (handles.walk) {
+ handles.walk.remove();
+ delete handles.walk;
+ }
+
+ handles.run = handles.run || skinViewer.animation.add(skinview3d.RunningAnimation);
+ handles.run.speed = globalAnimationSpeed;
+}
+
+function rotate() {
+ if (handles.rotate) {
+ handles.rotate.paused = !handles.rotate.paused;
+ } else {
+ handles.rotate = skinViewer.animation.add(skinview3d.RotatingAnimation);
+ handles.rotate.speed = globalAnimationSpeed;
+ }
+}
+
+function setGlobalAnimationSpeed() {
+ var currentSpeed = el('speed').value;
+
+ if (! isNaN(currentSpeed)) {
+ globalAnimationSpeed = currentSpeed;
+
+ for (var key in handles) {
+ handles[key].speed = currentSpeed;
+ }
+ }
+}
diff --git a/js/skinview3d.min.js b/js/skinview3d.min.js
index c757ab2..df6815a 100644
--- a/js/skinview3d.min.js
+++ b/js/skinview3d.min.js
@@ -25,7 +25,7 @@
* SOFTWARE.
*/
-!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("three")):"function"==typeof define&&define.amd?define(["exports","three"],t):t(e.skinview3d={},e.THREE)}(this,function(e,t){"use strict";var n=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},a=function(){function e(e,t){for(var n=0;nb||8*(1-d.dot(l.object.quaternion))>b)&&(l.dispatchEvent(m),h.copy(l.object.position),d.copy(l.object.quaternion),x=!1,!0)}),u.dispose=function(){l.domElement.removeEventListener("contextmenu",Q,!1),l.domElement.removeEventListener("mousedown",D,!1),l.domElement.removeEventListener("wheel",H,!1),l.domElement.removeEventListener("touchstart",Z,!1),l.domElement.removeEventListener("touchend",q,!1),l.domElement.removeEventListener("touchmove",W,!1),document.removeEventListener("mousemove",F,!1),document.removeEventListener("mouseup",Y,!1),window.removeEventListener("keydown",X,!1)};var l=u,m={type:"change"},p={type:"start"},f={type:"end"},g={NONE:-1,ROTATE:0,DOLLY:1,PAN:2,TOUCH_ROTATE:3,TOUCH_DOLLY:4,TOUCH_PAN:5},v=g.NONE,b=1e-6,w=new t.Spherical,y=new t.Spherical,M=1,k=new t.Vector3,x=!1,E=new t.Vector2,O=new t.Vector2,C=new t.Vector2,P=new t.Vector2,I=new t.Vector2,j=new t.Vector2,A=new t.Vector2,T=new t.Vector2,L=new t.Vector2;function _(){return Math.pow(.95,l.zoomSpeed)}function V(e){y.theta-=e}function N(e){y.phi-=e}var U,S=(U=new t.Vector3,function(e,t){U.setFromMatrixColumn(t,0),U.multiplyScalar(-e),k.add(U)}),z=function(){var e=new t.Vector3;return function(t,n){e.setFromMatrixColumn(n,1),e.multiplyScalar(t),k.add(e)}}(),R=function(){var e=new t.Vector3;return function(n,a){var o=l.domElement===document?l.domElement.body:l.domElement;if(l.object instanceof t.PerspectiveCamera){var i=l.object.position;e.copy(i).sub(l.target);var r=e.length();r*=Math.tan(l.object.fov/2*Math.PI/180),S(2*n*r/o.clientHeight,l.object.matrix),z(2*a*r/o.clientHeight,l.object.matrix)}else l.object instanceof t.OrthographicCamera?(S(n*(l.object.right-l.object.left)/l.object.zoom/o.clientWidth,l.object.matrix),z(a*(l.object.top-l.object.bottom)/l.object.zoom/o.clientHeight,l.object.matrix)):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."),l.enablePan=!1)}}();function G(e){l.object instanceof t.PerspectiveCamera?M/=e:l.object instanceof t.OrthographicCamera?(l.object.zoom=Math.max(l.minZoom,Math.min(l.maxZoom,l.object.zoom*e)),l.object.updateProjectionMatrix(),x=!0):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."),l.enableZoom=!1)}function B(e){l.object instanceof t.PerspectiveCamera?M*=e:l.object instanceof t.OrthographicCamera?(l.object.zoom=Math.max(l.minZoom,Math.min(l.maxZoom,l.object.zoom/e)),l.object.updateProjectionMatrix(),x=!0):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."),l.enableZoom=!1)}function D(e){if(!1!==l.enabled){switch(e.button){case l.mouseButtons.ORBIT:if(!1===l.enableRotate)return;!function(e){E.set(e.clientX,e.clientY)}(e),v=g.ROTATE;break;case l.mouseButtons.ZOOM:if(!1===l.enableZoom)return;!function(e){A.set(e.clientX,e.clientY)}(e),v=g.DOLLY;break;case l.mouseButtons.PAN:if(!1===l.enablePan)return;!function(e){P.set(e.clientX,e.clientY)}(e),v=g.PAN}e.preventDefault(),v!==g.NONE&&(document.addEventListener("mousemove",F,!1),document.addEventListener("mouseup",Y,!1),l.dispatchEvent(p))}}function F(e){if(!1!==l.enabled){switch(v){case g.ROTATE:if(!1===l.enableRotate)return;!function(e){O.set(e.clientX,e.clientY),C.subVectors(O,E);var t=l.domElement===document?l.domElement.body:l.domElement;V(2*Math.PI*C.x/t.clientWidth*l.rotateSpeed),N(2*Math.PI*C.y/t.clientHeight*l.rotateSpeed),E.copy(O),l.update()}(e);break;case g.DOLLY:if(!1===l.enableZoom)return;!function(e){T.set(e.clientX,e.clientY),L.subVectors(T,A),L.y>0?G(_()):L.y<0&&B(_()),A.copy(T),l.update()}(e);break;case g.PAN:if(!1===l.enablePan)return;!function(e){I.set(e.clientX,e.clientY),j.subVectors(I,P),R(j.x,j.y),P.copy(I),l.update()}(e)}e.preventDefault()}}function Y(e){!1!==l.enabled&&(document.removeEventListener("mousemove",F,!1),document.removeEventListener("mouseup",Y,!1),l.dispatchEvent(f),v=g.NONE)}function H(e){!1===l.enabled||!1===l.enableZoom||v!==g.NONE&&v!==g.ROTATE||(e.preventDefault(),e.stopPropagation(),function(e){e.deltaY<0?B(_()):e.deltaY>0&&G(_()),l.update()}(e),l.dispatchEvent(p),l.dispatchEvent(f))}function X(e){!1!==l.enabled&&!1!==l.enableKeys&&!1!==l.enablePan&&function(e){switch(e.keyCode){case l.keys.UP:R(0,l.keyPanSpeed),l.update();break;case l.keys.BOTTOM:R(0,-l.keyPanSpeed),l.update();break;case l.keys.LEFT:R(l.keyPanSpeed,0),l.update();break;case l.keys.RIGHT:R(-l.keyPanSpeed,0),l.update()}}(e)}function Z(e){if(!1!==l.enabled){switch(e.touches.length){case 1:if(!1===l.enableRotate)return;!function(e){E.set(e.touches[0].pageX,e.touches[0].pageY)}(e),v=g.TOUCH_ROTATE;break;case 2:if(!1===l.enableZoom)return;!function(e){var t=e.touches[0].pageX-e.touches[1].pageX,n=e.touches[0].pageY-e.touches[1].pageY,a=Math.sqrt(t*t+n*n);A.set(0,a)}(e),v=g.TOUCH_DOLLY;break;case 3:if(!1===l.enablePan)return;!function(e){P.set(e.touches[0].pageX,e.touches[0].pageY)}(e),v=g.TOUCH_PAN;break;default:v=g.NONE}v!==g.NONE&&l.dispatchEvent(p)}}function W(e){if(!1!==l.enabled){switch(e.touches.length){case 1:if(!1===l.enableRotate)return;if(v!==g.TOUCH_ROTATE)return;!function(e){O.set(e.touches[0].pageX,e.touches[0].pageY),C.subVectors(O,E);var t=l.domElement===document?l.domElement.body:l.domElement;V(2*Math.PI*C.x/t.clientWidth*l.rotateSpeed),N(2*Math.PI*C.y/t.clientHeight*l.rotateSpeed),E.copy(O),l.update()}(e);break;case 2:if(!1===l.enableZoom)return;if(v!==g.TOUCH_DOLLY)return;!function(e){var t=e.touches[0].pageX-e.touches[1].pageX,n=e.touches[0].pageY-e.touches[1].pageY,a=Math.sqrt(t*t+n*n);T.set(0,a),L.subVectors(T,A),L.y>0?B(_()):L.y<0&&G(_()),A.copy(T),l.update()}(e);break;case 3:if(!1===l.enablePan)return;if(v!==g.TOUCH_PAN)return;!function(e){I.set(e.touches[0].pageX,e.touches[0].pageY),j.subVectors(I,P),R(j.x,j.y),P.copy(I),l.update()}(e);break;default:v=g.NONE}e.preventDefault(),e.stopPropagation()}}function q(e){!1!==l.enabled&&(l.dispatchEvent(f),v=g.NONE)}function Q(e){!1!==l.enabled&&!1!==l.enablePan&&e.preventDefault()}return l.domElement.addEventListener("contextmenu",Q,!1),l.domElement.addEventListener("mousedown",D,!1),l.domElement.addEventListener("wheel",H,!1),l.domElement.addEventListener("touchstart",Z,!1),l.domElement.addEventListener("touchend",q,!1),l.domElement.addEventListener("touchmove",W,!1),window.addEventListener("keydown",X,!1),u.update(),u}return o(a,e),a}(t.EventDispatcher);function f(e,t,n){if(e instanceof v)e.play(t,n);else{if(!(e instanceof Function))throw"Not an animation: "+e;e(t,n)}}var g=function(){function e(t){n(this,e),this.animation=t,this.paused=this._paused=!1,this.speed=this._speed=1,this._lastChange=null,this._lastChangeX=null}return a(e,[{key:"play",value:function(e,t){if(null===this._lastChange)this._lastChange=t,this._lastChangeX=0;else if(this.paused!==this._paused||this.speed!==this._speed){var n=t-this._lastChange;!1===this._paused&&(this._lastChangeX+=n*this._speed),this._paused=this.paused,this._speed=this.speed,this._lastChange=t}if(!1===this.paused){var a=t-this._lastChange,o=this._lastChangeX+this.speed*a;f(this.animation,e,o)}}},{key:"reset",value:function(){this._lastChange=null}}]),e}(),v=function(){function e(){n(this,e),this.handles=new Set}return a(e,[{key:"add",value:function(e){var t=this,n=new g(e);return n.remove=function(){return t.handles.delete(n)},this.handles.add(n),n}},{key:"play",value:function(e,t){this.handles.forEach(function(n){return n.play(e,t)})}}]),e}();var b=function(){function e(a){var o=this;n(this,e),this.domElement=a.domElement,this.animation=a.animation||null,this.animationPaused=!1,this.animationTime=0,this.disposed=!1,this.skinImg=new Image,this.skinCanvas=document.createElement("canvas"),this.skinTexture=new t.Texture(this.skinCanvas),this.skinTexture.magFilter=t.NearestFilter,this.skinTexture.minFilter=t.NearestMipMapNearestFilter,this.capeImg=new Image,this.capeCanvas=document.createElement("canvas"),this.capeTexture=new t.Texture(this.capeCanvas),this.capeTexture.magFilter=t.NearestFilter,this.capeTexture.minFilter=t.NearestMipMapNearestFilter,this.layer1Material=new t.MeshBasicMaterial({map:this.skinTexture,side:t.FrontSide}),this.layer2Material=new t.MeshBasicMaterial({map:this.skinTexture,transparent:!0,opacity:1,side:t.DoubleSide}),this.capeMaterial=new t.MeshBasicMaterial({map:this.capeTexture}),this.scene=new t.Scene,this.camera=new t.PerspectiveCamera(40),this.camera.position.y=-12,this.camera.position.z=60,this.renderer=new t.WebGLRenderer({angleRot:!0,alpha:!0,antialias:!1}),this.renderer.setSize(300,300),this.renderer.context.getShaderInfoLog=function(){return""},this.domElement.appendChild(this.renderer.domElement),this.playerObject=new m(!0===a.slim,this.layer1Material,this.layer2Material,this.capeMaterial),this.scene.add(this.playerObject),this.skinImg.crossOrigin="",this.skinImg.onerror=function(){return console.error("Failed loading "+o.skinImg.src)},this.skinImg.onload=function(){var e=!1;if(o.skinImg.width!==o.skinImg.height){if(o.skinImg.width!==2*o.skinImg.height)return void console.error("Bad skin size");e=!0}var t=o.skinCanvas.getContext("2d");if(e){var n=o.skinImg.width;o.skinCanvas.width=n,o.skinCanvas.height=n,t.clearRect(0,0,n,n),t.drawImage(o.skinImg,0,0,n,n/2),function(e,t){var n=t/64,a=function(e,t,a,o,i,r,s,c){return function(e,t,n,a,o,i,r,s){var c=e.getImageData(t,n,a,o);if(s)for(var h=0;hb||8*(1-d.dot(m.object.quaternion))>b)&&(m.dispatchEvent(p),h.copy(m.object.position),d.copy(m.object.quaternion),k=!1,!0)}),u.dispose=function(){m.domElement.removeEventListener("contextmenu",Q,!1),m.domElement.removeEventListener("mousedown",D,!1),m.domElement.removeEventListener("wheel",H,!1),m.domElement.removeEventListener("touchstart",Z,!1),m.domElement.removeEventListener("touchend",q,!1),m.domElement.removeEventListener("touchmove",W,!1),document.removeEventListener("mousemove",F,!1),document.removeEventListener("mouseup",Y,!1),window.removeEventListener("keydown",X,!1)};var m=u,p={type:"change"},l={type:"start"},f={type:"end"},g={NONE:-1,ROTATE:0,DOLLY:1,PAN:2,TOUCH_ROTATE:3,TOUCH_DOLLY:4,TOUCH_PAN:5},v=g.NONE,b=1e-6,w=new t.Spherical,y=new t.Spherical,M=1,x=new t.Vector3,k=!1,E=new t.Vector2,O=new t.Vector2,I=new t.Vector2,P=new t.Vector2,j=new t.Vector2,C=new t.Vector2,A=new t.Vector2,T=new t.Vector2,L=new t.Vector2;function _(){return Math.pow(.95,m.zoomSpeed)}function V(e){y.theta-=e}function N(e){y.phi-=e}var U,S=(U=new t.Vector3,function(e,t){U.setFromMatrixColumn(t,0),U.multiplyScalar(-e),x.add(U)}),z=function(){var e=new t.Vector3;return function(t,n){e.setFromMatrixColumn(n,1),e.multiplyScalar(t),x.add(e)}}(),G=function(){var e=new t.Vector3;return function(n,a){var i=m.domElement===document?m.domElement.body:m.domElement;if(m.object instanceof t.PerspectiveCamera){var o=m.object.position;e.copy(o).sub(m.target);var r=e.length();r*=Math.tan(m.object.fov/2*Math.PI/180),S(2*n*r/i.clientHeight,m.object.matrix),z(2*a*r/i.clientHeight,m.object.matrix)}else m.object instanceof t.OrthographicCamera?(S(n*(m.object.right-m.object.left)/m.object.zoom/i.clientWidth,m.object.matrix),z(a*(m.object.top-m.object.bottom)/m.object.zoom/i.clientHeight,m.object.matrix)):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."),m.enablePan=!1)}}();function R(e){m.object instanceof t.PerspectiveCamera?M/=e:m.object instanceof t.OrthographicCamera?(m.object.zoom=Math.max(m.minZoom,Math.min(m.maxZoom,m.object.zoom*e)),m.object.updateProjectionMatrix(),k=!0):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."),m.enableZoom=!1)}function B(e){m.object instanceof t.PerspectiveCamera?M*=e:m.object instanceof t.OrthographicCamera?(m.object.zoom=Math.max(m.minZoom,Math.min(m.maxZoom,m.object.zoom/e)),m.object.updateProjectionMatrix(),k=!0):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."),m.enableZoom=!1)}function D(e){if(!1!==m.enabled){switch(e.button){case m.mouseButtons.ORBIT:if(!1===m.enableRotate)return;!function(e){E.set(e.clientX,e.clientY)}(e),v=g.ROTATE;break;case m.mouseButtons.ZOOM:if(!1===m.enableZoom)return;!function(e){A.set(e.clientX,e.clientY)}(e),v=g.DOLLY;break;case m.mouseButtons.PAN:if(!1===m.enablePan)return;!function(e){P.set(e.clientX,e.clientY)}(e),v=g.PAN}e.preventDefault(),v!==g.NONE&&(document.addEventListener("mousemove",F,!1),document.addEventListener("mouseup",Y,!1),m.dispatchEvent(l))}}function F(e){if(!1!==m.enabled){switch(v){case g.ROTATE:if(!1===m.enableRotate)return;!function(e){O.set(e.clientX,e.clientY),I.subVectors(O,E);var t=m.domElement===document?m.domElement.body:m.domElement;V(2*Math.PI*I.x/t.clientWidth*m.rotateSpeed),N(2*Math.PI*I.y/t.clientHeight*m.rotateSpeed),E.copy(O),m.update()}(e);break;case g.DOLLY:if(!1===m.enableZoom)return;!function(e){T.set(e.clientX,e.clientY),L.subVectors(T,A),L.y>0?R(_()):L.y<0&&B(_()),A.copy(T),m.update()}(e);break;case g.PAN:if(!1===m.enablePan)return;!function(e){j.set(e.clientX,e.clientY),C.subVectors(j,P),G(C.x,C.y),P.copy(j),m.update()}(e)}e.preventDefault()}}function Y(e){!1!==m.enabled&&(document.removeEventListener("mousemove",F,!1),document.removeEventListener("mouseup",Y,!1),m.dispatchEvent(f),v=g.NONE)}function H(e){!1===m.enabled||!1===m.enableZoom||v!==g.NONE&&v!==g.ROTATE||(e.preventDefault(),e.stopPropagation(),function(e){e.deltaY<0?B(_()):e.deltaY>0&&R(_()),m.update()}(e),m.dispatchEvent(l),m.dispatchEvent(f))}function X(e){!1!==m.enabled&&!1!==m.enableKeys&&!1!==m.enablePan&&function(e){switch(e.keyCode){case m.keys.UP:G(0,m.keyPanSpeed),m.update();break;case m.keys.BOTTOM:G(0,-m.keyPanSpeed),m.update();break;case m.keys.LEFT:G(m.keyPanSpeed,0),m.update();break;case m.keys.RIGHT:G(-m.keyPanSpeed,0),m.update()}}(e)}function Z(e){if(!1!==m.enabled){switch(e.touches.length){case 1:if(!1===m.enableRotate)return;!function(e){E.set(e.touches[0].pageX,e.touches[0].pageY)}(e),v=g.TOUCH_ROTATE;break;case 2:if(!1===m.enableZoom)return;!function(e){var t=e.touches[0].pageX-e.touches[1].pageX,n=e.touches[0].pageY-e.touches[1].pageY,a=Math.sqrt(t*t+n*n);A.set(0,a)}(e),v=g.TOUCH_DOLLY;break;case 3:if(!1===m.enablePan)return;!function(e){P.set(e.touches[0].pageX,e.touches[0].pageY)}(e),v=g.TOUCH_PAN;break;default:v=g.NONE}v!==g.NONE&&m.dispatchEvent(l)}}function W(e){if(!1!==m.enabled){switch(e.touches.length){case 1:if(!1===m.enableRotate)return;if(v!==g.TOUCH_ROTATE)return;!function(e){O.set(e.touches[0].pageX,e.touches[0].pageY),I.subVectors(O,E);var t=m.domElement===document?m.domElement.body:m.domElement;V(2*Math.PI*I.x/t.clientWidth*m.rotateSpeed),N(2*Math.PI*I.y/t.clientHeight*m.rotateSpeed),E.copy(O),m.update()}(e);break;case 2:if(!1===m.enableZoom)return;if(v!==g.TOUCH_DOLLY)return;!function(e){var t=e.touches[0].pageX-e.touches[1].pageX,n=e.touches[0].pageY-e.touches[1].pageY,a=Math.sqrt(t*t+n*n);T.set(0,a),L.subVectors(T,A),L.y>0?B(_()):L.y<0&&R(_()),A.copy(T),m.update()}(e);break;case 3:if(!1===m.enablePan)return;if(v!==g.TOUCH_PAN)return;!function(e){j.set(e.touches[0].pageX,e.touches[0].pageY),C.subVectors(j,P),G(C.x,C.y),P.copy(j),m.update()}(e);break;default:v=g.NONE}e.preventDefault(),e.stopPropagation()}}function q(e){!1!==m.enabled&&(m.dispatchEvent(f),v=g.NONE)}function Q(e){!1!==m.enabled&&!1!==m.enablePan&&e.preventDefault()}return m.domElement.addEventListener("contextmenu",Q,!1),m.domElement.addEventListener("mousedown",D,!1),m.domElement.addEventListener("wheel",H,!1),m.domElement.addEventListener("touchstart",Z,!1),m.domElement.addEventListener("touchend",q,!1),m.domElement.addEventListener("touchmove",W,!1),window.addEventListener("keydown",X,!1),u.update(),u}return i(a,e),a}(t.EventDispatcher);e.SkinObject=u,e.CapeObject=m,e.PlayerObject=p,e.SkinViewer=v,e.OrbitControls=b,e.createOrbitControls=function(e){var n=new b(e.camera,e.renderer.domElement);return n.enablePan=!1,n.target=new t.Vector3(0,-12,0),n.minDistance=10,n.maxDistance=256,n.update(),n},e.invokeAnimation=l,e.CompositeAnimation=g,e.WalkingAnimation=function(e,t){var n=e.skin;t*=8,n.leftLeg.rotation.x=.5*Math.sin(t),n.rightLeg.rotation.x=.5*Math.sin(t+Math.PI),n.leftArm.rotation.x=.5*Math.sin(t+Math.PI),n.rightArm.rotation.x=.5*Math.sin(t);var a=.02*Math.PI;n.leftArm.rotation.z=.03*Math.cos(t)+a,n.rightArm.rotation.z=.03*Math.cos(t+Math.PI)-a,n.head.rotation.y=.2*Math.sin(t/4),n.head.rotation.x=.1*Math.sin(t/5);var i=.06*Math.PI;e.cape.rotation.x=.06*Math.sin(t/1.5)+i},e.RunningAnimation=function(e,t){var n=e.skin;t*=15,n.leftLeg.rotation.x=1.3*Math.cos(t+Math.PI),n.rightLeg.rotation.x=1.3*Math.cos(t),n.leftArm.rotation.x=1.5*Math.cos(t),n.rightArm.rotation.x=1.5*Math.cos(t+Math.PI);var a=.1*Math.PI;n.leftArm.rotation.z=.1*Math.cos(t)+a,n.rightArm.rotation.z=.1*Math.cos(t+Math.PI)-a,e.position.y=Math.cos(2*t),e.position.x=.15*Math.cos(t),e.rotation.z=.01*Math.cos(t+Math.PI);var i=.3*Math.PI;e.cape.rotation.x=.1*Math.sin(2*t)+i},e.RotatingAnimation=function(e,t){e.rotation.y=t},Object.defineProperty(e,"__esModule",{value:!0})});
//# sourceMappingURL=skinview3d.min.js.map
diff --git a/js/skinview3d.min.js.map b/js/skinview3d.min.js.map
index f09692d..85e9b74 100644
--- a/js/skinview3d.min.js.map
+++ b/js/skinview3d.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"skinview3d.min.js","sources":["../src/model.js","../src/orbit_controls.js","../src/animation.js","../src/viewer.js"],"sourcesContent":["import * as THREE from \"three\";\n\nfunction toFaceVertices(x1, y1, x2, y2, w, h) {\n\treturn [\n\t\tnew THREE.Vector2(x1 / w, 1.0 - y2 / h),\n\t\tnew THREE.Vector2(x2 / w, 1.0 - y2 / h),\n\t\tnew THREE.Vector2(x2 / w, 1.0 - y1 / h),\n\t\tnew THREE.Vector2(x1 / w, 1.0 - y1 / h)\n\t];\n}\n\nfunction toSkinVertices(x1, y1, x2, y2) {\n\treturn toFaceVertices(x1, y1, x2, y2, 64.0, 64.0);\n}\n\nfunction toCapeVertices(x1, y1, x2, y2) {\n\treturn toFaceVertices(x1, y1, x2, y2, 64.0, 32.0);\n}\n\nfunction addVertices(box, top, bottom, left, front, right, back) {\n\tbox.faceVertexUvs[0] = [];\n\tbox.faceVertexUvs[0][0] = [right[3], right[0], right[2]];\n\tbox.faceVertexUvs[0][1] = [right[0], right[1], right[2]];\n\tbox.faceVertexUvs[0][2] = [left[3], left[0], left[2]];\n\tbox.faceVertexUvs[0][3] = [left[0], left[1], left[2]];\n\tbox.faceVertexUvs[0][4] = [top[3], top[0], top[2]];\n\tbox.faceVertexUvs[0][5] = [top[0], top[1], top[2]];\n\tbox.faceVertexUvs[0][6] = [bottom[0], bottom[3], bottom[1]];\n\tbox.faceVertexUvs[0][7] = [bottom[3], bottom[2], bottom[1]];\n\tbox.faceVertexUvs[0][8] = [front[3], front[0], front[2]];\n\tbox.faceVertexUvs[0][9] = [front[0], front[1], front[2]];\n\tbox.faceVertexUvs[0][10] = [back[3], back[0], back[2]];\n\tbox.faceVertexUvs[0][11] = [back[0], back[1], back[2]];\n}\n\nconst esp = 0.002;\n\nclass SkinObject extends THREE.Group {\n\tconstructor(slim, layer1Material, layer2Material) {\n\t\tsuper();\n\n\t\tthis.slim = slim;\n\n\t\t// Head\n\t\tthis.head = new THREE.Group();\n\n\t\tlet headBox = new THREE.BoxGeometry(8, 8, 8, 0, 0, 0);\n\t\taddVertices(headBox,\n\t\t\ttoSkinVertices(8, 0, 16, 8),\n\t\t\ttoSkinVertices(16, 0, 24, 8),\n\t\t\ttoSkinVertices(0, 8, 8, 16),\n\t\t\ttoSkinVertices(8, 8, 16, 16),\n\t\t\ttoSkinVertices(16, 8, 24, 16),\n\t\t\ttoSkinVertices(24, 8, 32, 16)\n\t\t);\n\t\tlet headMesh = new THREE.Mesh(headBox, layer1Material);\n\t\tthis.head.add(headMesh);\n\n\t\tlet head2Box = new THREE.BoxGeometry(9, 9, 9, 0, 0, 0);\n\t\taddVertices(head2Box,\n\t\t\ttoSkinVertices(40, 0, 48, 8),\n\t\t\ttoSkinVertices(48, 0, 56, 8),\n\t\t\ttoSkinVertices(32, 8, 40, 16),\n\t\t\ttoSkinVertices(40, 8, 48, 16),\n\t\t\ttoSkinVertices(48, 8, 56, 16),\n\t\t\ttoSkinVertices(56, 8, 64, 16)\n\t\t);\n\t\tlet head2Mesh = new THREE.Mesh(head2Box, layer2Material);\n\t\thead2Mesh.renderOrder = -1;\n\t\tthis.head.add(head2Mesh);\n\n\t\tthis.add(this.head);\n\n\n\t\t// Body\n\t\tthis.body = new THREE.Group();\n\n\t\tlet bodyBox = new THREE.BoxGeometry(8, 12, 4, 0, 0, 0);\n\t\taddVertices(bodyBox,\n\t\t\ttoSkinVertices(20, 16, 28, 20),\n\t\t\ttoSkinVertices(28, 16, 36, 20),\n\t\t\ttoSkinVertices(16, 20, 20, 32),\n\t\t\ttoSkinVertices(20, 20, 28, 32),\n\t\t\ttoSkinVertices(28, 20, 32, 32),\n\t\t\ttoSkinVertices(32, 20, 40, 32)\n\t\t);\n\t\tlet bodyMesh = new THREE.Mesh(bodyBox, layer1Material);\n\t\tthis.body.add(bodyMesh);\n\n\t\tlet body2Box = new THREE.BoxGeometry(9, 13.5, 4.5, 0, 0, 0);\n\t\taddVertices(body2Box,\n\t\t\ttoSkinVertices(20, 32, 28, 36),\n\t\t\ttoSkinVertices(28, 32, 36, 36),\n\t\t\ttoSkinVertices(16, 36, 20, 48),\n\t\t\ttoSkinVertices(20, 36, 28, 48),\n\t\t\ttoSkinVertices(28, 36, 32, 48),\n\t\t\ttoSkinVertices(32, 36, 40, 48)\n\t\t);\n\t\tlet body2Mesh = new THREE.Mesh(body2Box, layer2Material);\n\t\tthis.body.add(body2Mesh);\n\n\t\tthis.body.position.y = -10;\n\t\tthis.add(this.body);\n\n\n\t\t// Right Arm\n\t\tthis.rightArm = new THREE.Group();\n\t\tlet rightArmPivot = new THREE.Group();\n\n\t\tlet rightArmBox = new THREE.BoxGeometry((slim ? 3 : 4) - esp, 12 - esp, 4 - esp, 0, 0, 0);\n\t\tif (slim) {\n\t\t\taddVertices(rightArmBox,\n\t\t\t\ttoSkinVertices(44, 16, 47, 20),\n\t\t\t\ttoSkinVertices(47, 16, 50, 20),\n\t\t\t\ttoSkinVertices(40, 20, 44, 32),\n\t\t\t\ttoSkinVertices(44, 20, 47, 32),\n\t\t\t\ttoSkinVertices(47, 20, 51, 32),\n\t\t\t\ttoSkinVertices(51, 20, 54, 32)\n\t\t\t);\n\t\t} else {\n\t\t\taddVertices(rightArmBox,\n\t\t\t\ttoSkinVertices(44, 16, 48, 20),\n\t\t\t\ttoSkinVertices(48, 16, 52, 20),\n\t\t\t\ttoSkinVertices(40, 20, 44, 32),\n\t\t\t\ttoSkinVertices(44, 20, 48, 32),\n\t\t\t\ttoSkinVertices(48, 20, 52, 32),\n\t\t\t\ttoSkinVertices(52, 20, 56, 32)\n\t\t\t);\n\t\t}\n\t\tlet rightArmMesh = new THREE.Mesh(rightArmBox, layer1Material);\n\t\trightArmPivot.add(rightArmMesh);\n\n\t\tlet rightArm2Box = new THREE.BoxGeometry((slim ? 3.375 : 4.5) - esp, 13.5 - esp, 4.5 - esp, 0, 0, 0);\n\t\tif (slim) {\n\t\t\taddVertices(rightArm2Box,\n\t\t\t\ttoSkinVertices(44, 32, 47, 36),\n\t\t\t\ttoSkinVertices(47, 32, 50, 36),\n\t\t\t\ttoSkinVertices(40, 36, 44, 48),\n\t\t\t\ttoSkinVertices(44, 36, 47, 48),\n\t\t\t\ttoSkinVertices(47, 36, 51, 48),\n\t\t\t\ttoSkinVertices(51, 36, 54, 48)\n\t\t\t);\n\t\t} else {\n\t\t\taddVertices(rightArm2Box,\n\t\t\t\ttoSkinVertices(44, 32, 48, 36),\n\t\t\t\ttoSkinVertices(48, 32, 52, 36),\n\t\t\t\ttoSkinVertices(40, 36, 44, 48),\n\t\t\t\ttoSkinVertices(44, 36, 48, 48),\n\t\t\t\ttoSkinVertices(48, 36, 52, 48),\n\t\t\t\ttoSkinVertices(52, 36, 56, 48)\n\t\t\t);\n\t\t}\n\t\tlet rightArm2Mesh = new THREE.Mesh(rightArm2Box, layer2Material);\n\t\trightArm2Mesh.renderOrder = 1;\n\t\trightArmPivot.add(rightArm2Mesh);\n\n\t\trightArmPivot.position.y = -6;\n\t\tthis.rightArm.add(rightArmPivot);\n\t\tthis.rightArm.position.y = -4;\n\t\tthis.rightArm.position.x = slim ? -5.5 : -6;\n\t\tthis.add(this.rightArm);\n\n\n\t\t// Left Arm\n\t\tthis.leftArm = new THREE.Group();\n\t\tlet leftArmPivot = new THREE.Group();\n\n\t\tlet leftArmBox = new THREE.BoxGeometry((slim ? 3 : 4) - esp, 12 - esp, 4 - esp, 0, 0, 0);\n\t\tif (slim) {\n\t\t\taddVertices(leftArmBox,\n\t\t\t\ttoSkinVertices(36, 48, 39, 52),\n\t\t\t\ttoSkinVertices(39, 48, 42, 52),\n\t\t\t\ttoSkinVertices(32, 52, 36, 64),\n\t\t\t\ttoSkinVertices(36, 52, 39, 64),\n\t\t\t\ttoSkinVertices(39, 52, 43, 64),\n\t\t\t\ttoSkinVertices(43, 52, 46, 64)\n\t\t\t);\n\t\t} else {\n\t\t\taddVertices(leftArmBox,\n\t\t\t\ttoSkinVertices(36, 48, 40, 52),\n\t\t\t\ttoSkinVertices(40, 48, 44, 52),\n\t\t\t\ttoSkinVertices(32, 52, 36, 64),\n\t\t\t\ttoSkinVertices(36, 52, 40, 64),\n\t\t\t\ttoSkinVertices(40, 52, 44, 64),\n\t\t\t\ttoSkinVertices(44, 52, 48, 64)\n\t\t\t);\n\t\t}\n\t\tlet leftArmMesh = new THREE.Mesh(leftArmBox, layer1Material);\n\t\tleftArmPivot.add(leftArmMesh);\n\n\t\tlet leftArm2Box = new THREE.BoxGeometry((slim ? 3.375 : 4.5) - esp, 13.5 - esp, 4.5 - esp, 0, 0, 0);\n\t\tif (slim) {\n\t\t\taddVertices(leftArm2Box,\n\t\t\t\ttoSkinVertices(52, 48, 55, 52),\n\t\t\t\ttoSkinVertices(55, 48, 58, 52),\n\t\t\t\ttoSkinVertices(48, 52, 52, 64),\n\t\t\t\ttoSkinVertices(52, 52, 55, 64),\n\t\t\t\ttoSkinVertices(55, 52, 59, 64),\n\t\t\t\ttoSkinVertices(59, 52, 62, 64)\n\t\t\t);\n\t\t} else {\n\t\t\taddVertices(leftArm2Box,\n\t\t\t\ttoSkinVertices(52, 48, 56, 52),\n\t\t\t\ttoSkinVertices(56, 48, 60, 52),\n\t\t\t\ttoSkinVertices(48, 52, 52, 64),\n\t\t\t\ttoSkinVertices(52, 52, 56, 64),\n\t\t\t\ttoSkinVertices(56, 52, 60, 64),\n\t\t\t\ttoSkinVertices(60, 52, 64, 64)\n\t\t\t);\n\t\t}\n\t\tlet leftArm2Mesh = new THREE.Mesh(leftArm2Box, layer2Material);\n\t\tleftArm2Mesh.renderOrder = 1;\n\t\tleftArmPivot.add(leftArm2Mesh);\n\n\t\tleftArmPivot.position.y = -6;\n\t\tthis.leftArm.add(leftArmPivot);\n\t\tthis.leftArm.position.y = -4;\n\t\tthis.leftArm.position.x = slim ? 5.5 : 6;\n\t\tthis.add(this.leftArm);\n\n\n\t\t// Right Leg\n\t\tthis.rightLeg = new THREE.Group();\n\t\tlet rightLegPivot = new THREE.Group();\n\n\t\tlet rightLegBox = new THREE.BoxGeometry(4 - esp, 12 - esp, 4 - esp, 0, 0, 0);\n\t\taddVertices(rightLegBox,\n\t\t\ttoSkinVertices(4, 16, 8, 20),\n\t\t\ttoSkinVertices(8, 16, 12, 20),\n\t\t\ttoSkinVertices(0, 20, 4, 32),\n\t\t\ttoSkinVertices(4, 20, 8, 32),\n\t\t\ttoSkinVertices(8, 20, 12, 32),\n\t\t\ttoSkinVertices(12, 20, 16, 32)\n\t\t);\n\t\tlet rightLegMesh = new THREE.Mesh(rightLegBox, layer1Material);\n\t\trightLegPivot.add(rightLegMesh);\n\n\t\tlet rightLeg2Box = new THREE.BoxGeometry(4.5 - esp, 13.5 - esp, 4.5 - esp, 0, 0, 0);\n\t\taddVertices(rightLeg2Box,\n\t\t\ttoSkinVertices(4, 32, 8, 36),\n\t\t\ttoSkinVertices(8, 32, 12, 36),\n\t\t\ttoSkinVertices(0, 36, 4, 48),\n\t\t\ttoSkinVertices(4, 36, 8, 48),\n\t\t\ttoSkinVertices(8, 36, 12, 48),\n\t\t\ttoSkinVertices(12, 36, 16, 48)\n\t\t);\n\t\tlet rightLeg2Mesh = new THREE.Mesh(rightLeg2Box, layer2Material);\n\t\trightLeg2Mesh.renderOrder = 1;\n\t\trightLegPivot.add(rightLeg2Mesh);\n\n\t\trightLegPivot.position.y = -6;\n\t\tthis.rightLeg.add(rightLegPivot);\n\t\tthis.rightLeg.position.y = -16;\n\t\tthis.rightLeg.position.x = -2;\n\t\tthis.add(this.rightLeg);\n\n\t\t// Left Leg\n\t\tthis.leftLeg = new THREE.Group();\n\t\tlet leftLegPivot = new THREE.Group();\n\n\t\tlet leftLegBox = new THREE.BoxGeometry(4 - esp, 12 - esp, 4 - esp, 0, 0, 0);\n\t\taddVertices(leftLegBox,\n\t\t\ttoSkinVertices(20, 48, 24, 52),\n\t\t\ttoSkinVertices(24, 48, 28, 52),\n\t\t\ttoSkinVertices(16, 52, 20, 64),\n\t\t\ttoSkinVertices(20, 52, 24, 64),\n\t\t\ttoSkinVertices(24, 52, 28, 64),\n\t\t\ttoSkinVertices(28, 52, 32, 64)\n\t\t);\n\t\tlet leftLegMesh = new THREE.Mesh(leftLegBox, layer1Material);\n\t\tleftLegPivot.add(leftLegMesh);\n\n\t\tlet leftLeg2Box = new THREE.BoxGeometry(4.5 - esp, 13.5 - esp, 4.5 - esp, 0, 0, 0);\n\t\taddVertices(leftLeg2Box,\n\t\t\ttoSkinVertices(4, 48, 8, 52),\n\t\t\ttoSkinVertices(8, 48, 12, 52),\n\t\t\ttoSkinVertices(0, 52, 4, 64),\n\t\t\ttoSkinVertices(4, 52, 8, 64),\n\t\t\ttoSkinVertices(8, 52, 12, 64),\n\t\t\ttoSkinVertices(12, 52, 16, 64)\n\t\t);\n\t\tlet leftLeg2Mesh = new THREE.Mesh(leftLeg2Box, layer2Material);\n\t\tleftLeg2Mesh.renderOrder = 1;\n\t\tleftLegPivot.add(leftLeg2Mesh);\n\n\t\tleftLegPivot.position.y = -6;\n\t\tthis.leftLeg.add(leftLegPivot);\n\t\tthis.leftLeg.position.y = -16;\n\t\tthis.leftLeg.position.x = 2;\n\t\tthis.add(this.leftLeg);\n\t}\n}\n\nclass CapeObject extends THREE.Group {\n\tconstructor(capeMaterial) {\n\t\tsuper();\n\n\t\t// back = outside\n\t\t// front = inside\n\t\tlet capeBox = new THREE.BoxGeometry(10, 16, 1, 0, 0, 0);\n\t\taddVertices(capeBox,\n\t\t\ttoCapeVertices(1, 0, 11, 1),\n\t\t\ttoCapeVertices(11, 0, 21, 1),\n\t\t\ttoCapeVertices(11, 1, 12, 17),\n\t\t\ttoCapeVertices(12, 1, 22, 17),\n\t\t\ttoCapeVertices(0, 1, 1, 17),\n\t\t\ttoCapeVertices(1, 1, 11, 17)\n\t\t);\n\t\tthis.cape = new THREE.Mesh(capeBox, capeMaterial);\n\t\tthis.cape.position.y = -8;\n\t\tthis.cape.position.z = -0.5;\n\t\tthis.add(this.cape);\n\t}\n}\n\nclass PlayerObject extends THREE.Group {\n\tconstructor(slim, layer1Material, layer2Material, capeMaterial) {\n\t\tsuper();\n\n\t\tthis.skin = new SkinObject(slim, layer1Material, layer2Material);\n\t\tthis.skin.visible = false;\n\t\tthis.add(this.skin);\n\n\t\tthis.cape = new CapeObject(capeMaterial);\n\t\tthis.cape.position.z = -2;\n\t\tthis.cape.position.y = -4;\n\t\tthis.cape.rotation.x = 25 * Math.PI / 180;\n\t\tthis.cape.visible = false;\n\t\tthis.add(this.cape);\n\t}\n}\n\nexport { SkinObject, CapeObject, PlayerObject };\n","import * as THREE from \"three\";\n\nclass OrbitControls extends THREE.EventDispatcher {\n\t/**\n\t * @preserve\n\t * The code was originally from https://github.com/mrdoob/three.js/blob/d45a042cf962e9b1aa9441810ba118647b48aacb/examples/js/controls/OrbitControls.js\n\t */\n\t/**\n\t * @license\n\t * Copyright (C) 2010-2017 three.js authors\n\t *\n\t * Permission is hereby granted, free of charge, to any person obtaining a copy\n\t * of this software and associated documentation files (the \"Software\"), to deal\n\t * in the Software without restriction, including without limitation the rights\n\t * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\t * copies of the Software, and to permit persons to whom the Software is\n\t * furnished to do so, subject to the following conditions:\n\t *\n\t * The above copyright notice and this permission notice shall be included in\n\t * all copies or substantial portions of the Software.\n\t *\n\t * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\t * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\t * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\t * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\t * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\t * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\t * THE SOFTWARE.\n\t *\n\t *\n\t * @author qiao / https://github.com/qiao\n\t * @author mrdoob / http://mrdoob.com\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author erich666 / http://erichaines.com\n\t */\n\n\t// This set of controls performs orbiting, dollying (zooming), and panning.\n\t// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n\t//\n\t// Orbit - left mouse / touch: one finger move\n\t// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish\n\t// Pan - right mouse, or arrow keys / touch: three finger swipe\n\n\tconstructor(object, domElement) {\n\t\tsuper();\n\t\tthis.object = object;\n\t\tthis.domElement = (domElement !== undefined) ? domElement : document;\n\n\t\t// Set to false to disable this control\n\t\tthis.enabled = true;\n\n\t\t// \"target\" sets the location of focus, where the object orbits around\n\t\tthis.target = new THREE.Vector3();\n\n\t\t// How far you can dolly in and out (PerspectiveCamera only)\n\t\tthis.minDistance = 0;\n\t\tthis.maxDistance = Infinity;\n\n\t\t// How far you can zoom in and out (OrthographicCamera only)\n\t\tthis.minZoom = 0;\n\t\tthis.maxZoom = Infinity;\n\n\t\t// How far you can orbit vertically, upper and lower limits.\n\t\t// Range is 0 to Math.PI radians.\n\t\tthis.minPolarAngle = 0; // radians\n\t\tthis.maxPolarAngle = Math.PI; // radians\n\n\t\t// How far you can orbit horizontally, upper and lower limits.\n\t\t// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].\n\t\tthis.minAzimuthAngle = -Infinity; // radians\n\t\tthis.maxAzimuthAngle = Infinity; // radians\n\n\t\t// Set to true to enable damping (inertia)\n\t\t// If damping is enabled, you must call controls.update() in your animation loop\n\t\tthis.enableDamping = false;\n\t\tthis.dampingFactor = 0.25;\n\n\t\t// This option actually enables dollying in and out; left as \"zoom\" for backwards compatibility.\n\t\t// Set to false to disable zooming\n\t\tthis.enableZoom = true;\n\t\tthis.zoomSpeed = 1.0;\n\n\t\t// Set to false to disable rotating\n\t\tthis.enableRotate = true;\n\t\tthis.rotateSpeed = 1.0;\n\n\t\t// Set to false to disable panning\n\t\tthis.enablePan = true;\n\t\tthis.keyPanSpeed = 7.0; // pixels moved per arrow key push\n\n\t\t// Set to true to automatically rotate around the target\n\t\t// If auto-rotate is enabled, you must call controls.update() in your animation loop\n\t\tthis.autoRotate = false;\n\t\tthis.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60\n\n\t\t// Set to false to disable use of the keys\n\t\tthis.enableKeys = true;\n\n\t\t// The four arrow keys\n\t\tthis.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };\n\n\t\t// Mouse buttons\n\t\tthis.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };\n\n\t\t// for reset\n\t\tthis.target0 = this.target.clone();\n\t\tthis.position0 = this.object.position.clone();\n\t\tthis.zoom0 = this.object.zoom;\n\n\t\t//\n\t\t// public methods\n\t\t//\n\t\tthis.getPolarAngle = function () {\n\t\t\treturn spherical.phi;\n\t\t};\n\t\tthis.getAzimuthalAngle = function () {\n\t\t\treturn spherical.theta;\n\t\t};\n\t\tthis.saveState = function () {\n\t\t\tscope.target0.copy(scope.target);\n\t\t\tscope.position0.copy(scope.object.position);\n\t\t\tscope.zoom0 = scope.object.zoom;\n\t\t};\n\t\tthis.reset = function () {\n\t\t\tscope.target.copy(scope.target0);\n\t\t\tscope.object.position.copy(scope.position0);\n\t\t\tscope.object.zoom = scope.zoom0;\n\t\t\tscope.object.updateProjectionMatrix();\n\t\t\tscope.dispatchEvent(changeEvent);\n\t\t\tscope.update();\n\t\t\tstate = STATE.NONE;\n\t\t};\n\n\t\t// this method is exposed, but perhaps it would be better if we can make it private...\n\t\tthis.update = function () {\n\t\t\tlet offset = new THREE.Vector3();\n\t\t\t// so camera.up is the orbit axis\n\t\t\tlet quat = new THREE.Quaternion().setFromUnitVectors(object.up, new THREE.Vector3(0, 1, 0));\n\t\t\tlet quatInverse = quat.clone().inverse();\n\t\t\tlet lastPosition = new THREE.Vector3();\n\t\t\tlet lastQuaternion = new THREE.Quaternion();\n\t\t\treturn function update() {\n\t\t\t\tlet position = scope.object.position;\n\t\t\t\toffset.copy(position).sub(scope.target);\n\t\t\t\t// rotate offset to \"y-axis-is-up\" space\n\t\t\t\toffset.applyQuaternion(quat);\n\t\t\t\t// angle from z-axis around y-axis\n\t\t\t\tspherical.setFromVector3(offset);\n\t\t\t\tif (scope.autoRotate && state === STATE.NONE) {\n\t\t\t\t\trotateLeft(getAutoRotationAngle());\n\t\t\t\t}\n\t\t\t\tspherical.theta += sphericalDelta.theta;\n\t\t\t\tspherical.phi += sphericalDelta.phi;\n\t\t\t\t// restrict theta to be between desired limits\n\t\t\t\tspherical.theta = Math.max(scope.minAzimuthAngle, Math.min(scope.maxAzimuthAngle, spherical.theta));\n\t\t\t\t// restrict phi to be between desired limits\n\t\t\t\tspherical.phi = Math.max(scope.minPolarAngle, Math.min(scope.maxPolarAngle, spherical.phi));\n\t\t\t\tspherical.makeSafe();\n\t\t\t\tspherical.radius *= scale;\n\t\t\t\t// restrict radius to be between desired limits\n\t\t\t\tspherical.radius = Math.max(scope.minDistance, Math.min(scope.maxDistance, spherical.radius));\n\t\t\t\t// move target to panned location\n\t\t\t\tscope.target.add(panOffset);\n\t\t\t\toffset.setFromSpherical(spherical);\n\t\t\t\t// rotate offset back to \"camera-up-vector-is-up\" space\n\t\t\t\toffset.applyQuaternion(quatInverse);\n\t\t\t\tposition.copy(scope.target).add(offset);\n\t\t\t\tscope.object.lookAt(scope.target);\n\t\t\t\tif (scope.enableDamping === true) {\n\t\t\t\t\tsphericalDelta.theta *= (1 - scope.dampingFactor);\n\t\t\t\t\tsphericalDelta.phi *= (1 - scope.dampingFactor);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tsphericalDelta.set(0, 0, 0);\n\t\t\t\t}\n\t\t\t\tscale = 1;\n\t\t\t\tpanOffset.set(0, 0, 0);\n\t\t\t\t// update condition is:\n\t\t\t\t// min(camera displacement, camera rotation in radians)^2 > EPS\n\t\t\t\t// using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\t\t\t\tif (zoomChanged ||\n\t\t\t\t\tlastPosition.distanceToSquared(scope.object.position) > EPS ||\n\t\t\t\t\t8 * (1 - lastQuaternion.dot(scope.object.quaternion)) > EPS) {\n\t\t\t\t\tscope.dispatchEvent(changeEvent);\n\t\t\t\t\tlastPosition.copy(scope.object.position);\n\t\t\t\t\tlastQuaternion.copy(scope.object.quaternion);\n\t\t\t\t\tzoomChanged = false;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}();\n\t\tthis.dispose = function () {\n\t\t\tscope.domElement.removeEventListener(\"contextmenu\", onContextMenu, false);\n\t\t\tscope.domElement.removeEventListener(\"mousedown\", onMouseDown, false);\n\t\t\tscope.domElement.removeEventListener(\"wheel\", onMouseWheel, false);\n\t\t\tscope.domElement.removeEventListener(\"touchstart\", onTouchStart, false);\n\t\t\tscope.domElement.removeEventListener(\"touchend\", onTouchEnd, false);\n\t\t\tscope.domElement.removeEventListener(\"touchmove\", onTouchMove, false);\n\t\t\tdocument.removeEventListener(\"mousemove\", onMouseMove, false);\n\t\t\tdocument.removeEventListener(\"mouseup\", onMouseUp, false);\n\t\t\twindow.removeEventListener(\"keydown\", onKeyDown, false);\n\t\t\t//scope.dispatchEvent({ type: \"dispose\" }); // should this be added here?\n\t\t};\n\t\t//\n\t\t// internals\n\t\t//\n\t\tlet scope = this;\n\t\tlet changeEvent = { type: \"change\" };\n\t\tlet startEvent = { type: \"start\" };\n\t\tlet endEvent = { type: \"end\" };\n\t\tlet STATE = { NONE: -1, ROTATE: 0, DOLLY: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_DOLLY: 4, TOUCH_PAN: 5 };\n\t\tlet state = STATE.NONE;\n\t\tlet EPS = 0.000001;\n\t\t// current position in spherical coordinates\n\t\tlet spherical = new THREE.Spherical();\n\t\tlet sphericalDelta = new THREE.Spherical();\n\t\tlet scale = 1;\n\t\tlet panOffset = new THREE.Vector3();\n\t\tlet zoomChanged = false;\n\t\tlet rotateStart = new THREE.Vector2();\n\t\tlet rotateEnd = new THREE.Vector2();\n\t\tlet rotateDelta = new THREE.Vector2();\n\t\tlet panStart = new THREE.Vector2();\n\t\tlet panEnd = new THREE.Vector2();\n\t\tlet panDelta = new THREE.Vector2();\n\t\tlet dollyStart = new THREE.Vector2();\n\t\tlet dollyEnd = new THREE.Vector2();\n\t\tlet dollyDelta = new THREE.Vector2();\n\t\tfunction getAutoRotationAngle() {\n\t\t\treturn 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n\t\t}\n\t\tfunction getZoomScale() {\n\t\t\treturn Math.pow(0.95, scope.zoomSpeed);\n\t\t}\n\t\tfunction rotateLeft(angle) {\n\t\t\tsphericalDelta.theta -= angle;\n\t\t}\n\t\tfunction rotateUp(angle) {\n\t\t\tsphericalDelta.phi -= angle;\n\t\t}\n\t\tlet panLeft = function () {\n\t\t\tlet v = new THREE.Vector3();\n\t\t\treturn function panLeft(distance, objectMatrix) {\n\t\t\t\tv.setFromMatrixColumn(objectMatrix, 0); // get X column of objectMatrix\n\t\t\t\tv.multiplyScalar(-distance);\n\t\t\t\tpanOffset.add(v);\n\t\t\t};\n\t\t}();\n\t\tlet panUp = function () {\n\t\t\tlet v = new THREE.Vector3();\n\t\t\treturn function panUp(distance, objectMatrix) {\n\t\t\t\tv.setFromMatrixColumn(objectMatrix, 1); // get Y column of objectMatrix\n\t\t\t\tv.multiplyScalar(distance);\n\t\t\t\tpanOffset.add(v);\n\t\t\t};\n\t\t}();\n\t\t// deltaX and deltaY are in pixels; right and down are positive\n\t\tlet pan = function () {\n\t\t\tlet offset = new THREE.Vector3();\n\t\t\treturn function pan(deltaX, deltaY) {\n\t\t\t\tlet element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\t\t\t\tif (scope.object instanceof THREE.PerspectiveCamera) {\n\t\t\t\t\t// perspective\n\t\t\t\t\tlet position = scope.object.position;\n\t\t\t\t\toffset.copy(position).sub(scope.target);\n\t\t\t\t\tlet targetDistance = offset.length();\n\t\t\t\t\t// half of the fov is center to top of screen\n\t\t\t\t\ttargetDistance *= Math.tan((scope.object.fov / 2) * Math.PI / 180.0);\n\t\t\t\t\t// we actually don't use screenWidth, since perspective camera is fixed to screen height\n\t\t\t\t\tpanLeft(2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix);\n\t\t\t\t\tpanUp(2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix);\n\t\t\t\t}\n\t\t\t\telse if (scope.object instanceof THREE.OrthographicCamera) {\n\t\t\t\t\t// orthographic\n\t\t\t\t\tpanLeft(deltaX * (scope.object.right - scope.object.left) / scope.object.zoom / element.clientWidth, scope.object.matrix);\n\t\t\t\t\tpanUp(deltaY * (scope.object.top - scope.object.bottom) / scope.object.zoom / element.clientHeight, scope.object.matrix);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t// camera neither orthographic nor perspective\n\t\t\t\t\tconsole.warn(\"WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.\");\n\t\t\t\t\tscope.enablePan = false;\n\t\t\t\t}\n\t\t\t};\n\t\t}();\n\t\tfunction dollyIn(dollyScale) {\n\t\t\tif (scope.object instanceof THREE.PerspectiveCamera) {\n\t\t\t\tscale /= dollyScale;\n\t\t\t}\n\t\t\telse if (scope.object instanceof THREE.OrthographicCamera) {\n\t\t\t\tscope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom * dollyScale));\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tconsole.warn(\"WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.\");\n\t\t\t\tscope.enableZoom = false;\n\t\t\t}\n\t\t}\n\t\tfunction dollyOut(dollyScale) {\n\t\t\tif (scope.object instanceof THREE.PerspectiveCamera) {\n\t\t\t\tscale *= dollyScale;\n\t\t\t}\n\t\t\telse if (scope.object instanceof THREE.OrthographicCamera) {\n\t\t\t\tscope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom / dollyScale));\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tconsole.warn(\"WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.\");\n\t\t\t\tscope.enableZoom = false;\n\t\t\t}\n\t\t}\n\t\t//\n\t\t// event callbacks - update the object state\n\t\t//\n\t\tfunction handleMouseDownRotate(event) {\n\t\t\trotateStart.set(event.clientX, event.clientY);\n\t\t}\n\t\tfunction handleMouseDownDolly(event) {\n\t\t\tdollyStart.set(event.clientX, event.clientY);\n\t\t}\n\t\tfunction handleMouseDownPan(event) {\n\t\t\tpanStart.set(event.clientX, event.clientY);\n\t\t}\n\t\tfunction handleMouseMoveRotate(event) {\n\t\t\trotateEnd.set(event.clientX, event.clientY);\n\t\t\trotateDelta.subVectors(rotateEnd, rotateStart);\n\t\t\tlet element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft(2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed);\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed);\n\t\t\trotateStart.copy(rotateEnd);\n\t\t\tscope.update();\n\t\t}\n\t\tfunction handleMouseMoveDolly(event) {\n\t\t\tdollyEnd.set(event.clientX, event.clientY);\n\t\t\tdollyDelta.subVectors(dollyEnd, dollyStart);\n\t\t\tif (dollyDelta.y > 0) {\n\t\t\t\tdollyIn(getZoomScale());\n\t\t\t}\n\t\t\telse if (dollyDelta.y < 0) {\n\t\t\t\tdollyOut(getZoomScale());\n\t\t\t}\n\t\t\tdollyStart.copy(dollyEnd);\n\t\t\tscope.update();\n\t\t}\n\t\tfunction handleMouseMovePan(event) {\n\t\t\tpanEnd.set(event.clientX, event.clientY);\n\t\t\tpanDelta.subVectors(panEnd, panStart);\n\t\t\tpan(panDelta.x, panDelta.y);\n\t\t\tpanStart.copy(panEnd);\n\t\t\tscope.update();\n\t\t}\n\t\tfunction handleMouseUp(event) {\n\t\t}\n\t\tfunction handleMouseWheel(event) {\n\t\t\tif (event.deltaY < 0) {\n\t\t\t\tdollyOut(getZoomScale());\n\t\t\t}\n\t\t\telse if (event.deltaY > 0) {\n\t\t\t\tdollyIn(getZoomScale());\n\t\t\t}\n\t\t\tscope.update();\n\t\t}\n\t\tfunction handleKeyDown(event) {\n\t\t\tswitch (event.keyCode) {\n\t\t\t\tcase scope.keys.UP:\n\t\t\t\t\tpan(0, scope.keyPanSpeed);\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\t\t\t\tcase scope.keys.BOTTOM:\n\t\t\t\t\tpan(0, -scope.keyPanSpeed);\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\t\t\t\tcase scope.keys.LEFT:\n\t\t\t\t\tpan(scope.keyPanSpeed, 0);\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\t\t\t\tcase scope.keys.RIGHT:\n\t\t\t\t\tpan(-scope.keyPanSpeed, 0);\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tfunction handleTouchStartRotate(event) {\n\t\t\trotateStart.set(event.touches[0].pageX, event.touches[0].pageY);\n\t\t}\n\t\tfunction handleTouchStartDolly(event) {\n\t\t\tlet dx = event.touches[0].pageX - event.touches[1].pageX;\n\t\t\tlet dy = event.touches[0].pageY - event.touches[1].pageY;\n\t\t\tlet distance = Math.sqrt(dx * dx + dy * dy);\n\t\t\tdollyStart.set(0, distance);\n\t\t}\n\t\tfunction handleTouchStartPan(event) {\n\t\t\tpanStart.set(event.touches[0].pageX, event.touches[0].pageY);\n\t\t}\n\t\tfunction handleTouchMoveRotate(event) {\n\t\t\trotateEnd.set(event.touches[0].pageX, event.touches[0].pageY);\n\t\t\trotateDelta.subVectors(rotateEnd, rotateStart);\n\t\t\tlet element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\t\t\trotateLeft(2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed);\n\t\t\trotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed);\n\t\t\trotateStart.copy(rotateEnd);\n\t\t\tscope.update();\n\t\t}\n\t\tfunction handleTouchMoveDolly(event) {\n\t\t\tlet dx = event.touches[0].pageX - event.touches[1].pageX;\n\t\t\tlet dy = event.touches[0].pageY - event.touches[1].pageY;\n\t\t\tlet distance = Math.sqrt(dx * dx + dy * dy);\n\t\t\tdollyEnd.set(0, distance);\n\t\t\tdollyDelta.subVectors(dollyEnd, dollyStart);\n\t\t\tif (dollyDelta.y > 0) {\n\t\t\t\tdollyOut(getZoomScale());\n\t\t\t}\n\t\t\telse if (dollyDelta.y < 0) {\n\t\t\t\tdollyIn(getZoomScale());\n\t\t\t}\n\t\t\tdollyStart.copy(dollyEnd);\n\t\t\tscope.update();\n\t\t}\n\t\tfunction handleTouchMovePan(event) {\n\t\t\tpanEnd.set(event.touches[0].pageX, event.touches[0].pageY);\n\t\t\tpanDelta.subVectors(panEnd, panStart);\n\t\t\tpan(panDelta.x, panDelta.y);\n\t\t\tpanStart.copy(panEnd);\n\t\t\tscope.update();\n\t\t}\n\t\tfunction handleTouchEnd(event) {\n\t\t}\n\t\t//\n\t\t// event handlers - FSM: listen for events and reset state\n\t\t//\n\t\tfunction onMouseDown(event) {\n\t\t\tif (scope.enabled === false)\n\t\t\t\treturn;\n\t\t\tswitch (event.button) {\n\t\t\t\tcase scope.mouseButtons.ORBIT:\n\t\t\t\t\tif (scope.enableRotate === false)\n\t\t\t\t\t\treturn;\n\t\t\t\t\thandleMouseDownRotate(event);\n\t\t\t\t\tstate = STATE.ROTATE;\n\t\t\t\t\tbreak;\n\t\t\t\tcase scope.mouseButtons.ZOOM:\n\t\t\t\t\tif (scope.enableZoom === false)\n\t\t\t\t\t\treturn;\n\t\t\t\t\thandleMouseDownDolly(event);\n\t\t\t\t\tstate = STATE.DOLLY;\n\t\t\t\t\tbreak;\n\t\t\t\tcase scope.mouseButtons.PAN:\n\t\t\t\t\tif (scope.enablePan === false)\n\t\t\t\t\t\treturn;\n\t\t\t\t\thandleMouseDownPan(event);\n\t\t\t\t\tstate = STATE.PAN;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tevent.preventDefault();\n\t\t\tif (state !== STATE.NONE) {\n\t\t\t\tdocument.addEventListener(\"mousemove\", onMouseMove, false);\n\t\t\t\tdocument.addEventListener(\"mouseup\", onMouseUp, false);\n\t\t\t\tscope.dispatchEvent(startEvent);\n\t\t\t}\n\t\t}\n\t\tfunction onMouseMove(event) {\n\t\t\tif (scope.enabled === false)\n\t\t\t\treturn;\n\t\t\tswitch (state) {\n\t\t\t\tcase STATE.ROTATE:\n\t\t\t\t\tif (scope.enableRotate === false)\n\t\t\t\t\t\treturn;\n\t\t\t\t\thandleMouseMoveRotate(event);\n\t\t\t\t\tbreak;\n\t\t\t\tcase STATE.DOLLY:\n\t\t\t\t\tif (scope.enableZoom === false)\n\t\t\t\t\t\treturn;\n\t\t\t\t\thandleMouseMoveDolly(event);\n\t\t\t\t\tbreak;\n\t\t\t\tcase STATE.PAN:\n\t\t\t\t\tif (scope.enablePan === false)\n\t\t\t\t\t\treturn;\n\t\t\t\t\thandleMouseMovePan(event);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tevent.preventDefault();\n\t\t}\n\t\tfunction onMouseUp(event) {\n\t\t\tif (scope.enabled === false)\n\t\t\t\treturn;\n\t\t\thandleMouseUp(event);\n\t\t\tdocument.removeEventListener(\"mousemove\", onMouseMove, false);\n\t\t\tdocument.removeEventListener(\"mouseup\", onMouseUp, false);\n\t\t\tscope.dispatchEvent(endEvent);\n\t\t\tstate = STATE.NONE;\n\t\t}\n\t\tfunction onMouseWheel(event) {\n\t\t\tif (scope.enabled === false || scope.enableZoom === false || (state !== STATE.NONE && state !== STATE.ROTATE))\n\t\t\t\treturn;\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t\thandleMouseWheel(event);\n\t\t\tscope.dispatchEvent(startEvent); // not sure why these are here...\n\t\t\tscope.dispatchEvent(endEvent);\n\t\t}\n\t\tfunction onKeyDown(event) {\n\t\t\tif (scope.enabled === false || scope.enableKeys === false || scope.enablePan === false)\n\t\t\t\treturn;\n\t\t\thandleKeyDown(event);\n\t\t}\n\t\tfunction onTouchStart(event) {\n\t\t\tif (scope.enabled === false)\n\t\t\t\treturn;\n\t\t\tswitch (event.touches.length) {\n\t\t\t\tcase 1:// one-fingered touch: rotate\n\t\t\t\t\tif (scope.enableRotate === false)\n\t\t\t\t\t\treturn;\n\t\t\t\t\thandleTouchStartRotate(event);\n\t\t\t\t\tstate = STATE.TOUCH_ROTATE;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:// two-fingered touch: dolly\n\t\t\t\t\tif (scope.enableZoom === false)\n\t\t\t\t\t\treturn;\n\t\t\t\t\thandleTouchStartDolly(event);\n\t\t\t\t\tstate = STATE.TOUCH_DOLLY;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 3:// three-fingered touch: pan\n\t\t\t\t\tif (scope.enablePan === false)\n\t\t\t\t\t\treturn;\n\t\t\t\t\thandleTouchStartPan(event);\n\t\t\t\t\tstate = STATE.TOUCH_PAN;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tstate = STATE.NONE;\n\t\t\t}\n\t\t\tif (state !== STATE.NONE) {\n\t\t\t\tscope.dispatchEvent(startEvent);\n\t\t\t}\n\t\t}\n\t\tfunction onTouchMove(event) {\n\t\t\tif (scope.enabled === false)\n\t\t\t\treturn;\n\t\t\tswitch (event.touches.length) {\n\t\t\t\tcase 1:// one-fingered touch: rotate\n\t\t\t\t\tif (scope.enableRotate === false)\n\t\t\t\t\t\treturn;\n\t\t\t\t\tif (state !== STATE.TOUCH_ROTATE)\n\t\t\t\t\t\treturn; // is this needed?...\n\t\t\t\t\thandleTouchMoveRotate(event);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:// two-fingered touch: dolly\n\t\t\t\t\tif (scope.enableZoom === false)\n\t\t\t\t\t\treturn;\n\t\t\t\t\tif (state !== STATE.TOUCH_DOLLY)\n\t\t\t\t\t\treturn; // is this needed?...\n\t\t\t\t\thandleTouchMoveDolly(event);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 3:// three-fingered touch: pan\n\t\t\t\t\tif (scope.enablePan === false)\n\t\t\t\t\t\treturn;\n\t\t\t\t\tif (state !== STATE.TOUCH_PAN)\n\t\t\t\t\t\treturn; // is this needed?...\n\t\t\t\t\thandleTouchMovePan(event);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tstate = STATE.NONE;\n\t\t\t}\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t}\n\t\tfunction onTouchEnd(event) {\n\t\t\tif (scope.enabled === false)\n\t\t\t\treturn;\n\t\t\thandleTouchEnd(event);\n\t\t\tscope.dispatchEvent(endEvent);\n\t\t\tstate = STATE.NONE;\n\t\t}\n\t\tfunction onContextMenu(event) {\n\t\t\tif (scope.enabled === false || scope.enablePan === false)\n\t\t\t\treturn;\n\t\t\tevent.preventDefault();\n\t\t}\n\t\t//\n\t\tscope.domElement.addEventListener(\"contextmenu\", onContextMenu, false);\n\t\tscope.domElement.addEventListener(\"mousedown\", onMouseDown, false);\n\t\tscope.domElement.addEventListener(\"wheel\", onMouseWheel, false);\n\t\tscope.domElement.addEventListener(\"touchstart\", onTouchStart, false);\n\t\tscope.domElement.addEventListener(\"touchend\", onTouchEnd, false);\n\t\tscope.domElement.addEventListener(\"touchmove\", onTouchMove, false);\n\t\twindow.addEventListener(\"keydown\", onKeyDown, false);\n\t\t// force an update at start\n\t\tthis.update();\n\t}\n}\n\nexport { OrbitControls };\n","function invokeAnimation(animation, player, time) {\n\tif (animation instanceof CompositeAnimation) {\n\t\tanimation.play(player, time);\n\t} else if (animation instanceof Function) {\n\t\tanimation(player, time);\n\t} else {\n\t\tthrow `Not an animation: ${animation}`;\n\t}\n}\n\nclass AnimationHandle {\n\tconstructor(animation) {\n\t\tthis.animation = animation;\n\t\tthis.paused = this._paused = false;\n\t\tthis.speed = this._speed = 1.0;\n\t\tthis._lastChange = null;\n\t\tthis._lastChangeX = null;\n\t}\n\tplay(player, time) {\n\t\tif (this._lastChange === null) {\n\t\t\tthis._lastChange = time;\n\t\t\tthis._lastChangeX = 0;\n\t\t} else if (this.paused !== this._paused || this.speed !== this._speed) {\n\t\t\tlet dt = time - this._lastChange;\n\t\t\tif (this._paused === false) {\n\t\t\t\tthis._lastChangeX += dt * this._speed;\n\t\t\t}\n\t\t\tthis._paused = this.paused;\n\t\t\tthis._speed = this.speed;\n\t\t\tthis._lastChange = time;\n\t\t}\n\t\tif (this.paused === false) {\n\t\t\tlet dt = time - this._lastChange;\n\t\t\tlet x = this._lastChangeX + this.speed * dt;\n\t\t\tinvokeAnimation(this.animation, player, x);\n\t\t}\n\t}\n\treset(){\n\t\tthis._lastChange = null;\n\t}\n}\n\nclass CompositeAnimation {\n\tconstructor() {\n\t\tthis.handles = new Set();\n\t}\n\tadd(animation) {\n\t\tlet handle = new AnimationHandle(animation);\n\t\thandle.remove = () => this.handles.delete(handle);\n\t\tthis.handles.add(handle);\n\t\treturn handle;\n\t}\n\tplay(player, time) {\n\t\tthis.handles.forEach(handle => handle.play(player, time));\n\t}\n}\n\nlet WalkingAnimation = (player, time) => {\n\tlet skin = player.skin;\n\n\t// Multiply by animation's natural speed\n\ttime *= 8;\n\n\t// Leg swing\n\tskin.leftLeg.rotation.x = Math.sin(time) * 0.5;\n\tskin.rightLeg.rotation.x = Math.sin(time + Math.PI) * 0.5;\n\n\t// Arm swing\n\tskin.leftArm.rotation.x = Math.sin(time + Math.PI) * 0.5;\n\tskin.rightArm.rotation.x = Math.sin(time) * 0.5;\n\tlet basicArmRotationZ = Math.PI * 0.02;\n\tskin.leftArm.rotation.z = Math.cos(time) * 0.03 + basicArmRotationZ;\n\tskin.rightArm.rotation.z = Math.cos(time + Math.PI) * 0.03 - basicArmRotationZ;\n\n\t// Head shaking with different frequency & amplitude\n\tskin.head.rotation.y = Math.sin(time / 4) * 0.2;\n\tskin.head.rotation.x = Math.sin(time / 5) * 0.1;\n\n\t// Always add an angle for cape around the x axis\n\tlet basicCapeRotationX = Math.PI * 0.06;\n\tplayer.cape.rotation.x = Math.sin(time / 1.5) * 0.06 + basicCapeRotationX;\n};\n\nlet RunningAnimation = (player, time) => {\n\tlet skin = player.skin;\n\n\ttime *= 15;\n\n\t// Leg swing with larger amplitude\n\tskin.leftLeg.rotation.x = Math.cos(time + Math.PI) * 1.3;\n\tskin.rightLeg.rotation.x = Math.cos(time) * 1.3;\n\n\t// Arm swing\n\tskin.leftArm.rotation.x = Math.cos(time) * 1.5;\n\tskin.rightArm.rotation.x = Math.cos(time + Math.PI) * 1.5;\n\tlet basicArmRotationZ = Math.PI * 0.1;\n\tskin.leftArm.rotation.z = Math.cos(time) * 0.1 + basicArmRotationZ;\n\tskin.rightArm.rotation.z = Math.cos(time + Math.PI) * 0.1 - basicArmRotationZ;\n\n\t// Jumping\n\tplayer.position.y = Math.cos(time * 2);\n\t// Dodging when running\n\tplayer.position.x = Math.cos(time) * 0.15;\n\t// Slightly tilting when running\n\tplayer.rotation.z = Math.cos(time + Math.PI) * 0.01;\n\n\t// Apply higher swing frequency, lower amplitude,\n\t// and greater basic rotation around x axis,\n\t// to cape when running.\n\tlet basicCapeRotationX = Math.PI * 0.3;\n\tplayer.cape.rotation.x = Math.sin(time * 2) * 0.1 + basicCapeRotationX;\n\n\t// What about head shaking?\n\t// You shouldn't glance right and left when running dude :P\n};\n\nlet RotatingAnimation = (player, time) => {\n\tplayer.rotation.y = time;\n};\n\nexport {\n\tCompositeAnimation,\n\tinvokeAnimation,\n\tWalkingAnimation,\n\tRunningAnimation,\n\tRotatingAnimation\n};\n","import * as THREE from \"three\";\nimport { PlayerObject } from \"./model\";\nimport { OrbitControls } from \"./orbit_controls\";\nimport { invokeAnimation } from \"./animation\";\n\nfunction copyImage(context, sX, sY, w, h, dX, dY, flipHorizontal) {\n\tlet imgData = context.getImageData(sX, sY, w, h);\n\tif (flipHorizontal) {\n\t\tfor (let y = 0; y < h; y++) {\n\t\t\tfor (let x = 0; x < (w / 2); x++) {\n\t\t\t\tlet index = (x + y * w) * 4;\n\t\t\t\tlet index2 = ((w - x - 1) + y * w) * 4;\n\t\t\t\tlet pA1 = imgData.data[index];\n\t\t\t\tlet pA2 = imgData.data[index + 1];\n\t\t\t\tlet pA3 = imgData.data[index + 2];\n\t\t\t\tlet pA4 = imgData.data[index + 3];\n\n\t\t\t\tlet pB1 = imgData.data[index2];\n\t\t\t\tlet pB2 = imgData.data[index2 + 1];\n\t\t\t\tlet pB3 = imgData.data[index2 + 2];\n\t\t\t\tlet pB4 = imgData.data[index2 + 3];\n\n\t\t\t\timgData.data[index] = pB1;\n\t\t\t\timgData.data[index + 1] = pB2;\n\t\t\t\timgData.data[index + 2] = pB3;\n\t\t\t\timgData.data[index + 3] = pB4;\n\n\t\t\t\timgData.data[index2] = pA1;\n\t\t\t\timgData.data[index2 + 1] = pA2;\n\t\t\t\timgData.data[index2 + 2] = pA3;\n\t\t\t\timgData.data[index2 + 3] = pA4;\n\t\t\t}\n\t\t}\n\t}\n\tcontext.putImageData(imgData, dX, dY);\n}\n\nfunction convertSkinTo1_8(context, width) {\n\tlet scale = width / 64.0;\n\tlet copySkin = (context, sX, sY, w, h, dX, dY, flipHorizontal) => copyImage(context, sX * scale, sY * scale, w * scale, h * scale, dX * scale, dY * scale, flipHorizontal);\n\n\tcopySkin(context, 4, 16, 4, 4, 20, 48, true); // Top Leg\n\tcopySkin(context, 8, 16, 4, 4, 24, 48, true); // Bottom Leg\n\tcopySkin(context, 0, 20, 4, 12, 24, 52, true); // Outer Leg\n\tcopySkin(context, 4, 20, 4, 12, 20, 52, true); // Front Leg\n\tcopySkin(context, 8, 20, 4, 12, 16, 52, true); // Inner Leg\n\tcopySkin(context, 12, 20, 4, 12, 28, 52, true); // Back Leg\n\tcopySkin(context, 44, 16, 4, 4, 36, 48, true); // Top Arm\n\tcopySkin(context, 48, 16, 4, 4, 40, 48, true); // Bottom Arm\n\tcopySkin(context, 40, 20, 4, 12, 40, 52, true); // Outer Arm\n\tcopySkin(context, 44, 20, 4, 12, 36, 52, true); // Front Arm\n\tcopySkin(context, 48, 20, 4, 12, 32, 52, true); // Inner Arm\n\tcopySkin(context, 52, 20, 4, 12, 44, 52, true); // Back Arm\n}\n\nclass SkinViewer {\n\tconstructor(options) {\n\t\tthis.domElement = options.domElement;\n\t\tthis.animation = options.animation || null;\n\t\tthis.animationPaused = false;\n\t\tthis.animationTime = 0;\n\t\tthis.disposed = false;\n\n\t\t// texture\n\t\tthis.skinImg = new Image();\n\t\tthis.skinCanvas = document.createElement(\"canvas\");\n\t\tthis.skinTexture = new THREE.Texture(this.skinCanvas);\n\t\tthis.skinTexture.magFilter = THREE.NearestFilter;\n\t\tthis.skinTexture.minFilter = THREE.NearestMipMapNearestFilter;\n\n\t\tthis.capeImg = new Image();\n\t\tthis.capeCanvas = document.createElement(\"canvas\");\n\t\tthis.capeTexture = new THREE.Texture(this.capeCanvas);\n\t\tthis.capeTexture.magFilter = THREE.NearestFilter;\n\t\tthis.capeTexture.minFilter = THREE.NearestMipMapNearestFilter;\n\n\t\tthis.layer1Material = new THREE.MeshBasicMaterial({ map: this.skinTexture, side: THREE.FrontSide });\n\t\tthis.layer2Material = new THREE.MeshBasicMaterial({ map: this.skinTexture, transparent: true, opacity: 1, side: THREE.DoubleSide });\n\t\tthis.capeMaterial = new THREE.MeshBasicMaterial({ map: this.capeTexture });\n\n\t\t// scene\n\t\tthis.scene = new THREE.Scene();\n\n\t\t// Use smaller fov to avoid distortion\n\t\tthis.camera = new THREE.PerspectiveCamera(40);\n\t\tthis.camera.position.y = -12;\n\t\tthis.camera.position.z = 60;\n\n\t\tthis.renderer = new THREE.WebGLRenderer({ angleRot: true, alpha: true, antialias: false });\n\t\tthis.renderer.setSize(300, 300); // default size\n\t\tthis.renderer.context.getShaderInfoLog = () => \"\"; // shut firefox up\n\t\tthis.domElement.appendChild(this.renderer.domElement);\n\n\t\tthis.playerObject = new PlayerObject(options.slim === true, this.layer1Material, this.layer2Material, this.capeMaterial);\n\t\tthis.scene.add(this.playerObject);\n\n\t\t// texture loading\n\t\tthis.skinImg.crossOrigin = \"\";\n\t\tthis.skinImg.onerror = () => console.error(\"Failed loading \" + this.skinImg.src);\n\t\tthis.skinImg.onload = () => {\n\t\t\tlet isOldFormat = false;\n\t\t\tif (this.skinImg.width !== this.skinImg.height) {\n\t\t\t\tif (this.skinImg.width === 2 * this.skinImg.height) {\n\t\t\t\t\tisOldFormat = true;\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(\"Bad skin size\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet skinContext = this.skinCanvas.getContext(\"2d\");\n\t\t\tif (isOldFormat) {\n\t\t\t\tlet width = this.skinImg.width;\n\t\t\t\tthis.skinCanvas.width = width;\n\t\t\t\tthis.skinCanvas.height = width;\n\t\t\t\tskinContext.clearRect(0, 0, width, width);\n\t\t\t\tskinContext.drawImage(this.skinImg, 0, 0, width, width / 2.0);\n\t\t\t\tconvertSkinTo1_8(skinContext, width);\n\t\t\t} else {\n\t\t\t\tthis.skinCanvas.width = this.skinImg.width;\n\t\t\t\tthis.skinCanvas.height = this.skinImg.height;\n\t\t\t\tskinContext.clearRect(0, 0, this.skinCanvas.width, this.skinCanvas.height);\n\t\t\t\tskinContext.drawImage(this.skinImg, 0, 0, this.skinCanvas.width, this.skinCanvas.height);\n\t\t\t}\n\n\t\t\tthis.skinTexture.needsUpdate = true;\n\t\t\tthis.layer1Material.needsUpdate = true;\n\t\t\tthis.layer2Material.needsUpdate = true;\n\n\t\t\tthis.playerObject.skin.visible = true;\n\t\t};\n\n\t\tthis.capeImg.crossOrigin = \"\";\n\t\tthis.capeImg.onerror = () => console.error(\"Failed loading \" + this.capeImg.src);\n\t\tthis.capeImg.onload = () => {\n\t\t\tlet isOldFormat = false;\n\t\t\tif (this.capeImg.width !== 2 * this.capeImg.height) {\n\t\t\t\tif (this.capeImg.width * 17 == this.capeImg.height * 22) {\n\t\t\t\t\t// width/height = 22/17\n\t\t\t\t\tisOldFormat = true;\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(\"Bad cape size\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet capeContext = this.capeCanvas.getContext(\"2d\");\n\t\t\tif (isOldFormat) {\n\t\t\t\tlet width = this.capeImg.width * 64 / 22;\n\t\t\t\tthis.capeCanvas.width = width;\n\t\t\t\tthis.capeCanvas.height = width / 2;\n\t\t\t} else {\n\t\t\t\tthis.capeCanvas.width = this.capeImg.width;\n\t\t\t\tthis.capeCanvas.height = this.capeImg.height;\n\t\t\t}\n\t\t\tcapeContext.clearRect(0, 0, this.capeCanvas.width, this.capeCanvas.height);\n\t\t\tcapeContext.drawImage(this.capeImg, 0, 0, this.capeImg.width, this.capeImg.height);\n\n\t\t\tthis.capeTexture.needsUpdate = true;\n\t\t\tthis.capeMaterial.needsUpdate = true;\n\n\t\t\tthis.playerObject.cape.visible = true;\n\t\t};\n\n\t\tif (options.skinUrl) this.skinUrl = options.skinUrl;\n\t\tif (options.capeUrl) this.capeUrl = options.capeUrl;\n\t\tif (options.width) this.width = options.width;\n\t\tif (options.height) this.height = options.height;\n\n\t\tlet draw = () => {\n\t\t\tif (this.disposed) return;\n\t\t\twindow.requestAnimationFrame(draw);\n\t\t\tif (!this.animationPaused) {\n\t\t\t\tthis.animationTime++;\n\t\t\t\tif (this.animation) {\n\t\t\t\t\tinvokeAnimation(this.animation, this.playerObject, this.animationTime / 100.0);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.renderer.render(this.scene, this.camera);\n\t\t};\n\t\tdraw();\n\t}\n\n\tsetSize(width, height) {\n\t\tthis.camera.aspect = width / height;\n\t\tthis.camera.updateProjectionMatrix();\n\t\tthis.renderer.setSize(width, height);\n\t}\n\n\tdispose() {\n\t\tthis.disposed = true;\n\t\tthis.domElement.removeChild(this.renderer.domElement);\n\t\tthis.renderer.dispose();\n\t\tthis.skinTexture.dispose();\n\t\tthis.capeTexture.dispose();\n\t}\n\n\tget skinUrl() {\n\t\treturn this.skinImg.src;\n\t}\n\n\tset skinUrl(url) {\n\t\tthis.skinImg.src = url;\n\t}\n\n\tget capeUrl() {\n\t\treturn this.capeImg.src;\n\t}\n\n\tset capeUrl(url) {\n\t\tthis.capeImg.src = url;\n\t}\n\n\tget width() {\n\t\treturn this.renderer.getSize().width;\n\t}\n\n\tset width(newWidth) {\n\t\tthis.setSize(newWidth, this.height);\n\t}\n\n\tget height() {\n\t\treturn this.renderer.getSize().height;\n\t}\n\n\tset height(newHeight) {\n\t\tthis.setSize(this.width, newHeight);\n\t}\n}\n\nclass MouseControl {\n\tconstructor(skinViewer) {\n\t\tthis.skinViewer = skinViewer;\n\n\t\tthis.orbitControls = new OrbitControls(skinViewer.camera, skinViewer.renderer.domElement);\n\t\tthis.orbitControls.enablePan = false;\n\t\tthis.orbitControls.target = new THREE.Vector3(0, -12, 0);\n\t\tthis.orbitControls.minDistance = 10;\n\t\tthis.orbitControls.maxDistance = 256;\n\t\tthis.orbitControls.update();\n\t}\n\n\tget rotation() {\n\t\treturn this.orbitControls.enableRotate;\n\t}\n\n\tset rotation(value) {\n\t\tthis.orbitControls.enableRotate = value;\n\t}\n\n\tget zoom() {\n\t\treturn this.orbitControls.enableZoom;\n\t}\n\n\tset zoom(value) {\n\t\tthis.orbitControls.enableZoom = value;\n\t}\n\n\tget pan() {\n\t\treturn this.orbitControls.enablePan;\n\t}\n\n\tset pan(value) {\n\t\tthis.orbitControls.enablePan = value;\n\t}\n\n\tdispose() {\n\t\tthis.orbitControls.dispose();\n\t}\n}\n\nexport { SkinViewer, MouseControl };\n"],"names":["toFaceVertices","x1","y1","x2","y2","w","h","THREE","toSkinVertices","toCapeVertices","addVertices","box","top","bottom","left","front","right","back","faceVertexUvs","esp","SkinObject","slim","layer1Material","layer2Material","head","headBox","headMesh","add","head2Box","head2Mesh","renderOrder","_this","body","bodyBox","bodyMesh","body2Box","body2Mesh","position","y","rightArm","rightArmPivot","rightArmBox","rightArmMesh","rightArm2Box","rightArm2Mesh","x","leftArm","leftArmPivot","leftArmBox","leftArmMesh","leftArm2Box","leftArm2Mesh","rightLeg","rightLegPivot","rightLegBox","rightLegMesh","rightLeg2Box","rightLeg2Mesh","leftLeg","leftLegPivot","leftLegBox","leftLegMesh","leftLeg2Box","leftLeg2Mesh","CapeObject","capeMaterial","capeBox","cape","z","_this2","PlayerObject","skin","visible","_this3","rotation","Math","PI","OrbitControls","object","domElement","offset","quat","quatInverse","lastPosition","lastQuaternion","undefined","document","enabled","target","minDistance","maxDistance","Infinity","minZoom","maxZoom","minPolarAngle","maxPolarAngle","minAzimuthAngle","maxAzimuthAngle","enableDamping","dampingFactor","enableZoom","zoomSpeed","enableRotate","rotateSpeed","enablePan","keyPanSpeed","autoRotate","autoRotateSpeed","enableKeys","keys","LEFT","UP","RIGHT","BOTTOM","mouseButtons","ORBIT","ZOOM","MIDDLE","PAN","target0","clone","position0","zoom0","zoom","getPolarAngle","spherical","phi","getAzimuthalAngle","theta","saveState","copy","scope","reset","updateProjectionMatrix","dispatchEvent","changeEvent","update","STATE","NONE","setFromUnitVectors","up","inverse","sub","applyQuaternion","setFromVector3","state","sphericalDelta","max","min","makeSafe","radius","scale","panOffset","setFromSpherical","lookAt","set","zoomChanged","distanceToSquared","EPS","dot","quaternion","dispose","removeEventListener","onContextMenu","onMouseDown","onMouseWheel","onTouchStart","onTouchEnd","onTouchMove","onMouseMove","onMouseUp","onKeyDown","type","startEvent","endEvent","ROTATE","DOLLY","TOUCH_ROTATE","TOUCH_DOLLY","TOUCH_PAN","rotateStart","rotateEnd","rotateDelta","panStart","panEnd","panDelta","dollyStart","dollyEnd","dollyDelta","getZoomScale","pow","rotateLeft","angle","rotateUp","v","panLeft","distance","objectMatrix","setFromMatrixColumn","multiplyScalar","panUp","pan","deltaX","deltaY","element","targetDistance","length","tan","fov","clientHeight","matrix","clientWidth","warn","dollyIn","dollyScale","dollyOut","event","button","clientX","clientY","preventDefault","addEventListener","subVectors","stopPropagation","keyCode","touches","pageX","pageY","dx","dy","sqrt","invokeAnimation","animation","player","time","CompositeAnimation","play","Function","AnimationHandle","paused","this","_paused","speed","_speed","_lastChange","_lastChangeX","dt","handles","Set","handle","remove","delete","forEach","SkinViewer","options","animationPaused","animationTime","disposed","skinImg","Image","skinCanvas","createElement","skinTexture","magFilter","minFilter","capeImg","capeCanvas","capeTexture","map","side","transparent","opacity","scene","camera","renderer","angleRot","alpha","antialias","setSize","context","getShaderInfoLog","appendChild","playerObject","crossOrigin","onerror","console","error","src","onload","isOldFormat","width","height","skinContext","getContext","clearRect","drawImage","copySkin","sX","sY","dX","dY","flipHorizontal","imgData","getImageData","index","index2","pA1","data","pA2","pA3","pA4","pB1","pB2","pB3","pB4","putImageData","copyImage","needsUpdate","capeContext","skinUrl","capeUrl","draw","requestAnimationFrame","render","aspect","removeChild","url","getSize","newWidth","newHeight","MouseControl","skinViewer","orbitControls","value","sin","basicArmRotationZ","cos","basicCapeRotationX"],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"skinview3d.min.js","sources":["../src/model.js","../src/animation.js","../src/viewer.js","../src/orbit_controls.js"],"sourcesContent":["import * as THREE from \"three\";\n\nfunction toFaceVertices(x1, y1, x2, y2, w, h) {\n\treturn [\n\t\tnew THREE.Vector2(x1 / w, 1.0 - y2 / h),\n\t\tnew THREE.Vector2(x2 / w, 1.0 - y2 / h),\n\t\tnew THREE.Vector2(x2 / w, 1.0 - y1 / h),\n\t\tnew THREE.Vector2(x1 / w, 1.0 - y1 / h)\n\t];\n}\n\nfunction toSkinVertices(x1, y1, x2, y2) {\n\treturn toFaceVertices(x1, y1, x2, y2, 64.0, 64.0);\n}\n\nfunction toCapeVertices(x1, y1, x2, y2) {\n\treturn toFaceVertices(x1, y1, x2, y2, 64.0, 32.0);\n}\n\nfunction addVertices(box, top, bottom, left, front, right, back) {\n\tbox.faceVertexUvs[0] = [];\n\tbox.faceVertexUvs[0][0] = [right[3], right[0], right[2]];\n\tbox.faceVertexUvs[0][1] = [right[0], right[1], right[2]];\n\tbox.faceVertexUvs[0][2] = [left[3], left[0], left[2]];\n\tbox.faceVertexUvs[0][3] = [left[0], left[1], left[2]];\n\tbox.faceVertexUvs[0][4] = [top[3], top[0], top[2]];\n\tbox.faceVertexUvs[0][5] = [top[0], top[1], top[2]];\n\tbox.faceVertexUvs[0][6] = [bottom[0], bottom[3], bottom[1]];\n\tbox.faceVertexUvs[0][7] = [bottom[3], bottom[2], bottom[1]];\n\tbox.faceVertexUvs[0][8] = [front[3], front[0], front[2]];\n\tbox.faceVertexUvs[0][9] = [front[0], front[1], front[2]];\n\tbox.faceVertexUvs[0][10] = [back[3], back[0], back[2]];\n\tbox.faceVertexUvs[0][11] = [back[0], back[1], back[2]];\n}\n\nconst esp = 0.002;\n\nclass SkinObject extends THREE.Group {\n\tconstructor(slim, layer1Material, layer2Material) {\n\t\tsuper();\n\n\t\tthis.slim = slim;\n\n\t\t// Head\n\t\tthis.head = new THREE.Group();\n\n\t\tlet headBox = new THREE.BoxGeometry(8, 8, 8, 0, 0, 0);\n\t\taddVertices(headBox,\n\t\t\ttoSkinVertices(8, 0, 16, 8),\n\t\t\ttoSkinVertices(16, 0, 24, 8),\n\t\t\ttoSkinVertices(0, 8, 8, 16),\n\t\t\ttoSkinVertices(8, 8, 16, 16),\n\t\t\ttoSkinVertices(16, 8, 24, 16),\n\t\t\ttoSkinVertices(24, 8, 32, 16)\n\t\t);\n\t\tlet headMesh = new THREE.Mesh(headBox, layer1Material);\n\t\tthis.head.add(headMesh);\n\n\t\tlet head2Box = new THREE.BoxGeometry(9, 9, 9, 0, 0, 0);\n\t\taddVertices(head2Box,\n\t\t\ttoSkinVertices(40, 0, 48, 8),\n\t\t\ttoSkinVertices(48, 0, 56, 8),\n\t\t\ttoSkinVertices(32, 8, 40, 16),\n\t\t\ttoSkinVertices(40, 8, 48, 16),\n\t\t\ttoSkinVertices(48, 8, 56, 16),\n\t\t\ttoSkinVertices(56, 8, 64, 16)\n\t\t);\n\t\tlet head2Mesh = new THREE.Mesh(head2Box, layer2Material);\n\t\thead2Mesh.renderOrder = -1;\n\t\tthis.head.add(head2Mesh);\n\n\t\tthis.add(this.head);\n\n\n\t\t// Body\n\t\tthis.body = new THREE.Group();\n\n\t\tlet bodyBox = new THREE.BoxGeometry(8, 12, 4, 0, 0, 0);\n\t\taddVertices(bodyBox,\n\t\t\ttoSkinVertices(20, 16, 28, 20),\n\t\t\ttoSkinVertices(28, 16, 36, 20),\n\t\t\ttoSkinVertices(16, 20, 20, 32),\n\t\t\ttoSkinVertices(20, 20, 28, 32),\n\t\t\ttoSkinVertices(28, 20, 32, 32),\n\t\t\ttoSkinVertices(32, 20, 40, 32)\n\t\t);\n\t\tlet bodyMesh = new THREE.Mesh(bodyBox, layer1Material);\n\t\tthis.body.add(bodyMesh);\n\n\t\tlet body2Box = new THREE.BoxGeometry(9, 13.5, 4.5, 0, 0, 0);\n\t\taddVertices(body2Box,\n\t\t\ttoSkinVertices(20, 32, 28, 36),\n\t\t\ttoSkinVertices(28, 32, 36, 36),\n\t\t\ttoSkinVertices(16, 36, 20, 48),\n\t\t\ttoSkinVertices(20, 36, 28, 48),\n\t\t\ttoSkinVertices(28, 36, 32, 48),\n\t\t\ttoSkinVertices(32, 36, 40, 48)\n\t\t);\n\t\tlet body2Mesh = new THREE.Mesh(body2Box, layer2Material);\n\t\tthis.body.add(body2Mesh);\n\n\t\tthis.body.position.y = -10;\n\t\tthis.add(this.body);\n\n\n\t\t// Right Arm\n\t\tthis.rightArm = new THREE.Group();\n\t\tlet rightArmPivot = new THREE.Group();\n\n\t\tlet rightArmBox = new THREE.BoxGeometry((slim ? 3 : 4) - esp, 12 - esp, 4 - esp, 0, 0, 0);\n\t\tif (slim) {\n\t\t\taddVertices(rightArmBox,\n\t\t\t\ttoSkinVertices(44, 16, 47, 20),\n\t\t\t\ttoSkinVertices(47, 16, 50, 20),\n\t\t\t\ttoSkinVertices(40, 20, 44, 32),\n\t\t\t\ttoSkinVertices(44, 20, 47, 32),\n\t\t\t\ttoSkinVertices(47, 20, 51, 32),\n\t\t\t\ttoSkinVertices(51, 20, 54, 32)\n\t\t\t);\n\t\t} else {\n\t\t\taddVertices(rightArmBox,\n\t\t\t\ttoSkinVertices(44, 16, 48, 20),\n\t\t\t\ttoSkinVertices(48, 16, 52, 20),\n\t\t\t\ttoSkinVertices(40, 20, 44, 32),\n\t\t\t\ttoSkinVertices(44, 20, 48, 32),\n\t\t\t\ttoSkinVertices(48, 20, 52, 32),\n\t\t\t\ttoSkinVertices(52, 20, 56, 32)\n\t\t\t);\n\t\t}\n\t\tlet rightArmMesh = new THREE.Mesh(rightArmBox, layer1Material);\n\t\trightArmPivot.add(rightArmMesh);\n\n\t\tlet rightArm2Box = new THREE.BoxGeometry((slim ? 3.375 : 4.5) - esp, 13.5 - esp, 4.5 - esp, 0, 0, 0);\n\t\tif (slim) {\n\t\t\taddVertices(rightArm2Box,\n\t\t\t\ttoSkinVertices(44, 32, 47, 36),\n\t\t\t\ttoSkinVertices(47, 32, 50, 36),\n\t\t\t\ttoSkinVertices(40, 36, 44, 48),\n\t\t\t\ttoSkinVertices(44, 36, 47, 48),\n\t\t\t\ttoSkinVertices(47, 36, 51, 48),\n\t\t\t\ttoSkinVertices(51, 36, 54, 48)\n\t\t\t);\n\t\t} else {\n\t\t\taddVertices(rightArm2Box,\n\t\t\t\ttoSkinVertices(44, 32, 48, 36),\n\t\t\t\ttoSkinVertices(48, 32, 52, 36),\n\t\t\t\ttoSkinVertices(40, 36, 44, 48),\n\t\t\t\ttoSkinVertices(44, 36, 48, 48),\n\t\t\t\ttoSkinVertices(48, 36, 52, 48),\n\t\t\t\ttoSkinVertices(52, 36, 56, 48)\n\t\t\t);\n\t\t}\n\t\tlet rightArm2Mesh = new THREE.Mesh(rightArm2Box, layer2Material);\n\t\trightArm2Mesh.renderOrder = 1;\n\t\trightArmPivot.add(rightArm2Mesh);\n\n\t\trightArmPivot.position.y = -6;\n\t\tthis.rightArm.add(rightArmPivot);\n\t\tthis.rightArm.position.y = -4;\n\t\tthis.rightArm.position.x = slim ? -5.5 : -6;\n\t\tthis.add(this.rightArm);\n\n\n\t\t// Left Arm\n\t\tthis.leftArm = new THREE.Group();\n\t\tlet leftArmPivot = new THREE.Group();\n\n\t\tlet leftArmBox = new THREE.BoxGeometry((slim ? 3 : 4) - esp, 12 - esp, 4 - esp, 0, 0, 0);\n\t\tif (slim) {\n\t\t\taddVertices(leftArmBox,\n\t\t\t\ttoSkinVertices(36, 48, 39, 52),\n\t\t\t\ttoSkinVertices(39, 48, 42, 52),\n\t\t\t\ttoSkinVertices(32, 52, 36, 64),\n\t\t\t\ttoSkinVertices(36, 52, 39, 64),\n\t\t\t\ttoSkinVertices(39, 52, 43, 64),\n\t\t\t\ttoSkinVertices(43, 52, 46, 64)\n\t\t\t);\n\t\t} else {\n\t\t\taddVertices(leftArmBox,\n\t\t\t\ttoSkinVertices(36, 48, 40, 52),\n\t\t\t\ttoSkinVertices(40, 48, 44, 52),\n\t\t\t\ttoSkinVertices(32, 52, 36, 64),\n\t\t\t\ttoSkinVertices(36, 52, 40, 64),\n\t\t\t\ttoSkinVertices(40, 52, 44, 64),\n\t\t\t\ttoSkinVertices(44, 52, 48, 64)\n\t\t\t);\n\t\t}\n\t\tlet leftArmMesh = new THREE.Mesh(leftArmBox, layer1Material);\n\t\tleftArmPivot.add(leftArmMesh);\n\n\t\tlet leftArm2Box = new THREE.BoxGeometry((slim ? 3.375 : 4.5) - esp, 13.5 - esp, 4.5 - esp, 0, 0, 0);\n\t\tif (slim) {\n\t\t\taddVertices(leftArm2Box,\n\t\t\t\ttoSkinVertices(52, 48, 55, 52),\n\t\t\t\ttoSkinVertices(55, 48, 58, 52),\n\t\t\t\ttoSkinVertices(48, 52, 52, 64),\n\t\t\t\ttoSkinVertices(52, 52, 55, 64),\n\t\t\t\ttoSkinVertices(55, 52, 59, 64),\n\t\t\t\ttoSkinVertices(59, 52, 62, 64)\n\t\t\t);\n\t\t} else {\n\t\t\taddVertices(leftArm2Box,\n\t\t\t\ttoSkinVertices(52, 48, 56, 52),\n\t\t\t\ttoSkinVertices(56, 48, 60, 52),\n\t\t\t\ttoSkinVertices(48, 52, 52, 64),\n\t\t\t\ttoSkinVertices(52, 52, 56, 64),\n\t\t\t\ttoSkinVertices(56, 52, 60, 64),\n\t\t\t\ttoSkinVertices(60, 52, 64, 64)\n\t\t\t);\n\t\t}\n\t\tlet leftArm2Mesh = new THREE.Mesh(leftArm2Box, layer2Material);\n\t\tleftArm2Mesh.renderOrder = 1;\n\t\tleftArmPivot.add(leftArm2Mesh);\n\n\t\tleftArmPivot.position.y = -6;\n\t\tthis.leftArm.add(leftArmPivot);\n\t\tthis.leftArm.position.y = -4;\n\t\tthis.leftArm.position.x = slim ? 5.5 : 6;\n\t\tthis.add(this.leftArm);\n\n\n\t\t// Right Leg\n\t\tthis.rightLeg = new THREE.Group();\n\t\tlet rightLegPivot = new THREE.Group();\n\n\t\tlet rightLegBox = new THREE.BoxGeometry(4 - esp, 12 - esp, 4 - esp, 0, 0, 0);\n\t\taddVertices(rightLegBox,\n\t\t\ttoSkinVertices(4, 16, 8, 20),\n\t\t\ttoSkinVertices(8, 16, 12, 20),\n\t\t\ttoSkinVertices(0, 20, 4, 32),\n\t\t\ttoSkinVertices(4, 20, 8, 32),\n\t\t\ttoSkinVertices(8, 20, 12, 32),\n\t\t\ttoSkinVertices(12, 20, 16, 32)\n\t\t);\n\t\tlet rightLegMesh = new THREE.Mesh(rightLegBox, layer1Material);\n\t\trightLegPivot.add(rightLegMesh);\n\n\t\tlet rightLeg2Box = new THREE.BoxGeometry(4.5 - esp, 13.5 - esp, 4.5 - esp, 0, 0, 0);\n\t\taddVertices(rightLeg2Box,\n\t\t\ttoSkinVertices(4, 32, 8, 36),\n\t\t\ttoSkinVertices(8, 32, 12, 36),\n\t\t\ttoSkinVertices(0, 36, 4, 48),\n\t\t\ttoSkinVertices(4, 36, 8, 48),\n\t\t\ttoSkinVertices(8, 36, 12, 48),\n\t\t\ttoSkinVertices(12, 36, 16, 48)\n\t\t);\n\t\tlet rightLeg2Mesh = new THREE.Mesh(rightLeg2Box, layer2Material);\n\t\trightLeg2Mesh.renderOrder = 1;\n\t\trightLegPivot.add(rightLeg2Mesh);\n\n\t\trightLegPivot.position.y = -6;\n\t\tthis.rightLeg.add(rightLegPivot);\n\t\tthis.rightLeg.position.y = -16;\n\t\tthis.rightLeg.position.x = -2;\n\t\tthis.add(this.rightLeg);\n\n\t\t// Left Leg\n\t\tthis.leftLeg = new THREE.Group();\n\t\tlet leftLegPivot = new THREE.Group();\n\n\t\tlet leftLegBox = new THREE.BoxGeometry(4 - esp, 12 - esp, 4 - esp, 0, 0, 0);\n\t\taddVertices(leftLegBox,\n\t\t\ttoSkinVertices(20, 48, 24, 52),\n\t\t\ttoSkinVertices(24, 48, 28, 52),\n\t\t\ttoSkinVertices(16, 52, 20, 64),\n\t\t\ttoSkinVertices(20, 52, 24, 64),\n\t\t\ttoSkinVertices(24, 52, 28, 64),\n\t\t\ttoSkinVertices(28, 52, 32, 64)\n\t\t);\n\t\tlet leftLegMesh = new THREE.Mesh(leftLegBox, layer1Material);\n\t\tleftLegPivot.add(leftLegMesh);\n\n\t\tlet leftLeg2Box = new THREE.BoxGeometry(4.5 - esp, 13.5 - esp, 4.5 - esp, 0, 0, 0);\n\t\taddVertices(leftLeg2Box,\n\t\t\ttoSkinVertices(4, 48, 8, 52),\n\t\t\ttoSkinVertices(8, 48, 12, 52),\n\t\t\ttoSkinVertices(0, 52, 4, 64),\n\t\t\ttoSkinVertices(4, 52, 8, 64),\n\t\t\ttoSkinVertices(8, 52, 12, 64),\n\t\t\ttoSkinVertices(12, 52, 16, 64)\n\t\t);\n\t\tlet leftLeg2Mesh = new THREE.Mesh(leftLeg2Box, layer2Material);\n\t\tleftLeg2Mesh.renderOrder = 1;\n\t\tleftLegPivot.add(leftLeg2Mesh);\n\n\t\tleftLegPivot.position.y = -6;\n\t\tthis.leftLeg.add(leftLegPivot);\n\t\tthis.leftLeg.position.y = -16;\n\t\tthis.leftLeg.position.x = 2;\n\t\tthis.add(this.leftLeg);\n\t}\n}\n\nclass CapeObject extends THREE.Group {\n\tconstructor(capeMaterial) {\n\t\tsuper();\n\n\t\t// back = outside\n\t\t// front = inside\n\t\tlet capeBox = new THREE.BoxGeometry(10, 16, 1, 0, 0, 0);\n\t\taddVertices(capeBox,\n\t\t\ttoCapeVertices(1, 0, 11, 1),\n\t\t\ttoCapeVertices(11, 0, 21, 1),\n\t\t\ttoCapeVertices(11, 1, 12, 17),\n\t\t\ttoCapeVertices(12, 1, 22, 17),\n\t\t\ttoCapeVertices(0, 1, 1, 17),\n\t\t\ttoCapeVertices(1, 1, 11, 17)\n\t\t);\n\t\tthis.cape = new THREE.Mesh(capeBox, capeMaterial);\n\t\tthis.cape.position.y = -8;\n\t\tthis.cape.position.z = -0.5;\n\t\tthis.add(this.cape);\n\t}\n}\n\nclass PlayerObject extends THREE.Group {\n\tconstructor(slim, layer1Material, layer2Material, capeMaterial) {\n\t\tsuper();\n\n\t\tthis.skin = new SkinObject(slim, layer1Material, layer2Material);\n\t\tthis.skin.visible = false;\n\t\tthis.add(this.skin);\n\n\t\tthis.cape = new CapeObject(capeMaterial);\n\t\tthis.cape.position.z = -2;\n\t\tthis.cape.position.y = -4;\n\t\tthis.cape.rotation.x = 25 * Math.PI / 180;\n\t\tthis.cape.visible = false;\n\t\tthis.add(this.cape);\n\t}\n}\n\nexport { SkinObject, CapeObject, PlayerObject };\n","function invokeAnimation(animation, player, time) {\n\tif (animation instanceof CompositeAnimation) {\n\t\tanimation.play(player, time);\n\t} else if (animation instanceof Function) {\n\t\tanimation(player, time);\n\t} else {\n\t\tthrow `Not an animation: ${animation}`;\n\t}\n}\n\nclass AnimationHandle {\n\tconstructor(animation) {\n\t\tthis.animation = animation;\n\t\tthis.paused = this._paused = false;\n\t\tthis.speed = this._speed = 1.0;\n\t\tthis._lastChange = null;\n\t\tthis._lastChangeX = null;\n\t}\n\tplay(player, time) {\n\t\tif (this._lastChange === null) {\n\t\t\tthis._lastChange = time;\n\t\t\tthis._lastChangeX = 0;\n\t\t} else if (this.paused !== this._paused || this.speed !== this._speed) {\n\t\t\tlet dt = time - this._lastChange;\n\t\t\tif (this._paused === false) {\n\t\t\t\tthis._lastChangeX += dt * this._speed;\n\t\t\t}\n\t\t\tthis._paused = this.paused;\n\t\t\tthis._speed = this.speed;\n\t\t\tthis._lastChange = time;\n\t\t}\n\t\tif (this.paused === false) {\n\t\t\tlet dt = time - this._lastChange;\n\t\t\tlet x = this._lastChangeX + this.speed * dt;\n\t\t\tinvokeAnimation(this.animation, player, x);\n\t\t}\n\t}\n\treset(){\n\t\tthis._lastChange = null;\n\t}\n}\n\nclass CompositeAnimation {\n\tconstructor() {\n\t\tthis.handles = new Set();\n\t}\n\tadd(animation) {\n\t\tlet handle = new AnimationHandle(animation);\n\t\thandle.remove = () => this.handles.delete(handle);\n\t\tthis.handles.add(handle);\n\t\treturn handle;\n\t}\n\tplay(player, time) {\n\t\tthis.handles.forEach(handle => handle.play(player, time));\n\t}\n}\n\nlet WalkingAnimation = (player, time) => {\n\tlet skin = player.skin;\n\n\t// Multiply by animation's natural speed\n\ttime *= 8;\n\n\t// Leg swing\n\tskin.leftLeg.rotation.x = Math.sin(time) * 0.5;\n\tskin.rightLeg.rotation.x = Math.sin(time + Math.PI) * 0.5;\n\n\t// Arm swing\n\tskin.leftArm.rotation.x = Math.sin(time + Math.PI) * 0.5;\n\tskin.rightArm.rotation.x = Math.sin(time) * 0.5;\n\tlet basicArmRotationZ = Math.PI * 0.02;\n\tskin.leftArm.rotation.z = Math.cos(time) * 0.03 + basicArmRotationZ;\n\tskin.rightArm.rotation.z = Math.cos(time + Math.PI) * 0.03 - basicArmRotationZ;\n\n\t// Head shaking with different frequency & amplitude\n\tskin.head.rotation.y = Math.sin(time / 4) * 0.2;\n\tskin.head.rotation.x = Math.sin(time / 5) * 0.1;\n\n\t// Always add an angle for cape around the x axis\n\tlet basicCapeRotationX = Math.PI * 0.06;\n\tplayer.cape.rotation.x = Math.sin(time / 1.5) * 0.06 + basicCapeRotationX;\n};\n\nlet RunningAnimation = (player, time) => {\n\tlet skin = player.skin;\n\n\ttime *= 15;\n\n\t// Leg swing with larger amplitude\n\tskin.leftLeg.rotation.x = Math.cos(time + Math.PI) * 1.3;\n\tskin.rightLeg.rotation.x = Math.cos(time) * 1.3;\n\n\t// Arm swing\n\tskin.leftArm.rotation.x = Math.cos(time) * 1.5;\n\tskin.rightArm.rotation.x = Math.cos(time + Math.PI) * 1.5;\n\tlet basicArmRotationZ = Math.PI * 0.1;\n\tskin.leftArm.rotation.z = Math.cos(time) * 0.1 + basicArmRotationZ;\n\tskin.rightArm.rotation.z = Math.cos(time + Math.PI) * 0.1 - basicArmRotationZ;\n\n\t// Jumping\n\tplayer.position.y = Math.cos(time * 2);\n\t// Dodging when running\n\tplayer.position.x = Math.cos(time) * 0.15;\n\t// Slightly tilting when running\n\tplayer.rotation.z = Math.cos(time + Math.PI) * 0.01;\n\n\t// Apply higher swing frequency, lower amplitude,\n\t// and greater basic rotation around x axis,\n\t// to cape when running.\n\tlet basicCapeRotationX = Math.PI * 0.3;\n\tplayer.cape.rotation.x = Math.sin(time * 2) * 0.1 + basicCapeRotationX;\n\n\t// What about head shaking?\n\t// You shouldn't glance right and left when running dude :P\n};\n\nlet RotatingAnimation = (player, time) => {\n\tplayer.rotation.y = time;\n};\n\nexport {\n\tCompositeAnimation,\n\tinvokeAnimation,\n\tWalkingAnimation,\n\tRunningAnimation,\n\tRotatingAnimation\n};\n","import * as THREE from \"three\";\nimport { PlayerObject } from \"./model\";\nimport { invokeAnimation } from \"./animation\";\n\nfunction copyImage(context, sX, sY, w, h, dX, dY, flipHorizontal) {\n\tlet imgData = context.getImageData(sX, sY, w, h);\n\tif (flipHorizontal) {\n\t\tfor (let y = 0; y < h; y++) {\n\t\t\tfor (let x = 0; x < (w / 2); x++) {\n\t\t\t\tlet index = (x + y * w) * 4;\n\t\t\t\tlet index2 = ((w - x - 1) + y * w) * 4;\n\t\t\t\tlet pA1 = imgData.data[index];\n\t\t\t\tlet pA2 = imgData.data[index + 1];\n\t\t\t\tlet pA3 = imgData.data[index + 2];\n\t\t\t\tlet pA4 = imgData.data[index + 3];\n\n\t\t\t\tlet pB1 = imgData.data[index2];\n\t\t\t\tlet pB2 = imgData.data[index2 + 1];\n\t\t\t\tlet pB3 = imgData.data[index2 + 2];\n\t\t\t\tlet pB4 = imgData.data[index2 + 3];\n\n\t\t\t\timgData.data[index] = pB1;\n\t\t\t\timgData.data[index + 1] = pB2;\n\t\t\t\timgData.data[index + 2] = pB3;\n\t\t\t\timgData.data[index + 3] = pB4;\n\n\t\t\t\timgData.data[index2] = pA1;\n\t\t\t\timgData.data[index2 + 1] = pA2;\n\t\t\t\timgData.data[index2 + 2] = pA3;\n\t\t\t\timgData.data[index2 + 3] = pA4;\n\t\t\t}\n\t\t}\n\t}\n\tcontext.putImageData(imgData, dX, dY);\n}\n\nfunction convertSkinTo1_8(context, width) {\n\tlet scale = width / 64.0;\n\tlet copySkin = (context, sX, sY, w, h, dX, dY, flipHorizontal) => copyImage(context, sX * scale, sY * scale, w * scale, h * scale, dX * scale, dY * scale, flipHorizontal);\n\n\tcopySkin(context, 4, 16, 4, 4, 20, 48, true); // Top Leg\n\tcopySkin(context, 8, 16, 4, 4, 24, 48, true); // Bottom Leg\n\tcopySkin(context, 0, 20, 4, 12, 24, 52, true); // Outer Leg\n\tcopySkin(context, 4, 20, 4, 12, 20, 52, true); // Front Leg\n\tcopySkin(context, 8, 20, 4, 12, 16, 52, true); // Inner Leg\n\tcopySkin(context, 12, 20, 4, 12, 28, 52, true); // Back Leg\n\tcopySkin(context, 44, 16, 4, 4, 36, 48, true); // Top Arm\n\tcopySkin(context, 48, 16, 4, 4, 40, 48, true); // Bottom Arm\n\tcopySkin(context, 40, 20, 4, 12, 40, 52, true); // Outer Arm\n\tcopySkin(context, 44, 20, 4, 12, 36, 52, true); // Front Arm\n\tcopySkin(context, 48, 20, 4, 12, 32, 52, true); // Inner Arm\n\tcopySkin(context, 52, 20, 4, 12, 44, 52, true); // Back Arm\n}\n\nclass SkinViewer {\n\tconstructor(options) {\n\t\tthis.domElement = options.domElement;\n\t\tthis.animation = options.animation || null;\n\t\tthis.animationPaused = false;\n\t\tthis.animationTime = 0;\n\t\tthis.disposed = false;\n\n\t\t// texture\n\t\tthis.skinImg = new Image();\n\t\tthis.skinCanvas = document.createElement(\"canvas\");\n\t\tthis.skinTexture = new THREE.Texture(this.skinCanvas);\n\t\tthis.skinTexture.magFilter = THREE.NearestFilter;\n\t\tthis.skinTexture.minFilter = THREE.NearestMipMapNearestFilter;\n\n\t\tthis.capeImg = new Image();\n\t\tthis.capeCanvas = document.createElement(\"canvas\");\n\t\tthis.capeTexture = new THREE.Texture(this.capeCanvas);\n\t\tthis.capeTexture.magFilter = THREE.NearestFilter;\n\t\tthis.capeTexture.minFilter = THREE.NearestMipMapNearestFilter;\n\n\t\tthis.layer1Material = new THREE.MeshBasicMaterial({ map: this.skinTexture, side: THREE.FrontSide });\n\t\tthis.layer2Material = new THREE.MeshBasicMaterial({ map: this.skinTexture, transparent: true, opacity: 1, side: THREE.DoubleSide });\n\t\tthis.capeMaterial = new THREE.MeshBasicMaterial({ map: this.capeTexture });\n\n\t\t// scene\n\t\tthis.scene = new THREE.Scene();\n\n\t\t// Use smaller fov to avoid distortion\n\t\tthis.camera = new THREE.PerspectiveCamera(40);\n\t\tthis.camera.position.y = -12;\n\t\tthis.camera.position.z = 60;\n\n\t\tthis.renderer = new THREE.WebGLRenderer({ angleRot: true, alpha: true, antialias: false });\n\t\tthis.renderer.setSize(300, 300); // default size\n\t\tthis.renderer.context.getShaderInfoLog = () => \"\"; // shut firefox up\n\t\tthis.domElement.appendChild(this.renderer.domElement);\n\n\t\tthis.playerObject = new PlayerObject(options.slim === true, this.layer1Material, this.layer2Material, this.capeMaterial);\n\t\tthis.scene.add(this.playerObject);\n\n\t\t// texture loading\n\t\tthis.skinImg.crossOrigin = \"\";\n\t\tthis.skinImg.onerror = () => console.error(\"Failed loading \" + this.skinImg.src);\n\t\tthis.skinImg.onload = () => {\n\t\t\tlet isOldFormat = false;\n\t\t\tif (this.skinImg.width !== this.skinImg.height) {\n\t\t\t\tif (this.skinImg.width === 2 * this.skinImg.height) {\n\t\t\t\t\tisOldFormat = true;\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(\"Bad skin size\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet skinContext = this.skinCanvas.getContext(\"2d\");\n\t\t\tif (isOldFormat) {\n\t\t\t\tlet width = this.skinImg.width;\n\t\t\t\tthis.skinCanvas.width = width;\n\t\t\t\tthis.skinCanvas.height = width;\n\t\t\t\tskinContext.clearRect(0, 0, width, width);\n\t\t\t\tskinContext.drawImage(this.skinImg, 0, 0, width, width / 2.0);\n\t\t\t\tconvertSkinTo1_8(skinContext, width);\n\t\t\t} else {\n\t\t\t\tthis.skinCanvas.width = this.skinImg.width;\n\t\t\t\tthis.skinCanvas.height = this.skinImg.height;\n\t\t\t\tskinContext.clearRect(0, 0, this.skinCanvas.width, this.skinCanvas.height);\n\t\t\t\tskinContext.drawImage(this.skinImg, 0, 0, this.skinCanvas.width, this.skinCanvas.height);\n\t\t\t}\n\n\t\t\tthis.skinTexture.needsUpdate = true;\n\t\t\tthis.layer1Material.needsUpdate = true;\n\t\t\tthis.layer2Material.needsUpdate = true;\n\n\t\t\tthis.playerObject.skin.visible = true;\n\t\t};\n\n\t\tthis.capeImg.crossOrigin = \"\";\n\t\tthis.capeImg.onerror = () => console.error(\"Failed loading \" + this.capeImg.src);\n\t\tthis.capeImg.onload = () => {\n\t\t\tlet isOldFormat = false;\n\t\t\tif (this.capeImg.width !== 2 * this.capeImg.height) {\n\t\t\t\tif (this.capeImg.width * 17 == this.capeImg.height * 22) {\n\t\t\t\t\t// width/height = 22/17\n\t\t\t\t\tisOldFormat = true;\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(\"Bad cape size\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet capeContext = this.capeCanvas.getContext(\"2d\");\n\t\t\tif (isOldFormat) {\n\t\t\t\tlet width = this.capeImg.width * 64 / 22;\n\t\t\t\tthis.capeCanvas.width = width;\n\t\t\t\tthis.capeCanvas.height = width / 2;\n\t\t\t} else {\n\t\t\t\tthis.capeCanvas.width = this.capeImg.width;\n\t\t\t\tthis.capeCanvas.height = this.capeImg.height;\n\t\t\t}\n\t\t\tcapeContext.clearRect(0, 0, this.capeCanvas.width, this.capeCanvas.height);\n\t\t\tcapeContext.drawImage(this.capeImg, 0, 0, this.capeImg.width, this.capeImg.height);\n\n\t\t\tthis.capeTexture.needsUpdate = true;\n\t\t\tthis.capeMaterial.needsUpdate = true;\n\n\t\t\tthis.playerObject.cape.visible = true;\n\t\t};\n\n\t\tif (options.skinUrl) this.skinUrl = options.skinUrl;\n\t\tif (options.capeUrl) this.capeUrl = options.capeUrl;\n\t\tif (options.width) this.width = options.width;\n\t\tif (options.height) this.height = options.height;\n\n\t\tlet draw = () => {\n\t\t\tif (this.disposed) return;\n\t\t\twindow.requestAnimationFrame(draw);\n\t\t\tif (!this.animationPaused) {\n\t\t\t\tthis.animationTime++;\n\t\t\t\tif (this.animation) {\n\t\t\t\t\tinvokeAnimation(this.animation, this.playerObject, this.animationTime / 100.0);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.renderer.render(this.scene, this.camera);\n\t\t};\n\t\tdraw();\n\t}\n\n\tsetSize(width, height) {\n\t\tthis.camera.aspect = width / height;\n\t\tthis.camera.updateProjectionMatrix();\n\t\tthis.renderer.setSize(width, height);\n\t}\n\n\tdispose() {\n\t\tthis.disposed = true;\n\t\tthis.domElement.removeChild(this.renderer.domElement);\n\t\tthis.renderer.dispose();\n\t\tthis.skinTexture.dispose();\n\t\tthis.capeTexture.dispose();\n\t}\n\n\tget skinUrl() {\n\t\treturn this.skinImg.src;\n\t}\n\n\tset skinUrl(url) {\n\t\tthis.skinImg.src = url;\n\t}\n\n\tget capeUrl() {\n\t\treturn this.capeImg.src;\n\t}\n\n\tset capeUrl(url) {\n\t\tthis.capeImg.src = url;\n\t}\n\n\tget width() {\n\t\treturn this.renderer.getSize().width;\n\t}\n\n\tset width(newWidth) {\n\t\tthis.setSize(newWidth, this.height);\n\t}\n\n\tget height() {\n\t\treturn this.renderer.getSize().height;\n\t}\n\n\tset height(newHeight) {\n\t\tthis.setSize(this.width, newHeight);\n\t}\n}\n\nexport { SkinViewer };\n","import * as THREE from \"three\";\n\nclass OrbitControls extends THREE.EventDispatcher {\n\t/**\n\t * @preserve\n\t * The code was originally from https://github.com/mrdoob/three.js/blob/d45a042cf962e9b1aa9441810ba118647b48aacb/examples/js/controls/OrbitControls.js\n\t */\n\t/**\n\t * @license\n\t * Copyright (C) 2010-2017 three.js authors\n\t *\n\t * Permission is hereby granted, free of charge, to any person obtaining a copy\n\t * of this software and associated documentation files (the \"Software\"), to deal\n\t * in the Software without restriction, including without limitation the rights\n\t * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\t * copies of the Software, and to permit persons to whom the Software is\n\t * furnished to do so, subject to the following conditions:\n\t *\n\t * The above copyright notice and this permission notice shall be included in\n\t * all copies or substantial portions of the Software.\n\t *\n\t * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\t * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\t * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\t * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\t * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\t * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\t * THE SOFTWARE.\n\t *\n\t *\n\t * @author qiao / https://github.com/qiao\n\t * @author mrdoob / http://mrdoob.com\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author erich666 / http://erichaines.com\n\t */\n\n\t// This set of controls performs orbiting, dollying (zooming), and panning.\n\t// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n\t//\n\t// Orbit - left mouse / touch: one finger move\n\t// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish\n\t// Pan - right mouse, or arrow keys / touch: three finger swipe\n\n\tconstructor(object, domElement) {\n\t\tsuper();\n\t\tthis.object = object;\n\t\tthis.domElement = (domElement !== undefined) ? domElement : document;\n\n\t\t// Set to false to disable this control\n\t\tthis.enabled = true;\n\n\t\t// \"target\" sets the location of focus, where the object orbits around\n\t\tthis.target = new THREE.Vector3();\n\n\t\t// How far you can dolly in and out (PerspectiveCamera only)\n\t\tthis.minDistance = 0;\n\t\tthis.maxDistance = Infinity;\n\n\t\t// How far you can zoom in and out (OrthographicCamera only)\n\t\tthis.minZoom = 0;\n\t\tthis.maxZoom = Infinity;\n\n\t\t// How far you can orbit vertically, upper and lower limits.\n\t\t// Range is 0 to Math.PI radians.\n\t\tthis.minPolarAngle = 0; // radians\n\t\tthis.maxPolarAngle = Math.PI; // radians\n\n\t\t// How far you can orbit horizontally, upper and lower limits.\n\t\t// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].\n\t\tthis.minAzimuthAngle = -Infinity; // radians\n\t\tthis.maxAzimuthAngle = Infinity; // radians\n\n\t\t// Set to true to enable damping (inertia)\n\t\t// If damping is enabled, you must call controls.update() in your animation loop\n\t\tthis.enableDamping = false;\n\t\tthis.dampingFactor = 0.25;\n\n\t\t// This option actually enables dollying in and out; left as \"zoom\" for backwards compatibility.\n\t\t// Set to false to disable zooming\n\t\tthis.enableZoom = true;\n\t\tthis.zoomSpeed = 1.0;\n\n\t\t// Set to false to disable rotating\n\t\tthis.enableRotate = true;\n\t\tthis.rotateSpeed = 1.0;\n\n\t\t// Set to false to disable panning\n\t\tthis.enablePan = true;\n\t\tthis.keyPanSpeed = 7.0; // pixels moved per arrow key push\n\n\t\t// Set to true to automatically rotate around the target\n\t\t// If auto-rotate is enabled, you must call controls.update() in your animation loop\n\t\tthis.autoRotate = false;\n\t\tthis.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60\n\n\t\t// Set to false to disable use of the keys\n\t\tthis.enableKeys = true;\n\n\t\t// The four arrow keys\n\t\tthis.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };\n\n\t\t// Mouse buttons\n\t\tthis.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };\n\n\t\t// for reset\n\t\tthis.target0 = this.target.clone();\n\t\tthis.position0 = this.object.position.clone();\n\t\tthis.zoom0 = this.object.zoom;\n\n\t\t//\n\t\t// public methods\n\t\t//\n\t\tthis.getPolarAngle = function () {\n\t\t\treturn spherical.phi;\n\t\t};\n\t\tthis.getAzimuthalAngle = function () {\n\t\t\treturn spherical.theta;\n\t\t};\n\t\tthis.saveState = function () {\n\t\t\tscope.target0.copy(scope.target);\n\t\t\tscope.position0.copy(scope.object.position);\n\t\t\tscope.zoom0 = scope.object.zoom;\n\t\t};\n\t\tthis.reset = function () {\n\t\t\tscope.target.copy(scope.target0);\n\t\t\tscope.object.position.copy(scope.position0);\n\t\t\tscope.object.zoom = scope.zoom0;\n\t\t\tscope.object.updateProjectionMatrix();\n\t\t\tscope.dispatchEvent(changeEvent);\n\t\t\tscope.update();\n\t\t\tstate = STATE.NONE;\n\t\t};\n\n\t\t// this method is exposed, but perhaps it would be better if we can make it private...\n\t\tthis.update = function () {\n\t\t\tlet offset = new THREE.Vector3();\n\t\t\t// so camera.up is the orbit axis\n\t\t\tlet quat = new THREE.Quaternion().setFromUnitVectors(object.up, new THREE.Vector3(0, 1, 0));\n\t\t\tlet quatInverse = quat.clone().inverse();\n\t\t\tlet lastPosition = new THREE.Vector3();\n\t\t\tlet lastQuaternion = new THREE.Quaternion();\n\t\t\treturn function update() {\n\t\t\t\tlet position = scope.object.position;\n\t\t\t\toffset.copy(position).sub(scope.target);\n\t\t\t\t// rotate offset to \"y-axis-is-up\" space\n\t\t\t\toffset.applyQuaternion(quat);\n\t\t\t\t// angle from z-axis around y-axis\n\t\t\t\tspherical.setFromVector3(offset);\n\t\t\t\tif (scope.autoRotate && state === STATE.NONE) {\n\t\t\t\t\trotateLeft(getAutoRotationAngle());\n\t\t\t\t}\n\t\t\t\tspherical.theta += sphericalDelta.theta;\n\t\t\t\tspherical.phi += sphericalDelta.phi;\n\t\t\t\t// restrict theta to be between desired limits\n\t\t\t\tspherical.theta = Math.max(scope.minAzimuthAngle, Math.min(scope.maxAzimuthAngle, spherical.theta));\n\t\t\t\t// restrict phi to be between desired limits\n\t\t\t\tspherical.phi = Math.max(scope.minPolarAngle, Math.min(scope.maxPolarAngle, spherical.phi));\n\t\t\t\tspherical.makeSafe();\n\t\t\t\tspherical.radius *= scale;\n\t\t\t\t// restrict radius to be between desired limits\n\t\t\t\tspherical.radius = Math.max(scope.minDistance, Math.min(scope.maxDistance, spherical.radius));\n\t\t\t\t// move target to panned location\n\t\t\t\tscope.target.add(panOffset);\n\t\t\t\toffset.setFromSpherical(spherical);\n\t\t\t\t// rotate offset back to \"camera-up-vector-is-up\" space\n\t\t\t\toffset.applyQuaternion(quatInverse);\n\t\t\t\tposition.copy(scope.target).add(offset);\n\t\t\t\tscope.object.lookAt(scope.target);\n\t\t\t\tif (scope.enableDamping === true) {\n\t\t\t\t\tsphericalDelta.theta *= (1 - scope.dampingFactor);\n\t\t\t\t\tsphericalDelta.phi *= (1 - scope.dampingFactor);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tsphericalDelta.set(0, 0, 0);\n\t\t\t\t}\n\t\t\t\tscale = 1;\n\t\t\t\tpanOffset.set(0, 0, 0);\n\t\t\t\t// update condition is:\n\t\t\t\t// min(camera displacement, camera rotation in radians)^2 > EPS\n\t\t\t\t// using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\t\t\t\tif (zoomChanged ||\n\t\t\t\t\tlastPosition.distanceToSquared(scope.object.position) > EPS ||\n\t\t\t\t\t8 * (1 - lastQuaternion.dot(scope.object.quaternion)) > EPS) {\n\t\t\t\t\tscope.dispatchEvent(changeEvent);\n\t\t\t\t\tlastPosition.copy(scope.object.position);\n\t\t\t\t\tlastQuaternion.copy(scope.object.quaternion);\n\t\t\t\t\tzoomChanged = false;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}();\n\t\tthis.dispose = function () {\n\t\t\tscope.domElement.removeEventListener(\"contextmenu\", onContextMenu, false);\n\t\t\tscope.domElement.removeEventListener(\"mousedown\", onMouseDown, false);\n\t\t\tscope.domElement.removeEventListener(\"wheel\", onMouseWheel, false);\n\t\t\tscope.domElement.removeEventListener(\"touchstart\", onTouchStart, false);\n\t\t\tscope.domElement.removeEventListener(\"touchend\", onTouchEnd, false);\n\t\t\tscope.domElement.removeEventListener(\"touchmove\", onTouchMove, false);\n\t\t\tdocument.removeEventListener(\"mousemove\", onMouseMove, false);\n\t\t\tdocument.removeEventListener(\"mouseup\", onMouseUp, false);\n\t\t\twindow.removeEventListener(\"keydown\", onKeyDown, false);\n\t\t\t//scope.dispatchEvent({ type: \"dispose\" }); // should this be added here?\n\t\t};\n\t\t//\n\t\t// internals\n\t\t//\n\t\tlet scope = this;\n\t\tlet changeEvent = { type: \"change\" };\n\t\tlet startEvent = { type: \"start\" };\n\t\tlet endEvent = { type: \"end\" };\n\t\tlet STATE = { NONE: -1, ROTATE: 0, DOLLY: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_DOLLY: 4, TOUCH_PAN: 5 };\n\t\tlet state = STATE.NONE;\n\t\tlet EPS = 0.000001;\n\t\t// current position in spherical coordinates\n\t\tlet spherical = new THREE.Spherical();\n\t\tlet sphericalDelta = new THREE.Spherical();\n\t\tlet scale = 1;\n\t\tlet panOffset = new THREE.Vector3();\n\t\tlet zoomChanged = false;\n\t\tlet rotateStart = new THREE.Vector2();\n\t\tlet rotateEnd = new THREE.Vector2();\n\t\tlet rotateDelta = new THREE.Vector2();\n\t\tlet panStart = new THREE.Vector2();\n\t\tlet panEnd = new THREE.Vector2();\n\t\tlet panDelta = new THREE.Vector2();\n\t\tlet dollyStart = new THREE.Vector2();\n\t\tlet dollyEnd = new THREE.Vector2();\n\t\tlet dollyDelta = new THREE.Vector2();\n\t\tfunction getAutoRotationAngle() {\n\t\t\treturn 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n\t\t}\n\t\tfunction getZoomScale() {\n\t\t\treturn Math.pow(0.95, scope.zoomSpeed);\n\t\t}\n\t\tfunction rotateLeft(angle) {\n\t\t\tsphericalDelta.theta -= angle;\n\t\t}\n\t\tfunction rotateUp(angle) {\n\t\t\tsphericalDelta.phi -= angle;\n\t\t}\n\t\tlet panLeft = function () {\n\t\t\tlet v = new THREE.Vector3();\n\t\t\treturn function panLeft(distance, objectMatrix) {\n\t\t\t\tv.setFromMatrixColumn(objectMatrix, 0); // get X column of objectMatrix\n\t\t\t\tv.multiplyScalar(-distance);\n\t\t\t\tpanOffset.add(v);\n\t\t\t};\n\t\t}();\n\t\tlet panUp = function () {\n\t\t\tlet v = new THREE.Vector3();\n\t\t\treturn function panUp(distance, objectMatrix) {\n\t\t\t\tv.setFromMatrixColumn(objectMatrix, 1); // get Y column of objectMatrix\n\t\t\t\tv.multiplyScalar(distance);\n\t\t\t\tpanOffset.add(v);\n\t\t\t};\n\t\t}();\n\t\t// deltaX and deltaY are in pixels; right and down are positive\n\t\tlet pan = function () {\n\t\t\tlet offset = new THREE.Vector3();\n\t\t\treturn function pan(deltaX, deltaY) {\n\t\t\t\tlet element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\t\t\t\tif (scope.object instanceof THREE.PerspectiveCamera) {\n\t\t\t\t\t// perspective\n\t\t\t\t\tlet position = scope.object.position;\n\t\t\t\t\toffset.copy(position).sub(scope.target);\n\t\t\t\t\tlet targetDistance = offset.length();\n\t\t\t\t\t// half of the fov is center to top of screen\n\t\t\t\t\ttargetDistance *= Math.tan((scope.object.fov / 2) * Math.PI / 180.0);\n\t\t\t\t\t// we actually don't use screenWidth, since perspective camera is fixed to screen height\n\t\t\t\t\tpanLeft(2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix);\n\t\t\t\t\tpanUp(2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix);\n\t\t\t\t}\n\t\t\t\telse if (scope.object instanceof THREE.OrthographicCamera) {\n\t\t\t\t\t// orthographic\n\t\t\t\t\tpanLeft(deltaX * (scope.object.right - scope.object.left) / scope.object.zoom / element.clientWidth, scope.object.matrix);\n\t\t\t\t\tpanUp(deltaY * (scope.object.top - scope.object.bottom) / scope.object.zoom / element.clientHeight, scope.object.matrix);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t// camera neither orthographic nor perspective\n\t\t\t\t\tconsole.warn(\"WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.\");\n\t\t\t\t\tscope.enablePan = false;\n\t\t\t\t}\n\t\t\t};\n\t\t}();\n\t\tfunction dollyIn(dollyScale) {\n\t\t\tif (scope.object instanceof THREE.PerspectiveCamera) {\n\t\t\t\tscale /= dollyScale;\n\t\t\t}\n\t\t\telse if (scope.object instanceof THREE.OrthographicCamera) {\n\t\t\t\tscope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom * dollyScale));\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tconsole.warn(\"WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.\");\n\t\t\t\tscope.enableZoom = false;\n\t\t\t}\n\t\t}\n\t\tfunction dollyOut(dollyScale) {\n\t\t\tif (scope.object instanceof THREE.PerspectiveCamera) {\n\t\t\t\tscale *= dollyScale;\n\t\t\t}\n\t\t\telse if (scope.object instanceof THREE.OrthographicCamera) {\n\t\t\t\tscope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom / dollyScale));\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tconsole.warn(\"WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.\");\n\t\t\t\tscope.enableZoom = false;\n\t\t\t}\n\t\t}\n\t\t//\n\t\t// event callbacks - update the object state\n\t\t//\n\t\tfunction handleMouseDownRotate(event) {\n\t\t\trotateStart.set(event.clientX, event.clientY);\n\t\t}\n\t\tfunction handleMouseDownDolly(event) {\n\t\t\tdollyStart.set(event.clientX, event.clientY);\n\t\t}\n\t\tfunction handleMouseDownPan(event) {\n\t\t\tpanStart.set(event.clientX, event.clientY);\n\t\t}\n\t\tfunction handleMouseMoveRotate(event) {\n\t\t\trotateEnd.set(event.clientX, event.clientY);\n\t\t\trotateDelta.subVectors(rotateEnd, rotateStart);\n\t\t\tlet element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft(2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed);\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed);\n\t\t\trotateStart.copy(rotateEnd);\n\t\t\tscope.update();\n\t\t}\n\t\tfunction handleMouseMoveDolly(event) {\n\t\t\tdollyEnd.set(event.clientX, event.clientY);\n\t\t\tdollyDelta.subVectors(dollyEnd, dollyStart);\n\t\t\tif (dollyDelta.y > 0) {\n\t\t\t\tdollyIn(getZoomScale());\n\t\t\t}\n\t\t\telse if (dollyDelta.y < 0) {\n\t\t\t\tdollyOut(getZoomScale());\n\t\t\t}\n\t\t\tdollyStart.copy(dollyEnd);\n\t\t\tscope.update();\n\t\t}\n\t\tfunction handleMouseMovePan(event) {\n\t\t\tpanEnd.set(event.clientX, event.clientY);\n\t\t\tpanDelta.subVectors(panEnd, panStart);\n\t\t\tpan(panDelta.x, panDelta.y);\n\t\t\tpanStart.copy(panEnd);\n\t\t\tscope.update();\n\t\t}\n\t\tfunction handleMouseUp(event) {\n\t\t}\n\t\tfunction handleMouseWheel(event) {\n\t\t\tif (event.deltaY < 0) {\n\t\t\t\tdollyOut(getZoomScale());\n\t\t\t}\n\t\t\telse if (event.deltaY > 0) {\n\t\t\t\tdollyIn(getZoomScale());\n\t\t\t}\n\t\t\tscope.update();\n\t\t}\n\t\tfunction handleKeyDown(event) {\n\t\t\tswitch (event.keyCode) {\n\t\t\t\tcase scope.keys.UP:\n\t\t\t\t\tpan(0, scope.keyPanSpeed);\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\t\t\t\tcase scope.keys.BOTTOM:\n\t\t\t\t\tpan(0, -scope.keyPanSpeed);\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\t\t\t\tcase scope.keys.LEFT:\n\t\t\t\t\tpan(scope.keyPanSpeed, 0);\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\t\t\t\tcase scope.keys.RIGHT:\n\t\t\t\t\tpan(-scope.keyPanSpeed, 0);\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tfunction handleTouchStartRotate(event) {\n\t\t\trotateStart.set(event.touches[0].pageX, event.touches[0].pageY);\n\t\t}\n\t\tfunction handleTouchStartDolly(event) {\n\t\t\tlet dx = event.touches[0].pageX - event.touches[1].pageX;\n\t\t\tlet dy = event.touches[0].pageY - event.touches[1].pageY;\n\t\t\tlet distance = Math.sqrt(dx * dx + dy * dy);\n\t\t\tdollyStart.set(0, distance);\n\t\t}\n\t\tfunction handleTouchStartPan(event) {\n\t\t\tpanStart.set(event.touches[0].pageX, event.touches[0].pageY);\n\t\t}\n\t\tfunction handleTouchMoveRotate(event) {\n\t\t\trotateEnd.set(event.touches[0].pageX, event.touches[0].pageY);\n\t\t\trotateDelta.subVectors(rotateEnd, rotateStart);\n\t\t\tlet element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\t\t\trotateLeft(2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed);\n\t\t\trotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed);\n\t\t\trotateStart.copy(rotateEnd);\n\t\t\tscope.update();\n\t\t}\n\t\tfunction handleTouchMoveDolly(event) {\n\t\t\tlet dx = event.touches[0].pageX - event.touches[1].pageX;\n\t\t\tlet dy = event.touches[0].pageY - event.touches[1].pageY;\n\t\t\tlet distance = Math.sqrt(dx * dx + dy * dy);\n\t\t\tdollyEnd.set(0, distance);\n\t\t\tdollyDelta.subVectors(dollyEnd, dollyStart);\n\t\t\tif (dollyDelta.y > 0) {\n\t\t\t\tdollyOut(getZoomScale());\n\t\t\t}\n\t\t\telse if (dollyDelta.y < 0) {\n\t\t\t\tdollyIn(getZoomScale());\n\t\t\t}\n\t\t\tdollyStart.copy(dollyEnd);\n\t\t\tscope.update();\n\t\t}\n\t\tfunction handleTouchMovePan(event) {\n\t\t\tpanEnd.set(event.touches[0].pageX, event.touches[0].pageY);\n\t\t\tpanDelta.subVectors(panEnd, panStart);\n\t\t\tpan(panDelta.x, panDelta.y);\n\t\t\tpanStart.copy(panEnd);\n\t\t\tscope.update();\n\t\t}\n\t\tfunction handleTouchEnd(event) {\n\t\t}\n\t\t//\n\t\t// event handlers - FSM: listen for events and reset state\n\t\t//\n\t\tfunction onMouseDown(event) {\n\t\t\tif (scope.enabled === false)\n\t\t\t\treturn;\n\t\t\tswitch (event.button) {\n\t\t\t\tcase scope.mouseButtons.ORBIT:\n\t\t\t\t\tif (scope.enableRotate === false)\n\t\t\t\t\t\treturn;\n\t\t\t\t\thandleMouseDownRotate(event);\n\t\t\t\t\tstate = STATE.ROTATE;\n\t\t\t\t\tbreak;\n\t\t\t\tcase scope.mouseButtons.ZOOM:\n\t\t\t\t\tif (scope.enableZoom === false)\n\t\t\t\t\t\treturn;\n\t\t\t\t\thandleMouseDownDolly(event);\n\t\t\t\t\tstate = STATE.DOLLY;\n\t\t\t\t\tbreak;\n\t\t\t\tcase scope.mouseButtons.PAN:\n\t\t\t\t\tif (scope.enablePan === false)\n\t\t\t\t\t\treturn;\n\t\t\t\t\thandleMouseDownPan(event);\n\t\t\t\t\tstate = STATE.PAN;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tevent.preventDefault();\n\t\t\tif (state !== STATE.NONE) {\n\t\t\t\tdocument.addEventListener(\"mousemove\", onMouseMove, false);\n\t\t\t\tdocument.addEventListener(\"mouseup\", onMouseUp, false);\n\t\t\t\tscope.dispatchEvent(startEvent);\n\t\t\t}\n\t\t}\n\t\tfunction onMouseMove(event) {\n\t\t\tif (scope.enabled === false)\n\t\t\t\treturn;\n\t\t\tswitch (state) {\n\t\t\t\tcase STATE.ROTATE:\n\t\t\t\t\tif (scope.enableRotate === false)\n\t\t\t\t\t\treturn;\n\t\t\t\t\thandleMouseMoveRotate(event);\n\t\t\t\t\tbreak;\n\t\t\t\tcase STATE.DOLLY:\n\t\t\t\t\tif (scope.enableZoom === false)\n\t\t\t\t\t\treturn;\n\t\t\t\t\thandleMouseMoveDolly(event);\n\t\t\t\t\tbreak;\n\t\t\t\tcase STATE.PAN:\n\t\t\t\t\tif (scope.enablePan === false)\n\t\t\t\t\t\treturn;\n\t\t\t\t\thandleMouseMovePan(event);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tevent.preventDefault();\n\t\t}\n\t\tfunction onMouseUp(event) {\n\t\t\tif (scope.enabled === false)\n\t\t\t\treturn;\n\t\t\thandleMouseUp(event);\n\t\t\tdocument.removeEventListener(\"mousemove\", onMouseMove, false);\n\t\t\tdocument.removeEventListener(\"mouseup\", onMouseUp, false);\n\t\t\tscope.dispatchEvent(endEvent);\n\t\t\tstate = STATE.NONE;\n\t\t}\n\t\tfunction onMouseWheel(event) {\n\t\t\tif (scope.enabled === false || scope.enableZoom === false || (state !== STATE.NONE && state !== STATE.ROTATE))\n\t\t\t\treturn;\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t\thandleMouseWheel(event);\n\t\t\tscope.dispatchEvent(startEvent); // not sure why these are here...\n\t\t\tscope.dispatchEvent(endEvent);\n\t\t}\n\t\tfunction onKeyDown(event) {\n\t\t\tif (scope.enabled === false || scope.enableKeys === false || scope.enablePan === false)\n\t\t\t\treturn;\n\t\t\thandleKeyDown(event);\n\t\t}\n\t\tfunction onTouchStart(event) {\n\t\t\tif (scope.enabled === false)\n\t\t\t\treturn;\n\t\t\tswitch (event.touches.length) {\n\t\t\t\tcase 1:// one-fingered touch: rotate\n\t\t\t\t\tif (scope.enableRotate === false)\n\t\t\t\t\t\treturn;\n\t\t\t\t\thandleTouchStartRotate(event);\n\t\t\t\t\tstate = STATE.TOUCH_ROTATE;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:// two-fingered touch: dolly\n\t\t\t\t\tif (scope.enableZoom === false)\n\t\t\t\t\t\treturn;\n\t\t\t\t\thandleTouchStartDolly(event);\n\t\t\t\t\tstate = STATE.TOUCH_DOLLY;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 3:// three-fingered touch: pan\n\t\t\t\t\tif (scope.enablePan === false)\n\t\t\t\t\t\treturn;\n\t\t\t\t\thandleTouchStartPan(event);\n\t\t\t\t\tstate = STATE.TOUCH_PAN;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tstate = STATE.NONE;\n\t\t\t}\n\t\t\tif (state !== STATE.NONE) {\n\t\t\t\tscope.dispatchEvent(startEvent);\n\t\t\t}\n\t\t}\n\t\tfunction onTouchMove(event) {\n\t\t\tif (scope.enabled === false)\n\t\t\t\treturn;\n\t\t\tswitch (event.touches.length) {\n\t\t\t\tcase 1:// one-fingered touch: rotate\n\t\t\t\t\tif (scope.enableRotate === false)\n\t\t\t\t\t\treturn;\n\t\t\t\t\tif (state !== STATE.TOUCH_ROTATE)\n\t\t\t\t\t\treturn; // is this needed?...\n\t\t\t\t\thandleTouchMoveRotate(event);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:// two-fingered touch: dolly\n\t\t\t\t\tif (scope.enableZoom === false)\n\t\t\t\t\t\treturn;\n\t\t\t\t\tif (state !== STATE.TOUCH_DOLLY)\n\t\t\t\t\t\treturn; // is this needed?...\n\t\t\t\t\thandleTouchMoveDolly(event);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 3:// three-fingered touch: pan\n\t\t\t\t\tif (scope.enablePan === false)\n\t\t\t\t\t\treturn;\n\t\t\t\t\tif (state !== STATE.TOUCH_PAN)\n\t\t\t\t\t\treturn; // is this needed?...\n\t\t\t\t\thandleTouchMovePan(event);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tstate = STATE.NONE;\n\t\t\t}\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t}\n\t\tfunction onTouchEnd(event) {\n\t\t\tif (scope.enabled === false)\n\t\t\t\treturn;\n\t\t\thandleTouchEnd(event);\n\t\t\tscope.dispatchEvent(endEvent);\n\t\t\tstate = STATE.NONE;\n\t\t}\n\t\tfunction onContextMenu(event) {\n\t\t\tif (scope.enabled === false || scope.enablePan === false)\n\t\t\t\treturn;\n\t\t\tevent.preventDefault();\n\t\t}\n\t\t//\n\t\tscope.domElement.addEventListener(\"contextmenu\", onContextMenu, false);\n\t\tscope.domElement.addEventListener(\"mousedown\", onMouseDown, false);\n\t\tscope.domElement.addEventListener(\"wheel\", onMouseWheel, false);\n\t\tscope.domElement.addEventListener(\"touchstart\", onTouchStart, false);\n\t\tscope.domElement.addEventListener(\"touchend\", onTouchEnd, false);\n\t\tscope.domElement.addEventListener(\"touchmove\", onTouchMove, false);\n\t\twindow.addEventListener(\"keydown\", onKeyDown, false);\n\t\t// force an update at start\n\t\tthis.update();\n\t}\n}\n\nfunction createOrbitControls(skinViewer) {\n\tlet control = new OrbitControls(skinViewer.camera, skinViewer.renderer.domElement);\n\n\t// default configuration\n\tcontrol.enablePan = false;\n\tcontrol.target = new THREE.Vector3(0, -12, 0);\n\tcontrol.minDistance = 10;\n\tcontrol.maxDistance = 256;\n\tcontrol.update();\n\n\treturn control;\n}\n\nexport { OrbitControls, createOrbitControls };\n"],"names":["toFaceVertices","x1","y1","x2","y2","w","h","THREE","toSkinVertices","toCapeVertices","addVertices","box","top","bottom","left","front","right","back","faceVertexUvs","esp","SkinObject","slim","layer1Material","layer2Material","head","headBox","headMesh","add","head2Box","head2Mesh","renderOrder","_this","body","bodyBox","bodyMesh","body2Box","body2Mesh","position","y","rightArm","rightArmPivot","rightArmBox","rightArmMesh","rightArm2Box","rightArm2Mesh","x","leftArm","leftArmPivot","leftArmBox","leftArmMesh","leftArm2Box","leftArm2Mesh","rightLeg","rightLegPivot","rightLegBox","rightLegMesh","rightLeg2Box","rightLeg2Mesh","leftLeg","leftLegPivot","leftLegBox","leftLegMesh","leftLeg2Box","leftLeg2Mesh","CapeObject","capeMaterial","capeBox","cape","z","_this2","PlayerObject","skin","visible","_this3","rotation","Math","PI","invokeAnimation","animation","player","time","CompositeAnimation","play","Function","AnimationHandle","paused","this","_paused","speed","_speed","_lastChange","_lastChangeX","dt","handles","Set","handle","remove","delete","forEach","SkinViewer","options","domElement","animationPaused","animationTime","disposed","skinImg","Image","skinCanvas","document","createElement","skinTexture","magFilter","minFilter","capeImg","capeCanvas","capeTexture","map","side","transparent","opacity","scene","camera","renderer","angleRot","alpha","antialias","setSize","context","getShaderInfoLog","appendChild","playerObject","crossOrigin","onerror","console","error","src","onload","isOldFormat","width","height","skinContext","getContext","clearRect","drawImage","scale","copySkin","sX","sY","dX","dY","flipHorizontal","imgData","getImageData","index","index2","pA1","data","pA2","pA3","pA4","pB1","pB2","pB3","pB4","putImageData","copyImage","needsUpdate","capeContext","skinUrl","capeUrl","draw","requestAnimationFrame","render","aspect","updateProjectionMatrix","removeChild","dispose","url","getSize","newWidth","newHeight","OrbitControls","object","offset","quat","quatInverse","lastPosition","lastQuaternion","undefined","enabled","target","minDistance","maxDistance","Infinity","minZoom","maxZoom","minPolarAngle","maxPolarAngle","minAzimuthAngle","maxAzimuthAngle","enableDamping","dampingFactor","enableZoom","zoomSpeed","enableRotate","rotateSpeed","enablePan","keyPanSpeed","autoRotate","autoRotateSpeed","enableKeys","keys","LEFT","UP","RIGHT","BOTTOM","mouseButtons","ORBIT","ZOOM","MIDDLE","PAN","target0","clone","position0","zoom0","zoom","getPolarAngle","spherical","phi","getAzimuthalAngle","theta","saveState","copy","scope","reset","dispatchEvent","changeEvent","update","STATE","NONE","setFromUnitVectors","up","inverse","sub","applyQuaternion","setFromVector3","state","sphericalDelta","max","min","makeSafe","radius","panOffset","setFromSpherical","lookAt","set","zoomChanged","distanceToSquared","EPS","dot","quaternion","removeEventListener","onContextMenu","onMouseDown","onMouseWheel","onTouchStart","onTouchEnd","onTouchMove","onMouseMove","onMouseUp","onKeyDown","type","startEvent","endEvent","ROTATE","DOLLY","TOUCH_ROTATE","TOUCH_DOLLY","TOUCH_PAN","rotateStart","rotateEnd","rotateDelta","panStart","panEnd","panDelta","dollyStart","dollyEnd","dollyDelta","getZoomScale","pow","rotateLeft","angle","rotateUp","v","panLeft","distance","objectMatrix","setFromMatrixColumn","multiplyScalar","panUp","pan","deltaX","deltaY","element","targetDistance","length","tan","fov","clientHeight","matrix","clientWidth","warn","dollyIn","dollyScale","dollyOut","event","button","clientX","clientY","preventDefault","addEventListener","subVectors","stopPropagation","keyCode","touches","pageX","pageY","dx","dy","sqrt","skinViewer","control","sin","basicArmRotationZ","cos","basicCapeRotationX"],"mappings":"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"}
\ No newline at end of file