Bläddra i källkod

Reverted TrackballControls changes.

Is as it was before, but I implemented the event dispatching in a different way (checking the distance of the object position between frames). Also renamed the 'update' event to 'change'.

controls.addEventListener( 'change', render );

Right now only misc_camera_trackball.html uses this.
Mr.doob 13 år sedan
förälder
incheckning
a48864b47a

+ 8 - 8
build/Three.js

@@ -520,14 +520,14 @@ this.object.matrix.n24=this.object.position.y;this.object.matrix.n34=this.object
 a;this.object.position.y-=this.object.matrix.n23*a;this.object.position.z-=this.object.matrix.n33*a};this.rotateHorizontally=function(a){c.set(this.object.matrix.n11,this.object.matrix.n21,this.object.matrix.n31);c.multiplyScalar(a);this.forward.subSelf(c);this.forward.normalize()};this.rotateVertically=function(a){d.set(this.object.matrix.n12,this.object.matrix.n22,this.object.matrix.n32);d.multiplyScalar(a);this.forward.addSelf(d);this.forward.normalize()};this.domElement.addEventListener("contextmenu",
 function(a){a.preventDefault()},!1);this.domElement.addEventListener("mousemove",function(a){p=(a.clientX-n)/window.innerWidth;o=(a.clientY-q)/window.innerHeight},!1);this.domElement.addEventListener("mousedown",function(a){a.preventDefault();a.stopPropagation();switch(a.button){case 0:i=1;break;case 2:i=-1}},!1);this.domElement.addEventListener("mouseup",function(a){a.preventDefault();a.stopPropagation();switch(a.button){case 0:i=0;break;case 2:i=0}},!1);this.domElement.addEventListener("keydown",
 function(a){switch(a.keyCode){case 38:case 87:i=1;break;case 37:case 65:l=-1;break;case 40:case 83:i=-1;break;case 39:case 68:l=1;break;case 81:f=!0;h=1;break;case 69:f=!0;h=-1;break;case 82:k=1;break;case 70:k=-1}},!1);this.domElement.addEventListener("keyup",function(a){switch(a.keyCode){case 38:case 87:i=0;break;case 37:case 65:l=0;break;case 40:case 83:i=0;break;case 39:case 68:l=0;break;case 81:f=!1;break;case 69:f=!1;break;case 82:k=0;break;case 70:k=0}},!1)};
-THREE.TrackballControls=function(a,b){function c(){f.copy(d.object.position).subSelf(d.target);d.noRotate||d.rotateCamera();d.noZoom||d.zoomCamera();d.noPan||d.panCamera();d.object.position.add(d.target,f);d.checkDistances();d.object.lookAt(d.target);d.dispatchEvent({type:"update"})}THREE.EventTarget.call(this);var d=this;this.object=a;this.domElement=void 0!==b?b:document;this.enabled=!0;this.screen={width:window.innerWidth,height:window.innerHeight,offsetLeft:0,offsetTop:0};this.radius=(this.screen.width+
-this.screen.height)/4;this.rotateSpeed=1;this.zoomSpeed=1.2;this.panSpeed=0.3;this.staticMoving=this.noPan=this.noZoom=this.noRotate=!1;this.dynamicDampingFactor=0.2;this.minDistance=0;this.maxDistance=Infinity;this.keys=[65,83,68];this.target=new THREE.Vector3(0,0,0);var e=!1,g=-1,f=new THREE.Vector3,h=new THREE.Vector3,i=new THREE.Vector3,l=new THREE.Vector2,k=new THREE.Vector2,p=new THREE.Vector2,o=new THREE.Vector2;this.handleEvent=function(a){if("function"==typeof this[a.type])this[a.type](a)};
-this.getMouseOnScreen=function(a,b){return new THREE.Vector2(0.5*((a-d.screen.offsetLeft)/d.radius),0.5*((b-d.screen.offsetTop)/d.radius))};this.getMouseProjectionOnBall=function(a,b){var c=new THREE.Vector3((a-0.5*d.screen.width-d.screen.offsetLeft)/d.radius,(0.5*d.screen.height+d.screen.offsetTop-b)/d.radius,0),e=c.length();1<e?c.normalize():c.z=Math.sqrt(1-e*e);f.copy(d.object.position).subSelf(d.target);e=d.object.up.clone().setLength(c.y);e.addSelf(d.object.up.clone().crossSelf(f).setLength(c.x));
-e.addSelf(f.setLength(c.z));return e};this.rotateCamera=function(){var a=Math.acos(h.dot(i)/h.length()/i.length());if(a){var b=(new THREE.Vector3).cross(h,i).normalize(),c=new THREE.Quaternion,a=a*d.rotateSpeed;c.setFromAxisAngle(b,-a);c.multiplyVector3(f);c.multiplyVector3(d.object.up);c.multiplyVector3(i);d.staticMoving?h=i:(c.setFromAxisAngle(b,a*(d.dynamicDampingFactor-1)),c.multiplyVector3(h))}};this.zoomCamera=function(){var a=1+(k.y-l.y)*d.zoomSpeed;1!==a&&0<a&&(f.multiplyScalar(a),d.staticMoving?
-l=k:l.y+=(k.y-l.y)*this.dynamicDampingFactor)};this.panCamera=function(){var a=o.clone().subSelf(p);if(a.lengthSq()){a.multiplyScalar(f.length()*d.panSpeed);var b=f.clone().crossSelf(d.object.up).setLength(a.x);b.addSelf(d.object.up.clone().setLength(a.y));d.object.position.addSelf(b);d.target.addSelf(b);d.staticMoving?p=o:p.addSelf(a.sub(o,p).multiplyScalar(d.dynamicDampingFactor))}};this.checkDistances=function(){if(!d.noZoom||!d.noPan)d.object.position.lengthSq()>d.maxDistance*d.maxDistance&&d.object.position.setLength(d.maxDistance),
-f.lengthSq()<d.minDistance*d.minDistance&&d.object.position.add(d.target,f.setLength(d.minDistance))};this.domElement.addEventListener("contextmenu",function(a){a.preventDefault()},!1);this.domElement.addEventListener("mousemove",function(a){d.enabled&&(e&&(h=i=d.getMouseProjectionOnBall(a.clientX,a.clientY),l=k=d.getMouseOnScreen(a.clientX,a.clientY),p=o=d.getMouseOnScreen(a.clientX,a.clientY),e=!1),-1!==g&&(0===g&&!d.noRotate?i=d.getMouseProjectionOnBall(a.clientX,a.clientY):1===g&&!d.noZoom?k=
-d.getMouseOnScreen(a.clientX,a.clientY):2===g&&!d.noPan&&(o=d.getMouseOnScreen(a.clientX,a.clientY)),c()))},!1);this.domElement.addEventListener("mousedown",function(a){if(d.enabled&&(a.preventDefault(),a.stopPropagation(),-1===g))g=a.button,0===g&&!d.noRotate?h=i=d.getMouseProjectionOnBall(a.clientX,a.clientY):1===g&&!d.noZoom?l=k=d.getMouseOnScreen(a.clientX,a.clientY):this.noPan||(p=o=d.getMouseOnScreen(a.clientX,a.clientY))},!1);this.domElement.addEventListener("mouseup",function(a){d.enabled&&
-(a.preventDefault(),a.stopPropagation(),g=-1)},!1);window.addEventListener("keydown",function(a){d.enabled&&-1===g&&(a.keyCode===d.keys[0]&&!d.noRotate?g=0:a.keyCode===d.keys[1]&&!d.noZoom?g=1:a.keyCode===d.keys[2]&&!d.noPan&&(g=2),-1!==g&&(e=!0))},!1);window.addEventListener("keyup",function(){d.enabled&&-1!==g&&(g=-1)},!1);c()};
+THREE.TrackballControls=function(a,b){THREE.EventTarget.call(this);var c=this;this.object=a;this.domElement=void 0!==b?b:document;this.enabled=!0;this.screen={width:window.innerWidth,height:window.innerHeight,offsetLeft:0,offsetTop:0};this.radius=(this.screen.width+this.screen.height)/4;this.rotateSpeed=1;this.zoomSpeed=1.2;this.panSpeed=0.3;this.staticMoving=this.noPan=this.noZoom=this.noRotate=!1;this.dynamicDampingFactor=0.2;this.minDistance=0;this.maxDistance=Infinity;this.keys=[65,83,68];this.target=
+new THREE.Vector3;var d=new THREE.Vector3,e=!1,g=-1,f=new THREE.Vector3,h=new THREE.Vector3,i=new THREE.Vector3,l=new THREE.Vector2,k=new THREE.Vector2,p=new THREE.Vector2,o=new THREE.Vector2;this.handleEvent=function(a){if("function"==typeof this[a.type])this[a.type](a)};this.getMouseOnScreen=function(a,b){return new THREE.Vector2(0.5*((a-c.screen.offsetLeft)/c.radius),0.5*((b-c.screen.offsetTop)/c.radius))};this.getMouseProjectionOnBall=function(a,b){var d=new THREE.Vector3((a-0.5*c.screen.width-
+c.screen.offsetLeft)/c.radius,(0.5*c.screen.height+c.screen.offsetTop-b)/c.radius,0),e=d.length();1<e?d.normalize():d.z=Math.sqrt(1-e*e);f.copy(c.object.position).subSelf(c.target);e=c.object.up.clone().setLength(d.y);e.addSelf(c.object.up.clone().crossSelf(f).setLength(d.x));e.addSelf(f.setLength(d.z));return e};this.rotateCamera=function(){var a=Math.acos(h.dot(i)/h.length()/i.length());if(a){var b=(new THREE.Vector3).cross(h,i).normalize(),d=new THREE.Quaternion,a=a*c.rotateSpeed;d.setFromAxisAngle(b,
+-a);d.multiplyVector3(f);d.multiplyVector3(c.object.up);d.multiplyVector3(i);c.staticMoving?h=i:(d.setFromAxisAngle(b,a*(c.dynamicDampingFactor-1)),d.multiplyVector3(h))}};this.zoomCamera=function(){var a=1+(k.y-l.y)*c.zoomSpeed;1!==a&&0<a&&(f.multiplyScalar(a),c.staticMoving?l=k:l.y+=(k.y-l.y)*this.dynamicDampingFactor)};this.panCamera=function(){var a=o.clone().subSelf(p);if(a.lengthSq()){a.multiplyScalar(f.length()*c.panSpeed);var b=f.clone().crossSelf(c.object.up).setLength(a.x);b.addSelf(c.object.up.clone().setLength(a.y));
+c.object.position.addSelf(b);c.target.addSelf(b);c.staticMoving?p=o:p.addSelf(a.sub(o,p).multiplyScalar(c.dynamicDampingFactor))}};this.checkDistances=function(){if(!c.noZoom||!c.noPan)c.object.position.lengthSq()>c.maxDistance*c.maxDistance&&c.object.position.setLength(c.maxDistance),f.lengthSq()<c.minDistance*c.minDistance&&c.object.position.add(c.target,f.setLength(c.minDistance))};this.update=function(){f.copy(c.object.position).subSelf(c.target);c.noRotate||c.rotateCamera();c.noZoom||c.zoomCamera();
+c.noPan||c.panCamera();c.object.position.add(c.target,f);c.checkDistances();c.object.lookAt(c.target);0<d.distanceTo(c.object.position)&&(c.dispatchEvent({type:"change"}),d.copy(c.object.position))};this.domElement.addEventListener("contextmenu",function(a){a.preventDefault()},!1);this.domElement.addEventListener("mousemove",function(a){c.enabled&&(e&&(h=i=c.getMouseProjectionOnBall(a.clientX,a.clientY),l=k=c.getMouseOnScreen(a.clientX,a.clientY),p=o=c.getMouseOnScreen(a.clientX,a.clientY),e=!1),
+-1!==g&&(0===g&&!c.noRotate?i=c.getMouseProjectionOnBall(a.clientX,a.clientY):1===g&&!c.noZoom?k=c.getMouseOnScreen(a.clientX,a.clientY):2===g&&!c.noPan&&(o=c.getMouseOnScreen(a.clientX,a.clientY))))},!1);this.domElement.addEventListener("mousedown",function(a){if(c.enabled&&(a.preventDefault(),a.stopPropagation(),-1===g))g=a.button,0===g&&!c.noRotate?h=i=c.getMouseProjectionOnBall(a.clientX,a.clientY):1===g&&!c.noZoom?l=k=c.getMouseOnScreen(a.clientX,a.clientY):this.noPan||(p=o=c.getMouseOnScreen(a.clientX,
+a.clientY))},!1);this.domElement.addEventListener("mouseup",function(a){c.enabled&&(a.preventDefault(),a.stopPropagation(),g=-1)},!1);window.addEventListener("keydown",function(a){c.enabled&&-1===g&&(a.keyCode===c.keys[0]&&!c.noRotate?g=0:a.keyCode===c.keys[1]&&!c.noZoom?g=1:a.keyCode===c.keys[2]&&!c.noPan&&(g=2),-1!==g&&(e=!0))},!1);window.addEventListener("keyup",function(){c.enabled&&-1!==g&&(g=-1)},!1)};
 THREE.CubeGeometry=function(a,b,c,d,e,g,f,h){function i(a,b,c,f,h,i,m,k){var n,o=d||1,p=e||1,q=h/2,r=i/2,s=l.vertices.length;if("x"===a&&"y"===b||"y"===a&&"x"===b)n="z";else if("x"===a&&"z"===b||"z"===a&&"x"===b)n="y",p=g||1;else if("z"===a&&"y"===b||"y"===a&&"z"===b)n="x",o=g||1;var j=o+1,t=p+1,w=h/o,E=i/p,Y=new THREE.Vector3;Y[n]=0<m?1:-1;for(h=0;h<t;h++)for(i=0;i<j;i++){var O=new THREE.Vector3;O[a]=(i*w-q)*c;O[b]=(h*E-r)*f;O[n]=m;l.vertices.push(new THREE.Vertex(O))}for(h=0;h<p;h++)for(i=0;i<o;i++)a=
 new THREE.Face4(i+j*h+s,i+j*(h+1)+s,i+1+j*(h+1)+s,i+1+j*h+s),a.normal.copy(Y),a.vertexNormals.push(Y.clone(),Y.clone(),Y.clone(),Y.clone()),a.materialIndex=k,l.faces.push(a),l.faceVertexUvs[0].push([new THREE.UV(i/o,h/p),new THREE.UV(i/o,(h+1)/p),new THREE.UV((i+1)/o,(h+1)/p),new THREE.UV((i+1)/o,h/p)])}THREE.Geometry.call(this);var l=this,k=a/2,p=b/2,o=c/2,n,q,m,r,s,t;if(void 0!==f){if(f instanceof Array)this.materials=f;else{this.materials=[];for(n=0;6>n;n++)this.materials.push(f)}n=0;r=1;q=2;s=
 3;m=4;t=5}else this.materials=[];this.sides={px:!0,nx:!0,py:!0,ny:!0,pz:!0,nz:!0};if(void 0!=h)for(var w in h)void 0!==this.sides[w]&&(this.sides[w]=h[w]);this.sides.px&&i("z","y",-1,-1,c,b,k,n);this.sides.nx&&i("z","y",1,-1,c,b,-k,r);this.sides.py&&i("x","z",1,1,a,c,p,q);this.sides.ny&&i("x","z",1,-1,a,c,-p,s);this.sides.pz&&i("x","y",1,-1,a,b,o,m);this.sides.nz&&i("x","y",-1,-1,a,b,-o,t);this.computeCentroids();this.mergeVertices()};THREE.CubeGeometry.prototype=new THREE.Geometry;

+ 8 - 8
build/custom/ThreeExtras.js

@@ -151,14 +151,14 @@ this.object.matrix.n24=this.object.position.y;this.object.matrix.n34=this.object
 a;this.object.position.y-=this.object.matrix.n23*a;this.object.position.z-=this.object.matrix.n33*a};this.rotateHorizontally=function(a){c.set(this.object.matrix.n11,this.object.matrix.n21,this.object.matrix.n31);c.multiplyScalar(a);this.forward.subSelf(c);this.forward.normalize()};this.rotateVertically=function(a){d.set(this.object.matrix.n12,this.object.matrix.n22,this.object.matrix.n32);d.multiplyScalar(a);this.forward.addSelf(d);this.forward.normalize()};this.domElement.addEventListener("contextmenu",
 function(a){a.preventDefault()},!1);this.domElement.addEventListener("mousemove",function(a){q=(a.clientX-n)/window.innerWidth;l=(a.clientY-r)/window.innerHeight},!1);this.domElement.addEventListener("mousedown",function(a){a.preventDefault();a.stopPropagation();switch(a.button){case 0:i=1;break;case 2:i=-1}},!1);this.domElement.addEventListener("mouseup",function(a){a.preventDefault();a.stopPropagation();switch(a.button){case 0:i=0;break;case 2:i=0}},!1);this.domElement.addEventListener("keydown",
 function(a){switch(a.keyCode){case 38:case 87:i=1;break;case 37:case 65:j=-1;break;case 40:case 83:i=-1;break;case 39:case 68:j=1;break;case 81:e=!0;h=1;break;case 69:e=!0;h=-1;break;case 82:k=1;break;case 70:k=-1}},!1);this.domElement.addEventListener("keyup",function(a){switch(a.keyCode){case 38:case 87:i=0;break;case 37:case 65:j=0;break;case 40:case 83:i=0;break;case 39:case 68:j=0;break;case 81:e=!1;break;case 69:e=!1;break;case 82:k=0;break;case 70:k=0}},!1)};
-THREE.TrackballControls=function(a,b){function c(){e.copy(d.object.position).subSelf(d.target);d.noRotate||d.rotateCamera();d.noZoom||d.zoomCamera();d.noPan||d.panCamera();d.object.position.add(d.target,e);d.checkDistances();d.object.lookAt(d.target);d.dispatchEvent({type:"update"})}THREE.EventTarget.call(this);var d=this;this.object=a;this.domElement=void 0!==b?b:document;this.enabled=!0;this.screen={width:window.innerWidth,height:window.innerHeight,offsetLeft:0,offsetTop:0};this.radius=(this.screen.width+
-this.screen.height)/4;this.rotateSpeed=1;this.zoomSpeed=1.2;this.panSpeed=0.3;this.staticMoving=this.noPan=this.noZoom=this.noRotate=!1;this.dynamicDampingFactor=0.2;this.minDistance=0;this.maxDistance=Infinity;this.keys=[65,83,68];this.target=new THREE.Vector3(0,0,0);var f=!1,g=-1,e=new THREE.Vector3,h=new THREE.Vector3,i=new THREE.Vector3,j=new THREE.Vector2,k=new THREE.Vector2,q=new THREE.Vector2,l=new THREE.Vector2;this.handleEvent=function(a){if("function"==typeof this[a.type])this[a.type](a)};
-this.getMouseOnScreen=function(a,b){return new THREE.Vector2(0.5*((a-d.screen.offsetLeft)/d.radius),0.5*((b-d.screen.offsetTop)/d.radius))};this.getMouseProjectionOnBall=function(a,b){var c=new THREE.Vector3((a-0.5*d.screen.width-d.screen.offsetLeft)/d.radius,(0.5*d.screen.height+d.screen.offsetTop-b)/d.radius,0),f=c.length();1<f?c.normalize():c.z=Math.sqrt(1-f*f);e.copy(d.object.position).subSelf(d.target);f=d.object.up.clone().setLength(c.y);f.addSelf(d.object.up.clone().crossSelf(e).setLength(c.x));
-f.addSelf(e.setLength(c.z));return f};this.rotateCamera=function(){var a=Math.acos(h.dot(i)/h.length()/i.length());if(a){var b=(new THREE.Vector3).cross(h,i).normalize(),c=new THREE.Quaternion,a=a*d.rotateSpeed;c.setFromAxisAngle(b,-a);c.multiplyVector3(e);c.multiplyVector3(d.object.up);c.multiplyVector3(i);d.staticMoving?h=i:(c.setFromAxisAngle(b,a*(d.dynamicDampingFactor-1)),c.multiplyVector3(h))}};this.zoomCamera=function(){var a=1+(k.y-j.y)*d.zoomSpeed;1!==a&&0<a&&(e.multiplyScalar(a),d.staticMoving?
-j=k:j.y+=(k.y-j.y)*this.dynamicDampingFactor)};this.panCamera=function(){var a=l.clone().subSelf(q);if(a.lengthSq()){a.multiplyScalar(e.length()*d.panSpeed);var b=e.clone().crossSelf(d.object.up).setLength(a.x);b.addSelf(d.object.up.clone().setLength(a.y));d.object.position.addSelf(b);d.target.addSelf(b);d.staticMoving?q=l:q.addSelf(a.sub(l,q).multiplyScalar(d.dynamicDampingFactor))}};this.checkDistances=function(){if(!d.noZoom||!d.noPan)d.object.position.lengthSq()>d.maxDistance*d.maxDistance&&d.object.position.setLength(d.maxDistance),
-e.lengthSq()<d.minDistance*d.minDistance&&d.object.position.add(d.target,e.setLength(d.minDistance))};this.domElement.addEventListener("contextmenu",function(a){a.preventDefault()},!1);this.domElement.addEventListener("mousemove",function(a){d.enabled&&(f&&(h=i=d.getMouseProjectionOnBall(a.clientX,a.clientY),j=k=d.getMouseOnScreen(a.clientX,a.clientY),q=l=d.getMouseOnScreen(a.clientX,a.clientY),f=!1),-1!==g&&(0===g&&!d.noRotate?i=d.getMouseProjectionOnBall(a.clientX,a.clientY):1===g&&!d.noZoom?k=
-d.getMouseOnScreen(a.clientX,a.clientY):2===g&&!d.noPan&&(l=d.getMouseOnScreen(a.clientX,a.clientY)),c()))},!1);this.domElement.addEventListener("mousedown",function(a){if(d.enabled&&(a.preventDefault(),a.stopPropagation(),-1===g))g=a.button,0===g&&!d.noRotate?h=i=d.getMouseProjectionOnBall(a.clientX,a.clientY):1===g&&!d.noZoom?j=k=d.getMouseOnScreen(a.clientX,a.clientY):this.noPan||(q=l=d.getMouseOnScreen(a.clientX,a.clientY))},!1);this.domElement.addEventListener("mouseup",function(a){d.enabled&&
-(a.preventDefault(),a.stopPropagation(),g=-1)},!1);window.addEventListener("keydown",function(a){d.enabled&&-1===g&&(a.keyCode===d.keys[0]&&!d.noRotate?g=0:a.keyCode===d.keys[1]&&!d.noZoom?g=1:a.keyCode===d.keys[2]&&!d.noPan&&(g=2),-1!==g&&(f=!0))},!1);window.addEventListener("keyup",function(){d.enabled&&-1!==g&&(g=-1)},!1);c()};
+THREE.TrackballControls=function(a,b){THREE.EventTarget.call(this);var c=this;this.object=a;this.domElement=void 0!==b?b:document;this.enabled=!0;this.screen={width:window.innerWidth,height:window.innerHeight,offsetLeft:0,offsetTop:0};this.radius=(this.screen.width+this.screen.height)/4;this.rotateSpeed=1;this.zoomSpeed=1.2;this.panSpeed=0.3;this.staticMoving=this.noPan=this.noZoom=this.noRotate=!1;this.dynamicDampingFactor=0.2;this.minDistance=0;this.maxDistance=Infinity;this.keys=[65,83,68];this.target=
+new THREE.Vector3;var d=new THREE.Vector3,f=!1,g=-1,e=new THREE.Vector3,h=new THREE.Vector3,i=new THREE.Vector3,j=new THREE.Vector2,k=new THREE.Vector2,q=new THREE.Vector2,l=new THREE.Vector2;this.handleEvent=function(a){if("function"==typeof this[a.type])this[a.type](a)};this.getMouseOnScreen=function(a,b){return new THREE.Vector2(0.5*((a-c.screen.offsetLeft)/c.radius),0.5*((b-c.screen.offsetTop)/c.radius))};this.getMouseProjectionOnBall=function(a,b){var d=new THREE.Vector3((a-0.5*c.screen.width-
+c.screen.offsetLeft)/c.radius,(0.5*c.screen.height+c.screen.offsetTop-b)/c.radius,0),f=d.length();1<f?d.normalize():d.z=Math.sqrt(1-f*f);e.copy(c.object.position).subSelf(c.target);f=c.object.up.clone().setLength(d.y);f.addSelf(c.object.up.clone().crossSelf(e).setLength(d.x));f.addSelf(e.setLength(d.z));return f};this.rotateCamera=function(){var a=Math.acos(h.dot(i)/h.length()/i.length());if(a){var b=(new THREE.Vector3).cross(h,i).normalize(),d=new THREE.Quaternion,a=a*c.rotateSpeed;d.setFromAxisAngle(b,
+-a);d.multiplyVector3(e);d.multiplyVector3(c.object.up);d.multiplyVector3(i);c.staticMoving?h=i:(d.setFromAxisAngle(b,a*(c.dynamicDampingFactor-1)),d.multiplyVector3(h))}};this.zoomCamera=function(){var a=1+(k.y-j.y)*c.zoomSpeed;1!==a&&0<a&&(e.multiplyScalar(a),c.staticMoving?j=k:j.y+=(k.y-j.y)*this.dynamicDampingFactor)};this.panCamera=function(){var a=l.clone().subSelf(q);if(a.lengthSq()){a.multiplyScalar(e.length()*c.panSpeed);var b=e.clone().crossSelf(c.object.up).setLength(a.x);b.addSelf(c.object.up.clone().setLength(a.y));
+c.object.position.addSelf(b);c.target.addSelf(b);c.staticMoving?q=l:q.addSelf(a.sub(l,q).multiplyScalar(c.dynamicDampingFactor))}};this.checkDistances=function(){if(!c.noZoom||!c.noPan)c.object.position.lengthSq()>c.maxDistance*c.maxDistance&&c.object.position.setLength(c.maxDistance),e.lengthSq()<c.minDistance*c.minDistance&&c.object.position.add(c.target,e.setLength(c.minDistance))};this.update=function(){e.copy(c.object.position).subSelf(c.target);c.noRotate||c.rotateCamera();c.noZoom||c.zoomCamera();
+c.noPan||c.panCamera();c.object.position.add(c.target,e);c.checkDistances();c.object.lookAt(c.target);0<d.distanceTo(c.object.position)&&(c.dispatchEvent({type:"change"}),d.copy(c.object.position))};this.domElement.addEventListener("contextmenu",function(a){a.preventDefault()},!1);this.domElement.addEventListener("mousemove",function(a){c.enabled&&(f&&(h=i=c.getMouseProjectionOnBall(a.clientX,a.clientY),j=k=c.getMouseOnScreen(a.clientX,a.clientY),q=l=c.getMouseOnScreen(a.clientX,a.clientY),f=!1),
+-1!==g&&(0===g&&!c.noRotate?i=c.getMouseProjectionOnBall(a.clientX,a.clientY):1===g&&!c.noZoom?k=c.getMouseOnScreen(a.clientX,a.clientY):2===g&&!c.noPan&&(l=c.getMouseOnScreen(a.clientX,a.clientY))))},!1);this.domElement.addEventListener("mousedown",function(a){if(c.enabled&&(a.preventDefault(),a.stopPropagation(),-1===g))g=a.button,0===g&&!c.noRotate?h=i=c.getMouseProjectionOnBall(a.clientX,a.clientY):1===g&&!c.noZoom?j=k=c.getMouseOnScreen(a.clientX,a.clientY):this.noPan||(q=l=c.getMouseOnScreen(a.clientX,
+a.clientY))},!1);this.domElement.addEventListener("mouseup",function(a){c.enabled&&(a.preventDefault(),a.stopPropagation(),g=-1)},!1);window.addEventListener("keydown",function(a){c.enabled&&-1===g&&(a.keyCode===c.keys[0]&&!c.noRotate?g=0:a.keyCode===c.keys[1]&&!c.noZoom?g=1:a.keyCode===c.keys[2]&&!c.noPan&&(g=2),-1!==g&&(f=!0))},!1);window.addEventListener("keyup",function(){c.enabled&&-1!==g&&(g=-1)},!1)};
 THREE.CubeGeometry=function(a,b,c,d,f,g,e,h){function i(a,b,c,e,h,i,l,k){var m,n=d||1,q=f||1,r=h/2,o=i/2,p=j.vertices.length;if("x"===a&&"y"===b||"y"===a&&"x"===b)m="z";else if("x"===a&&"z"===b||"z"===a&&"x"===b)m="y",q=g||1;else if("z"===a&&"y"===b||"y"===a&&"z"===b)m="x",n=g||1;var s=n+1,t=q+1,D=h/n,L=i/q,N=new THREE.Vector3;N[m]=0<l?1:-1;for(h=0;h<t;h++)for(i=0;i<s;i++){var M=new THREE.Vector3;M[a]=(i*D-r)*c;M[b]=(h*L-o)*e;M[m]=l;j.vertices.push(new THREE.Vertex(M))}for(h=0;h<q;h++)for(i=0;i<n;i++)a=
 new THREE.Face4(i+s*h+p,i+s*(h+1)+p,i+1+s*(h+1)+p,i+1+s*h+p),a.normal.copy(N),a.vertexNormals.push(N.clone(),N.clone(),N.clone(),N.clone()),a.materialIndex=k,j.faces.push(a),j.faceVertexUvs[0].push([new THREE.UV(i/n,h/q),new THREE.UV(i/n,(h+1)/q),new THREE.UV((i+1)/n,(h+1)/q),new THREE.UV((i+1)/n,h/q)])}THREE.Geometry.call(this);var j=this,k=a/2,q=b/2,l=c/2,n,r,m,p,o,s;if(void 0!==e){if(e instanceof Array)this.materials=e;else{this.materials=[];for(n=0;6>n;n++)this.materials.push(e)}n=0;p=1;r=2;o=
 3;m=4;s=5}else this.materials=[];this.sides={px:!0,nx:!0,py:!0,ny:!0,pz:!0,nz:!0};if(void 0!=h)for(var t in h)void 0!==this.sides[t]&&(this.sides[t]=h[t]);this.sides.px&&i("z","y",-1,-1,c,b,k,n);this.sides.nx&&i("z","y",1,-1,c,b,-k,p);this.sides.py&&i("x","z",1,1,a,c,q,r);this.sides.ny&&i("x","z",1,-1,a,c,-q,o);this.sides.pz&&i("x","y",1,-1,a,b,l,m);this.sides.nz&&i("x","y",-1,-1,a,b,-l,s);this.computeCentroids();this.mergeVertices()};THREE.CubeGeometry.prototype=new THREE.Geometry;

+ 17 - 3
examples/misc_camera_trackball.html

@@ -40,19 +40,20 @@
 		<script src="../build/Three.js"></script>
 
 		<script src="js/Detector.js"></script>
+		<script src="js/Stats.js"></script>
 
 		<script>
 
 			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
 
-			var container;
+			var container, stats;
 
 			var camera, controls, scene, renderer;
 
 			var cross;
 
 			init();
-			render();
+			animate();
 
 			function init() {
 
@@ -80,7 +81,7 @@
 
 				controls.keys = [ 65, 83, 68 ];
 
-				controls.addEventListener( 'update', render );
+				controls.addEventListener( 'change', render );
 
 				// world
 
@@ -130,12 +131,25 @@
 				container = document.getElementById( 'container' );
 				container.appendChild( renderer.domElement );
 
+				stats = new Stats();
+				stats.domElement.style.position = 'absolute';
+				stats.domElement.style.top = '0px';
+				stats.domElement.style.zIndex = 100;
+				container.appendChild( stats.domElement );
+
+			}
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+				controls.update();
 
 			}
 
 			function render() {
 
 				renderer.render( scene, camera );
+				stats.update();
 
 			}
 

+ 27 - 10
examples/webgl_lights_pointlights2.html

@@ -79,20 +79,35 @@
 
 				// CONTROLS
 
-				controls = new THREE.TrackballControls( camera );
-				controls.target.set( 0, 0, 0 );
+				if ( 1 ) {
 
-				controls.rotateSpeed = 1.0;
-				controls.zoomSpeed = 1.2;
-				controls.panSpeed = 0.8;
+					controls = new THREE.TrackballControls( camera );
+					controls.target.set( 0, 0, 0 );
 
-				controls.noZoom = false;
-				controls.noPan = false;
+					controls.rotateSpeed = 1.0;
+					controls.zoomSpeed = 1.2;
+					controls.panSpeed = 0.8;
 
-				controls.staticMoving = false;
-				controls.dynamicDampingFactor = 0.15;
+					controls.noZoom = false;
+					controls.noPan = false;
+
+					controls.staticMoving = false;
+					controls.dynamicDampingFactor = 0.15;
+
+					controls.keys = [ 65, 83, 68 ];
+
+				} else {
+
+					controls = new THREE.FirstPersonControls( camera );
+
+					controls.movementSpeed = 25;
+					controls.lookSpeed = 0.05;
+					controls.lookVertical = true;
+
+					controls.lon = -90;
+
+				}
 
-				controls.keys = [ 65, 83, 68 ];
 
 				// TEXTURES
 
@@ -240,6 +255,8 @@
 
 			function render() {
 
+				controls.update( clock.getDelta() );
+
 				var time = Date.now() * 0.00025;
 				var z = 20, d = 150;
 

+ 29 - 9
examples/webgl_loader_ctm_materials.html

@@ -44,7 +44,8 @@
 		<script src="js/ctm/CTMLoader.js"></script>
 
 		<script src="js/Detector.js"></script>
-		
+		<script src="js/Stats.js"></script>
+
 		<script>
 
 			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
@@ -53,7 +54,7 @@
 			var SCREEN_HEIGHT = window.innerHeight;
 			var FLOOR = -250;
 
-			var container;
+			var container, stats;
 
 			var camera, scene, controls;
 			var renderer;
@@ -71,6 +72,7 @@
 			var windowHalfY = window.innerHeight / 2;
 
 			init();
+			animate();
 
 			function init() {
 
@@ -89,7 +91,7 @@
 
 				controls = new THREE.TrackballControls( camera );
 				controls.dynamicDampingFactor = 0.25;
-				controls.addEventListener( 'update', render );
+
 
 				// SKYBOX
 
@@ -103,7 +105,7 @@
 							 r + "pz.png", r + "nz.png" ];
 
 
-				textureCube = THREE.ImageUtils.loadTextureCube( urls, new THREE.UVMapping(), render );
+				textureCube = THREE.ImageUtils.loadTextureCube( urls );
 
 				var shader = THREE.ShaderUtils.lib[ "cube" ];
 				shader.uniforms[ "tCube" ].texture = textureCube;
@@ -155,6 +157,18 @@
 				renderer.gammaOutput = true;
 				renderer.physicallyBasedShading = true;
 
+				// STATS
+
+				stats = new Stats();
+				stats.domElement.style.position = 'absolute';
+				stats.domElement.style.top = '5px';
+				stats.domElement.style.zIndex = 100;
+				container.appendChild( stats.domElement );
+
+				stats.domElement.children[ 0 ].children[ 0 ].style.color = "#aaa";
+				stats.domElement.children[ 0 ].style.background = "transparent";
+				stats.domElement.children[ 0 ].children[ 1 ].style.display = "none";
+
 				// EVENTS
 
 				window.addEventListener( 'resize', onWindowResize, false );
@@ -290,8 +304,6 @@
 				mesh.scale.set( s, s, s );
 				mesh.doubleSided = true;
 				scene.add( mesh );
-	
-				render();
 
 			}
 
@@ -310,8 +322,6 @@
 				cameraCube.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
 				cameraCube.updateProjectionMatrix();
 
-				render();
-
 			}
 
 
@@ -324,15 +334,25 @@
 
 			//
 
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				render();
+				stats.update();
+
+			}
+
 			function render() {
 
+				controls.update();
+
 				cameraCube.rotation.copy( camera.rotation );
 
 				renderer.clear();
 				renderer.render( sceneCube, cameraCube );
 				renderer.render( scene, camera );
 
-
 			}
 
 		</script>

+ 2 - 2
examples/webgl_morphtargets_md2.html

@@ -381,9 +381,9 @@
 
 			function render() {
 
-				var delta = clock.getDelta();
+				controls.update();
 
-				character.update( delta );
+				character.update( clock.getDelta() );
 
 				renderer.render( scene, camera );
 

+ 1 - 0
examples/webgl_shading_physical.html

@@ -550,6 +550,7 @@
 				var delta = 1000 * clock.getDelta();
 
 				TWEEN.update();
+				controls.update();
 
 				if ( morph ) morph.updateAnimation( delta );
 

+ 2 - 0
examples/webgl_terrain_dynamic.html

@@ -683,6 +683,8 @@
 
 				if ( terrain.visible ) {
 
+					controls.update();
+
 					var time = Date.now() * 0.001;
 
 					var fLow = 0.4, fHigh = 0.825;

+ 2 - 0
examples/webgl_trackballcamera_earth.html

@@ -287,6 +287,8 @@
 				);
 				meshMoon.rotation.y -= angle;
 
+				controls.update();
+
 				renderer.clear();
 				renderer.render( scene, camera );
 

+ 41 - 40
src/extras/controls/TrackballControls.js

@@ -37,7 +37,9 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 	// internals
 
-	this.target = new THREE.Vector3( 0, 0, 0 );
+	this.target = new THREE.Vector3();
+
+	var lastPosition = new THREE.Vector3();
 
 	var _keyPressed = false,
 	_state = STATE.NONE,
@@ -208,6 +210,44 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 	};
 
+	this.update = function() {
+
+		_eye.copy( _this.object.position ).subSelf( _this.target );
+
+		if ( !_this.noRotate ) {
+
+			_this.rotateCamera();
+
+		}
+		
+		if ( !_this.noZoom ) {
+
+			_this.zoomCamera();
+
+		}
+
+		if ( !_this.noPan ) {
+
+			_this.panCamera();
+
+		}
+
+		_this.object.position.add( _this.target, _eye );
+
+		_this.checkDistances();
+
+		_this.object.lookAt( _this.target );
+
+		if ( lastPosition.distanceTo( _this.object.position ) > 0 ) {
+			
+			_this.dispatchEvent( { type: 'change' } );
+
+			lastPosition.copy( _this.object.position );
+
+		}
+
+	};
+
 	// listeners
 
 	function keydown( event ) {
@@ -313,8 +353,6 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 		}
 
-		update();
-
 	};
 
 	function mouseup( event ) {
@@ -328,40 +366,6 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 	};
 
-	//
-
-	function update() {
-
-		_eye.copy( _this.object.position ).subSelf( _this.target );
-
-		if ( !_this.noRotate ) {
-
-			_this.rotateCamera();
-
-		}
-		
-		if ( !_this.noZoom ) {
-
-			_this.zoomCamera();
-
-		}
-
-		if ( !_this.noPan ) {
-
-			_this.panCamera();
-
-		}
-
-		_this.object.position.add( _this.target, _eye );
-
-		_this.checkDistances();
-
-		_this.object.lookAt( _this.target );
-
-		_this.dispatchEvent( { type: 'update' } );
-
-	};
-
 	this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
 
 	this.domElement.addEventListener( 'mousemove', mousemove, false );
@@ -371,7 +375,4 @@ THREE.TrackballControls = function ( object, domElement ) {
 	window.addEventListener( 'keydown', keydown, false );
 	window.addEventListener( 'keyup', keyup, false );
 
-	// TODO: Clean up the code so this isn't needed.
-	update();
-
 };