提交 18f78599 编写于 作者: M Mr.doob

Ray now intersects with particles too. (thx @jaycrossler)

上级 4f0199fc
因为 它太大了无法显示 source diff 。你可以改为 查看blob
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
<!DOCTYPE HTML>
<html lang="en">
<head>
<title>three.js canvas - interactive particles</title>
<meta charset="utf-8">
<style type="text/css">
body {
font-family: Monospace;
background-color: #f0f0f0;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<script type="text/javascript" src="../build/Three.js"></script>
<script type="text/javascript" src="js/RequestAnimationFrame.js"></script>
<script type="text/javascript" src="js/Stats.js"></script>
<script type="text/javascript">
var container, stats;
var camera, scene, projector, renderer;
var PI2 = Math.PI * 2;
var programFill = function ( context ) {
context.beginPath();
context.arc( 0, 0, 1, 0, PI2, true );
context.closePath();
context.fill();
}
var programStroke = function ( context ) {
context.beginPath();
context.arc( 0, 0, 1, 0, PI2, true );
context.closePath();
context.stroke();
}
var mouse = { x: 0, y: 0 }, INTERSECTED;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
var info = document.createElement( 'div' );
info.style.position = 'absolute';
info.style.top = '10px';
info.style.width = '100%';
info.style.textAlign = 'center';
info.innerHTML = '<a href="http://github.com/mrdoob/three.js" target="_blank">three.js</a> canvas - interactive particles';
container.appendChild( info );
camera = new THREE.Camera( 70, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.y = 300;
camera.position.z = 500;
scene = new THREE.Scene();
for ( var i = 0; i < 500; i ++ ) {
var particle = new THREE.Particle( new THREE.ParticleCanvasMaterial( { color: Math.random() * 0x808008 + 0x808080, program: programStroke } ) );
particle.position.x = Math.random() * 2000 - 1000;
particle.position.y = Math.random() * 2000 - 1000;
particle.position.z = Math.random() * 2000 - 1000;
particle.scale.x = particle.scale.y = Math.random() * 10 + 10;
scene.addObject( particle );
}
projector = new THREE.Projector();
renderer = new THREE.CanvasRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild(renderer.domElement);
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
container.appendChild( stats.domElement );
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
}
function onDocumentMouseMove( event ) {
event.preventDefault();
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
}
//
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
var radius = 600;
var theta = 0;
function render() {
// rotate camera
theta += 0.2;
camera.position.x = radius * Math.sin( theta * Math.PI / 360 );
camera.position.y = radius * Math.sin( theta * Math.PI / 360 );
camera.position.z = radius * Math.cos( theta * Math.PI / 360 );
// find intersections
camera.update();
var vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
projector.unprojectVector( vector, camera );
var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
var intersects = ray.intersectScene( scene );
if ( intersects.length > 0 ) {
if ( INTERSECTED != intersects[ 0 ].object ) {
if ( INTERSECTED ) INTERSECTED.materials[ 0 ].program = programStroke;
INTERSECTED = intersects[ 0 ].object;
INTERSECTED.materials[ 0 ].program = programFill;
}
} else {
if ( INTERSECTED ) INTERSECTED.materials[ 0 ].program = programStroke;
INTERSECTED = null;
}
renderer.render( scene, camera );
}
</script>
</body>
</html>
// stats.js r5 - http://github.com/mrdoob/stats.js
var Stats=function(){function w(d,K,n){var u,f,c;for(f=0;f<30;f++)for(u=0;u<73;u++){c=(u+f*74)*4;d[c]=d[c+4];d[c+1]=d[c+5];d[c+2]=d[c+6]}for(f=0;f<30;f++){c=(73+f*74)*4;if(f<K){d[c]=b[n].bg.r;d[c+1]=b[n].bg.g;d[c+2]=b[n].bg.b}else{d[c]=b[n].fg.r;d[c+1]=b[n].fg.g;d[c+2]=b[n].fg.b}}}var v=0,x=2,e,y=0,l=(new Date).getTime(),J=l,z=l,o=0,A=1E3,B=0,m,g,a,p,C,q=0,D=1E3,E=0,h,i,r,F,s=0,G=1E3,H=0,j,k,t,I,b={fps:{bg:{r:16,g:16,b:48},fg:{r:0,g:255,b:255}},ms:{bg:{r:16,g:48,b:16},fg:{r:0,g:255,b:0}},mem:{bg:{r:48,
g:16,b:26},fg:{r:255,g:0,b:128}}};e=document.createElement("div");e.style.cursor="pointer";e.style.width="80px";e.style.opacity="0.9";e.style.zIndex="10001";e.addEventListener("click",function(){v++;v==x&&(v=0);m.style.display="none";h.style.display="none";j.style.display="none";switch(v){case 0:m.style.display="block";break;case 1:h.style.display="block";break;case 2:j.style.display="block"}},false);m=document.createElement("div");m.style.backgroundColor="rgb("+Math.floor(b.fps.bg.r/2)+","+Math.floor(b.fps.bg.g/
2)+","+Math.floor(b.fps.bg.b/2)+")";m.style.padding="2px 0px 3px 0px";e.appendChild(m);g=document.createElement("div");g.style.fontFamily="Helvetica, Arial, sans-serif";g.style.textAlign="left";g.style.fontSize="9px";g.style.color="rgb("+b.fps.fg.r+","+b.fps.fg.g+","+b.fps.fg.b+")";g.style.margin="0px 0px 1px 3px";g.innerHTML='<span style="font-weight:bold">FPS</span>';m.appendChild(g);a=document.createElement("canvas");a.width=74;a.height=30;a.style.display="block";a.style.marginLeft="3px";m.appendChild(a);
p=a.getContext("2d");p.fillStyle="rgb("+b.fps.bg.r+","+b.fps.bg.g+","+b.fps.bg.b+")";p.fillRect(0,0,a.width,a.height);C=p.getImageData(0,0,a.width,a.height);h=document.createElement("div");h.style.backgroundColor="rgb("+Math.floor(b.ms.bg.r/2)+","+Math.floor(b.ms.bg.g/2)+","+Math.floor(b.ms.bg.b/2)+")";h.style.padding="2px 0px 3px 0px";h.style.display="none";e.appendChild(h);i=document.createElement("div");i.style.fontFamily="Helvetica, Arial, sans-serif";i.style.textAlign="left";i.style.fontSize=
"9px";i.style.color="rgb("+b.ms.fg.r+","+b.ms.fg.g+","+b.ms.fg.b+")";i.style.margin="0px 0px 1px 3px";i.innerHTML='<span style="font-weight:bold">MS</span>';h.appendChild(i);a=document.createElement("canvas");a.width=74;a.height=30;a.style.display="block";a.style.marginLeft="3px";h.appendChild(a);r=a.getContext("2d");r.fillStyle="rgb("+b.ms.bg.r+","+b.ms.bg.g+","+b.ms.bg.b+")";r.fillRect(0,0,a.width,a.height);F=r.getImageData(0,0,a.width,a.height);try{if(performance&&performance.memory&&performance.memory.totalJSHeapSize)x=
3}catch(L){}j=document.createElement("div");j.style.backgroundColor="rgb("+Math.floor(b.mem.bg.r/2)+","+Math.floor(b.mem.bg.g/2)+","+Math.floor(b.mem.bg.b/2)+")";j.style.padding="2px 0px 3px 0px";j.style.display="none";e.appendChild(j);k=document.createElement("div");k.style.fontFamily="Helvetica, Arial, sans-serif";k.style.textAlign="left";k.style.fontSize="9px";k.style.color="rgb("+b.mem.fg.r+","+b.mem.fg.g+","+b.mem.fg.b+")";k.style.margin="0px 0px 1px 3px";k.innerHTML='<span style="font-weight:bold">MEM</span>';
j.appendChild(k);a=document.createElement("canvas");a.width=74;a.height=30;a.style.display="block";a.style.marginLeft="3px";j.appendChild(a);t=a.getContext("2d");t.fillStyle="#301010";t.fillRect(0,0,a.width,a.height);I=t.getImageData(0,0,a.width,a.height);return{domElement:e,update:function(){y++;l=(new Date).getTime();q=l-J;D=Math.min(D,q);E=Math.max(E,q);w(F.data,Math.min(30,30-q/200*30),"ms");i.innerHTML='<span style="font-weight:bold">'+q+" MS</span> ("+D+"-"+E+")";r.putImageData(F,0,0);J=l;if(l>
z+1E3){o=Math.round(y*1E3/(l-z));A=Math.min(A,o);B=Math.max(B,o);w(C.data,Math.min(30,30-o/100*30),"fps");g.innerHTML='<span style="font-weight:bold">'+o+" FPS</span> ("+A+"-"+B+")";p.putImageData(C,0,0);if(x==3){s=performance.memory.usedJSHeapSize*9.54E-7;G=Math.min(G,s);H=Math.max(H,s);w(I.data,Math.min(30,30-s/2),"mem");k.innerHTML='<span style="font-weight:bold">'+Math.round(s)+" MEM</span> ("+Math.round(G)+"-"+Math.round(H)+")";t.putImageData(I,0,0)}z=l;y=0}}}};
// stats.js r6 - http://github.com/mrdoob/stats.js
var Stats=function(){function s(a,g,d){var f,c,e;for(c=0;c<30;c++)for(f=0;f<73;f++)e=(f+c*74)*4,a[e]=a[e+4],a[e+1]=a[e+5],a[e+2]=a[e+6];for(c=0;c<30;c++)e=(73+c*74)*4,c<g?(a[e]=b[d].bg.r,a[e+1]=b[d].bg.g,a[e+2]=b[d].bg.b):(a[e]=b[d].fg.r,a[e+1]=b[d].fg.g,a[e+2]=b[d].fg.b)}var r=0,t=2,g,u=0,j=(new Date).getTime(),F=j,v=j,l=0,w=1E3,x=0,k,d,a,m,y,n=0,z=1E3,A=0,f,c,o,B,p=0,C=1E3,D=0,h,i,q,E,b={fps:{bg:{r:16,g:16,b:48},fg:{r:0,g:255,b:255}},ms:{bg:{r:16,g:48,b:16},fg:{r:0,g:255,b:0}},mb:{bg:{r:48,g:16,
b:26},fg:{r:255,g:0,b:128}}};g=document.createElement("div");g.style.cursor="pointer";g.style.width="80px";g.style.opacity="0.9";g.style.zIndex="10001";g.addEventListener("click",function(){r++;r==t&&(r=0);k.style.display="none";f.style.display="none";h.style.display="none";switch(r){case 0:k.style.display="block";break;case 1:f.style.display="block";break;case 2:h.style.display="block"}},!1);k=document.createElement("div");k.style.backgroundColor="rgb("+Math.floor(b.fps.bg.r/2)+","+Math.floor(b.fps.bg.g/
2)+","+Math.floor(b.fps.bg.b/2)+")";k.style.padding="2px 0px 3px 0px";g.appendChild(k);d=document.createElement("div");d.style.fontFamily="Helvetica, Arial, sans-serif";d.style.textAlign="left";d.style.fontSize="9px";d.style.color="rgb("+b.fps.fg.r+","+b.fps.fg.g+","+b.fps.fg.b+")";d.style.margin="0px 0px 1px 3px";d.innerHTML='<span style="font-weight:bold">FPS</span>';k.appendChild(d);a=document.createElement("canvas");a.width=74;a.height=30;a.style.display="block";a.style.marginLeft="3px";k.appendChild(a);
m=a.getContext("2d");m.fillStyle="rgb("+b.fps.bg.r+","+b.fps.bg.g+","+b.fps.bg.b+")";m.fillRect(0,0,a.width,a.height);y=m.getImageData(0,0,a.width,a.height);f=document.createElement("div");f.style.backgroundColor="rgb("+Math.floor(b.ms.bg.r/2)+","+Math.floor(b.ms.bg.g/2)+","+Math.floor(b.ms.bg.b/2)+")";f.style.padding="2px 0px 3px 0px";f.style.display="none";g.appendChild(f);c=document.createElement("div");c.style.fontFamily="Helvetica, Arial, sans-serif";c.style.textAlign="left";c.style.fontSize=
"9px";c.style.color="rgb("+b.ms.fg.r+","+b.ms.fg.g+","+b.ms.fg.b+")";c.style.margin="0px 0px 1px 3px";c.innerHTML='<span style="font-weight:bold">MS</span>';f.appendChild(c);a=document.createElement("canvas");a.width=74;a.height=30;a.style.display="block";a.style.marginLeft="3px";f.appendChild(a);o=a.getContext("2d");o.fillStyle="rgb("+b.ms.bg.r+","+b.ms.bg.g+","+b.ms.bg.b+")";o.fillRect(0,0,a.width,a.height);B=o.getImageData(0,0,a.width,a.height);try{performance&&performance.memory&&performance.memory.totalJSHeapSize&&
(t=3)}catch(G){}h=document.createElement("div");h.style.backgroundColor="rgb("+Math.floor(b.mb.bg.r/2)+","+Math.floor(b.mb.bg.g/2)+","+Math.floor(b.mb.bg.b/2)+")";h.style.padding="2px 0px 3px 0px";h.style.display="none";g.appendChild(h);i=document.createElement("div");i.style.fontFamily="Helvetica, Arial, sans-serif";i.style.textAlign="left";i.style.fontSize="9px";i.style.color="rgb("+b.mb.fg.r+","+b.mb.fg.g+","+b.mb.fg.b+")";i.style.margin="0px 0px 1px 3px";i.innerHTML='<span style="font-weight:bold">MB</span>';
h.appendChild(i);a=document.createElement("canvas");a.width=74;a.height=30;a.style.display="block";a.style.marginLeft="3px";h.appendChild(a);q=a.getContext("2d");q.fillStyle="#301010";q.fillRect(0,0,a.width,a.height);E=q.getImageData(0,0,a.width,a.height);return{domElement:g,update:function(){u++;j=(new Date).getTime();n=j-F;z=Math.min(z,n);A=Math.max(A,n);s(B.data,Math.min(30,30-n/200*30),"ms");c.innerHTML='<span style="font-weight:bold">'+n+" MS</span> ("+z+"-"+A+")";o.putImageData(B,0,0);F=j;if(j>
v+1E3){l=Math.round(u*1E3/(j-v));w=Math.min(w,l);x=Math.max(x,l);s(y.data,Math.min(30,30-l/100*30),"fps");d.innerHTML='<span style="font-weight:bold">'+l+" FPS</span> ("+w+"-"+x+")";m.putImageData(y,0,0);if(t==3)p=performance.memory.usedJSHeapSize*9.54E-7,C=Math.min(C,p),D=Math.max(D,p),s(E.data,Math.min(30,30-p/2),"mb"),i.innerHTML='<span style="font-weight:bold">'+Math.round(p)+" MB</span> ("+Math.round(C)+"-"+Math.round(D)+")",q.putImageData(E,0,0);v=j;u=0}}}};
// Tween.js - http://github.com/sole/tween.js
var TWEEN=TWEEN||function(){var a,e,d,b=[];this.add=function(h){b.push(h)};this.remove=function(h){a=b.indexOf(h);a!==-1&&b.splice(a,1)};this.update=function(){a=0;e=b.length;for(d=(new Date).getTime();a<e;)if(b[a].update(d))a++;else{b.splice(a,1);e--}};return this}();
TWEEN.Tween=function(a){var e={},d={},b={},h=1E3,m=0,i=null,n=TWEEN.Easing.Linear.EaseNone,j=null,k=null,l=null;this.to=function(c,f){if(f!==null)h=f;for(var g in c)if(a[g]!==null)b[g]=c[g];return this};this.start=function(){TWEEN.add(this);i=(new Date).getTime()+m;for(var c in b)if(a[c]!==null){e[c]=a[c];d[c]=b[c]-a[c]}return this};this.stop=function(){TWEEN.remove(this);return this};this.delay=function(c){m=c;return this};this.easing=function(c){n=c;return this};this.chain=function(c){j=c};this.onUpdate=
function(c){k=c;return this};this.onComplete=function(c){l=c;return this};this.update=function(c){var f,g;if(c<i)return true;c=(c-i)/h;c=c>1?1:c;g=n(c);for(f in d)a[f]=e[f]+d[f]*g;k!==null&&k.call(a,g);if(c==1){l!==null&&l.call(a);j!==null&&j.start();return false}return true}};TWEEN.Easing={Linear:{},Quadratic:{},Cubic:{},Quartic:{},Quintic:{},Sinusoidal:{},Exponential:{},Circular:{},Elastic:{},Back:{},Bounce:{}};TWEEN.Easing.Linear.EaseNone=function(a){return a};
// tween.js r1 - http://github.com/sole/tween.js
var TWEEN=TWEEN||function(){var a,e,c,d,f=[];return{start:function(g){c=setInterval(this.update,1E3/(g||60))},stop:function(){clearInterval(c)},add:function(g){f.push(g)},remove:function(g){a=f.indexOf(g);a!==-1&&f.splice(a,1)},update:function(){a=0;e=f.length;for(d=(new Date).getTime();a<e;)if(f[a].update(d))a++;else{f.splice(a,1);e--}}}}();
TWEEN.Tween=function(a){var e={},c={},d={},f=1E3,g=0,j=null,n=TWEEN.Easing.Linear.EaseNone,k=null,l=null,m=null;this.to=function(b,h){if(h!==null)f=h;for(var i in b)if(a[i]!==null)d[i]=b[i];return this};this.start=function(){TWEEN.add(this);j=(new Date).getTime()+g;for(var b in d)if(a[b]!==null){e[b]=a[b];c[b]=d[b]-a[b]}return this};this.stop=function(){TWEEN.remove(this);return this};this.delay=function(b){g=b;return this};this.easing=function(b){n=b;return this};this.chain=function(b){k=b};this.onUpdate=
function(b){l=b;return this};this.onComplete=function(b){m=b;return this};this.update=function(b){var h,i;if(b<j)return true;b=(b-j)/f;b=b>1?1:b;i=n(b);for(h in c)a[h]=e[h]+c[h]*i;l!==null&&l.call(a,i);if(b==1){m!==null&&m.call(a);k!==null&&k.start();return false}return true}};TWEEN.Easing={Linear:{},Quadratic:{},Cubic:{},Quartic:{},Quintic:{},Sinusoidal:{},Exponential:{},Circular:{},Elastic:{},Back:{},Bounce:{}};TWEEN.Easing.Linear.EaseNone=function(a){return a};
TWEEN.Easing.Quadratic.EaseIn=function(a){return a*a};TWEEN.Easing.Quadratic.EaseOut=function(a){return-a*(a-2)};TWEEN.Easing.Quadratic.EaseInOut=function(a){if((a*=2)<1)return 0.5*a*a;return-0.5*(--a*(a-2)-1)};TWEEN.Easing.Cubic.EaseIn=function(a){return a*a*a};TWEEN.Easing.Cubic.EaseOut=function(a){return--a*a*a+1};TWEEN.Easing.Cubic.EaseInOut=function(a){if((a*=2)<1)return 0.5*a*a*a;return 0.5*((a-=2)*a*a+2)};TWEEN.Easing.Quartic.EaseIn=function(a){return a*a*a*a};
TWEEN.Easing.Quartic.EaseOut=function(a){return-(--a*a*a*a-1)};TWEEN.Easing.Quartic.EaseInOut=function(a){if((a*=2)<1)return 0.5*a*a*a*a;return-0.5*((a-=2)*a*a*a-2)};TWEEN.Easing.Quintic.EaseIn=function(a){return a*a*a*a*a};TWEEN.Easing.Quintic.EaseOut=function(a){return(a-=1)*a*a*a*a+1};TWEEN.Easing.Quintic.EaseInOut=function(a){if((a*=2)<1)return 0.5*a*a*a*a*a;return 0.5*((a-=2)*a*a*a*a+2)};TWEEN.Easing.Sinusoidal.EaseIn=function(a){return-Math.cos(a*Math.PI/2)+1};
TWEEN.Easing.Sinusoidal.EaseOut=function(a){return Math.sin(a*Math.PI/2)};TWEEN.Easing.Sinusoidal.EaseInOut=function(a){return-0.5*(Math.cos(Math.PI*a)-1)};TWEEN.Easing.Exponential.EaseIn=function(a){return a==0?0:Math.pow(2,10*(a-1))};TWEEN.Easing.Exponential.EaseOut=function(a){return a==1?1:-Math.pow(2,-10*a)+1};TWEEN.Easing.Exponential.EaseInOut=function(a){if(a==0)return 0;if(a==1)return 1;if((a*=2)<1)return 0.5*Math.pow(2,10*(a-1));return 0.5*(-Math.pow(2,-10*(a-1))+2)};
TWEEN.Easing.Circular.EaseIn=function(a){return-(Math.sqrt(1-a*a)-1)};TWEEN.Easing.Circular.EaseOut=function(a){return Math.sqrt(1- --a*a)};TWEEN.Easing.Circular.EaseInOut=function(a){if((a/=0.5)<1)return-0.5*(Math.sqrt(1-a*a)-1);return 0.5*(Math.sqrt(1-(a-=2)*a)+1)};TWEEN.Easing.Elastic.EaseIn=function(a){var e,d=0.1,b=0.4;if(a==0)return 0;if(a==1)return 1;b||(b=0.3);if(!d||d<1){d=1;e=b/4}else e=b/(2*Math.PI)*Math.asin(1/d);return-(d*Math.pow(2,10*(a-=1))*Math.sin((a-e)*2*Math.PI/b))};
TWEEN.Easing.Elastic.EaseOut=function(a){var e,d=0.1,b=0.4;if(a==0)return 0;if(a==1)return 1;b||(b=0.3);if(!d||d<1){d=1;e=b/4}else e=b/(2*Math.PI)*Math.asin(1/d);return d*Math.pow(2,-10*a)*Math.sin((a-e)*2*Math.PI/b)+1};
TWEEN.Easing.Elastic.EaseInOut=function(a){var e,d=0.1,b=0.4;if(a==0)return 0;if(a==1)return 1;b||(b=0.3);if(!d||d<1){d=1;e=b/4}else e=b/(2*Math.PI)*Math.asin(1/d);if((a*=2)<1)return-0.5*d*Math.pow(2,10*(a-=1))*Math.sin((a-e)*2*Math.PI/b);return d*Math.pow(2,-10*(a-=1))*Math.sin((a-e)*2*Math.PI/b)*0.5+1};TWEEN.Easing.Back.EaseIn=function(a){return a*a*(2.70158*a-1.70158)};TWEEN.Easing.Back.EaseOut=function(a){return(a-=1)*a*(2.70158*a+1.70158)+1};
TWEEN.Easing.Circular.EaseIn=function(a){return-(Math.sqrt(1-a*a)-1)};TWEEN.Easing.Circular.EaseOut=function(a){return Math.sqrt(1- --a*a)};TWEEN.Easing.Circular.EaseInOut=function(a){if((a/=0.5)<1)return-0.5*(Math.sqrt(1-a*a)-1);return 0.5*(Math.sqrt(1-(a-=2)*a)+1)};TWEEN.Easing.Elastic.EaseIn=function(a){var e,c=0.1,d=0.4;if(a==0)return 0;if(a==1)return 1;d||(d=0.3);if(!c||c<1){c=1;e=d/4}else e=d/(2*Math.PI)*Math.asin(1/c);return-(c*Math.pow(2,10*(a-=1))*Math.sin((a-e)*2*Math.PI/d))};
TWEEN.Easing.Elastic.EaseOut=function(a){var e,c=0.1,d=0.4;if(a==0)return 0;if(a==1)return 1;d||(d=0.3);if(!c||c<1){c=1;e=d/4}else e=d/(2*Math.PI)*Math.asin(1/c);return c*Math.pow(2,-10*a)*Math.sin((a-e)*2*Math.PI/d)+1};
TWEEN.Easing.Elastic.EaseInOut=function(a){var e,c=0.1,d=0.4;if(a==0)return 0;if(a==1)return 1;d||(d=0.3);if(!c||c<1){c=1;e=d/4}else e=d/(2*Math.PI)*Math.asin(1/c);if((a*=2)<1)return-0.5*c*Math.pow(2,10*(a-=1))*Math.sin((a-e)*2*Math.PI/d);return c*Math.pow(2,-10*(a-=1))*Math.sin((a-e)*2*Math.PI/d)*0.5+1};TWEEN.Easing.Back.EaseIn=function(a){return a*a*(2.70158*a-1.70158)};TWEEN.Easing.Back.EaseOut=function(a){return(a-=1)*a*(2.70158*a+1.70158)+1};
TWEEN.Easing.Back.EaseInOut=function(a){if((a*=2)<1)return 0.5*a*a*(3.5949095*a-2.5949095);return 0.5*((a-=2)*a*(3.5949095*a+2.5949095)+2)};TWEEN.Easing.Bounce.EaseIn=function(a){return 1-TWEEN.Easing.Bounce.EaseOut(1-a)};TWEEN.Easing.Bounce.EaseOut=function(a){return(a/=1)<1/2.75?7.5625*a*a:a<2/2.75?7.5625*(a-=1.5/2.75)*a+0.75:a<2.5/2.75?7.5625*(a-=2.25/2.75)*a+0.9375:7.5625*(a-=2.625/2.75)*a+0.984375};
TWEEN.Easing.Bounce.EaseInOut=function(a){if(a<0.5)return TWEEN.Easing.Bounce.EaseIn(a*2)*0.5;return TWEEN.Easing.Bounce.EaseOut(a*2-1)*0.5+0.5};
<!DOCTYPE HTML>
<html lang="en">
<head>
<title>three.js webgl - interactive cubes</title>
<meta charset="utf-8">
<style type="text/css">
body {
font-family: Monospace;
background-color: #f0f0f0;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<script type="text/javascript" src="../build/Three.js"></script>
<script type="text/javascript" src="js/Tween.js"></script>
<script type="text/javascript" src="js/RequestAnimationFrame.js"></script>
<script type="text/javascript" src="js/Stats.js"></script>
<script type="text/javascript">
var container, stats;
var camera, scene, projector, renderer;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
var info = document.createElement( 'div' );
info.style.position = 'absolute';
info.style.top = '10px';
info.style.width = '100%';
info.style.textAlign = 'center';
info.innerHTML = '<a href="http://github.com/mrdoob/three.js" target="_blank">three.js</a> webgl - interactive cubes';
container.appendChild( info );
camera = new THREE.Camera( 70, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.y = 300;
camera.position.z = 500;
scene = new THREE.Scene();
var light = new THREE.DirectionalLight( 0xffffff, 2 );
light.position.x = 1;
light.position.y = 1;
light.position.z = 1;
light.position.normalize();
scene.addLight( light );
var light = new THREE.DirectionalLight( 0xffffff );
light.position.x = - 1;
light.position.y = - 1;
light.position.z = - 1;
light.position.normalize();
scene.addLight( light );
var geometry = new THREE.Cube( 100, 100, 100 );
for ( var i = 0; i < 20; i ++ ) {
var object = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: Math.random() * 0xffffff } ) );
object.position.x = Math.random() * 800 - 400;
object.position.y = Math.random() * 800 - 400;
object.position.z = Math.random() * 800 - 400;
object.scale.x = Math.random() * 2 + 1;
object.scale.y = Math.random() * 2 + 1;
object.scale.z = Math.random() * 2 + 1;
object.rotation.x = ( Math.random() * 360 ) * Math.PI / 180;
object.rotation.y = ( Math.random() * 360 ) * Math.PI / 180;
object.rotation.z = ( Math.random() * 360 ) * Math.PI / 180;
scene.addObject( object );
}
projector = new THREE.Projector();
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild(renderer.domElement);
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
container.appendChild( stats.domElement );
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
}
function onDocumentMouseDown( event ) {
event.preventDefault();
var vector = new THREE.Vector3( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1, 0.5 );
projector.unprojectVector( vector, camera );
var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
var intersects = ray.intersectScene( scene );
if ( intersects.length > 0 ) {
new TWEEN.Tween( intersects[ 0 ].object.position ).to( {
x: Math.random() * 800 - 400,
y: Math.random() * 800 - 400,
z: Math.random() * 800 - 400 }, 2000 )
.easing( TWEEN.Easing.Elastic.EaseOut).start();
new TWEEN.Tween( intersects[ 0 ].object.rotation ).to( {
x: ( Math.random() * 360 ) * Math.PI / 180,
y: ( Math.random() * 360 ) * Math.PI / 180,
z: ( Math.random() * 360 ) * Math.PI / 180 }, 2000 )
.easing( TWEEN.Easing.Elastic.EaseOut).start();
}
/*
// Parse all the faces
for ( var i in intersects ) {
intersects[ i ].face.material[ 0 ].color.setHex( Math.random() * 0xffffff | 0x80000000 );
}
*/
}
//
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
var radius = 600;
var theta = 0;
function render() {
TWEEN.update();
theta += 0.2;
camera.position.x = radius * Math.sin( theta * Math.PI / 360 );
camera.position.y = radius * Math.sin( theta * Math.PI / 360 );
camera.position.z = radius * Math.cos( theta * Math.PI / 360 );
renderer.render( scene, camera );
}
</script>
</body>
</html>
......@@ -476,61 +476,63 @@ THREE.Matrix4.prototype = {
return this;
},
getPosition : function() {
if( !this.position ) {
getPosition: function() {
if ( ! this.position ) {
this.position = new THREE.Vector3();
}
this.position.set( this.n14, this.n24, this.n34 );
return this.position;
},
getColumnX : function() {
if( !this.columnX ) {
getColumnX: function() {
if ( ! this.columnX ) {
this.columnX = new THREE.Vector3();
}
this.columnX.set( this.n11, this.n21, this.n31 );
return this.columnX;
},
getColumnY : function() {
if( !this.columnY ) {
getColumnY: function() {
if ( ! this.columnY ) {
this.columnY = new THREE.Vector3();
}
this.columnY.set( this.n12, this.n22, this.n32 );
return this.columnY;
},
getColumnZ : function() {
if( !this.columnZ ) {
getColumnZ: function() {
if ( ! this.columnZ ) {
this.columnZ = new THREE.Vector3();
}
this.columnZ.set( this.n13, this.n23, this.n33 );
return this.columnZ;
},
setRotationFromEuler : function( v ) {
setRotationFromEuler: function( v ) {
var x = v.x, y = v.y, z = v.z,
a = Math.cos( x ), b = Math.sin( x ),
......@@ -554,7 +556,7 @@ THREE.Matrix4.prototype = {
},
setRotationFromQuaternion : function( q ) {
setRotationFromQuaternion: function( q ) {
var x = q.x, y = q.y, z = q.z, w = q.w,
x2 = x + x, y2 = y + y, z2 = z + z,
......@@ -578,7 +580,7 @@ THREE.Matrix4.prototype = {
},
scale : function ( v ) {
scale: function ( v ) {
var x = v.x, y = v.y, z = v.z;
......@@ -591,7 +593,7 @@ THREE.Matrix4.prototype = {
},
extractPosition : function ( m ) {
extractPosition: function ( m ) {
this.n14 = m.n14;
this.n24 = m.n24;
......@@ -599,7 +601,7 @@ THREE.Matrix4.prototype = {
},
extractRotation : function ( m, s ) {
extractRotation: function ( m, s ) {
var invScaleX = 1 / s.x, invScaleY = 1 / s.y, invScaleZ = 1 / s.z;
......@@ -628,7 +630,7 @@ THREE.Matrix4.makeInvert = function ( m1, m2 ) {
n31 = m1.n31, n32 = m1.n32, n33 = m1.n33, n34 = m1.n34,
n41 = m1.n41, n42 = m1.n42, n43 = m1.n43, n44 = m1.n44;
if( m2 === undefined ) m2 = new THREE.Matrix4();
if ( m2 === undefined ) m2 = new THREE.Matrix4();
m2.n11 = n23*n34*n42 - n24*n33*n42 + n24*n32*n43 - n22*n34*n43 - n23*n32*n44 + n22*n33*n44;
m2.n12 = n14*n33*n42 - n13*n34*n42 - n14*n32*n43 + n12*n34*n43 + n13*n32*n44 - n12*n33*n44;
......@@ -673,10 +675,12 @@ THREE.Matrix4.makeInvert3x3 = function ( m1 ) {
idet;
// no inverse
if (det == 0) {
throw "matrix not invertible";
if ( det == 0 ) {
console.error( 'THREE.Matrix4.makeInvert3x3: Matrix not invertible.' );
}
idet = 1.0 / det;
m33m[ 0 ] = idet * a11; m33m[ 1 ] = idet * a21; m33m[ 2 ] = idet * a31;
......
......@@ -11,26 +11,20 @@ THREE.Ray = function ( origin, direction ) {
THREE.Ray.prototype = {
intersectScene : function ( scene ) {
intersectScene: function ( scene ) {
return this.intersectObjects( scene.objects );
},
intersectObjects : function ( objects ) {
intersectObjects: function ( objects ) {
var i, l, object,
intersects = [];
for ( i = 0, l = objects.length; i < l; i ++ ) {
object = objects[ i ];
if ( object instanceof THREE.Mesh ) {
intersects = intersects.concat( this.intersectObject( object ) );
}
intersects = intersects.concat( this.intersectObject( objects[ i ] ) );
}
......@@ -40,70 +34,93 @@ THREE.Ray.prototype = {
},
intersectObject : function ( object ) {
intersectObject: function ( object ) {
var f, fl, face, a, b, c, d, normal,
dot, scalar,
origin, direction,
geometry = object.geometry,
vertices = geometry.vertices,
objMatrix,
intersect, intersects = [],
intersectPoint;
if ( object instanceof THREE.Particle ) {
for ( f = 0, fl = geometry.faces.length; f < fl; f ++ ) {
var intersects = [],
distance = distanceFromIntersection( this.origin, this.direction, object );
face = geometry.faces[ f ];
if ( distance && distance < object.scale.x ) {
origin = this.origin.clone();
direction = this.direction.clone();
intersects.push( {
objMatrix = object.matrixWorld;
distance: distance,
point: object.position,
object: object
a = objMatrix.multiplyVector3( vertices[ face.a ].position.clone() );
b = objMatrix.multiplyVector3( vertices[ face.b ].position.clone() );
c = objMatrix.multiplyVector3( vertices[ face.c ].position.clone() );
d = face instanceof THREE.Face4 ? objMatrix.multiplyVector3( vertices[ face.d ].position.clone() ) : null;
} );
normal = object.matrixRotationWorld.multiplyVector3( face.normal.clone() );
dot = direction.dot( normal );
}
if ( object.doubleSided || ( object.flipSided ? dot > 0 : dot < 0 ) ) { // Math.abs( dot ) > 0.0001
return intersects;
scalar = normal.dot( new THREE.Vector3().sub( a, origin ) ) / dot;
intersectPoint = origin.addSelf( direction.multiplyScalar( scalar ) );
} else if ( object instanceof THREE.Mesh ) {
if ( face instanceof THREE.Face3 ) {
var f, fl, face, a, b, c, d, normal,
dot, scalar,
origin, direction,
geometry = object.geometry,
vertices = geometry.vertices,
objMatrix,
intersect, intersects = [],
intersectPoint;
if ( pointInFace3( intersectPoint, a, b, c ) ) {
for ( f = 0, fl = geometry.faces.length; f < fl; f ++ ) {
intersect = {
face = geometry.faces[ f ];
distance: this.origin.distanceTo( intersectPoint ),
point: intersectPoint,
face: face,
object: object
origin = this.origin.clone();
direction = this.direction.clone();
};
objMatrix = object.matrixWorld;
intersects.push( intersect );
a = objMatrix.multiplyVector3( vertices[ face.a ].position.clone() );
b = objMatrix.multiplyVector3( vertices[ face.b ].position.clone() );
c = objMatrix.multiplyVector3( vertices[ face.c ].position.clone() );
d = face instanceof THREE.Face4 ? objMatrix.multiplyVector3( vertices[ face.d ].position.clone() ) : null;
}
normal = object.matrixRotationWorld.multiplyVector3( face.normal.clone() );
dot = direction.dot( normal );
if ( object.doubleSided || ( object.flipSided ? dot > 0 : dot < 0 ) ) { // Math.abs( dot ) > 0.0001
scalar = normal.dot( new THREE.Vector3().sub( a, origin ) ) / dot;
intersectPoint = origin.addSelf( direction.multiplyScalar( scalar ) );
if ( face instanceof THREE.Face3 ) {
if ( pointInFace3( intersectPoint, a, b, c ) ) {
intersect = {
distance: this.origin.distanceTo( intersectPoint ),
point: intersectPoint,
face: face,
object: object
};
} else if ( face instanceof THREE.Face4 ) {
intersects.push( intersect );
if ( pointInFace3( intersectPoint, a, b, d ) || pointInFace3( intersectPoint, b, c, d ) ) {
}
intersect = {
} else if ( face instanceof THREE.Face4 ) {
distance: this.origin.distanceTo( intersectPoint ),
point: intersectPoint,
face: face,
object: object
if ( pointInFace3( intersectPoint, a, b, d ) || pointInFace3( intersectPoint, b, c, d ) ) {
};
intersect = {
intersects.push( intersect );
distance: this.origin.distanceTo( intersectPoint ),
point: intersectPoint,
face: face,
object: object
};
intersects.push( intersect );
}
}
......@@ -111,9 +128,25 @@ THREE.Ray.prototype = {
}
return intersects;
}
return intersects;
function distanceFromIntersection( origin, direction, object ) {
var vector, dot, intersect, distance;
vector = object.position.clone().subSelf( origin );
dot = vector.dot( direction );
if ( dot < 0 ) return false; // Object is behind origin
intersect = origin.clone().addSelf( direction.clone().multiplyScalar( dot ) );
distance = object.position.distanceTo( intersect );
return distance;
}
// http://www.blackpawn.com/texts/pointinpoly/default.html
......
......@@ -98,7 +98,7 @@ THREE.Projector = function() {
_face4Count = 0;
_lineCount = 0;
_particleCount = 0;
camera.matrixAutoUpdate && camera.update( undefined, true );
scene.update( undefined, false, camera );
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册