Preparation Code Preparation HTML (this will be inserted in the <body>
of a valid HTML5 document in standards mode) (useful when testing DOM operations or including libraries) <script src ="https://raw.github.com/mrdoob/three.js/dev/build/three.js" > </script >
<script >
var orig_ray = THREE .Ray ;
</script >
<script src ="https://raw.github.com/gist/3376707/a9b7a47e4b8d8a4d3170880ec23276fa70249c8b/ray.js" > </script >
<script >
var local_ray = THREE .Ray ;
</script >
<script >
(function (b ){b.Ray =function (a,z,c,d ){this .origin =a||new b.Vector3 ;this .direction =z||new b.Vector3 ;this .near =c||0 ;this .far =d||Infinity };var o=new b.Vector3 ,p=new b.Vector3 ,q=new b.Vector3 ,v=new b.Vector3 ,r=new b.Vector3 ,n=new b.Vector3 ,s=new b.Matrix4 ,w=function (a,b ){return a.distance -b.distance },g=new b.Vector3 ,h=new b.Vector3 ,j=new b.Vector3 ,x=function (a,b,c ){var d;g.sub (c,a);d=g.dot (b);a=h.add (a,j.copy (b).multiplyScalar (d));return c.distanceTo (a)},t=function (a,b,c,d ){var e,k;g.sub (d,b);h.sub (c,
b);j.sub (a,b);a=g.dot (g);b=g.dot (h);c=g.dot (j);e=h.dot (h);d=h.dot (j);k=1 /(a*e-b*b);e=(e*c-b*d)*k;a=(a*d-b*c)*k;return 0 <=e&&0 <=a&&1 >e+a};b.Ray .prototype .precision =1E-4 ;b.Ray .prototype .setPrecision =function (a ){this .precision =a};b.Ray .prototype .intersectObject =function (a,g ){var c,d=[];if (!0 ===g)for (var e=0 ,k=a.children .length ;e<k;e++)Array .prototype .push .apply (d,this .intersectObject (a.children [e],g));if (a instanceof b.Particle ){distance=x (this .origin ,this .direction ,a.matrixWorld .getPosition ());if (distance>
a.scale .x )return [];c={distance :distance,point :a.position ,face :null ,object :a};d.push (c)}else if (a instanceof b.Mesh ){e=a.geometry .boundingSphere .radius *a.matrixWorld .getMaxScaleOnAxis ();distance=x (this .origin ,this .direction ,a.matrixWorld .getPosition ());if (distance>e)return d;var f,i,h=a.geometry ,l=h.vertices ,j,y,m;j=a.geometry .materials ;y=a.material instanceof b.MeshFaceMaterial ;var u,A=this .precision ;a.matrixRotationWorld .extractRotation (a.matrixWorld );o.copy (this .origin );s.getInverse (a.matrixWorld );
p.copy (o);s.multiplyVector3 (p);q.copy (this .direction );s.rotateAxis (q).normalize ();e=0 ;for (k=h.faces .length ;e<k;e++)if (c=h.faces [e],f=!0 ===y?j[c.materialIndex ]:a.material ,void 0 !==f&&(m=f.side ,v.sub (c.centroid ,p),r=c.normal ,f=q.dot (r),!(Math .abs (f)<A)&&(i=r.dot (v)/f,!(0 >i)&&(m===b.DoubleSide ||(m===b.FrontSide ?0 >f :0 <f)))))if (n.add (p,q.multiplyScalar (i)),c instanceof b.Face3 )f=l[c.a ],i=l[c.b ],m=l[c.c ],t (n,f,i,m)&&(f=a.matrixWorld .multiplyVector3 (n.clone ()),distance=o.distanceTo (f),!(distance<this .near )&&
!(distance>this .far )&&(c={distance :distance,point :f,face :c,faceIndex :e,object :a},d.push (c)));else if (c instanceof b.Face4 &&(f=l[c.a ],i=l[c.b ],m=l[c.c ],u=l[c.d ],t (n,f,i,u)||t (n,i,m,u)))f=a.matrixWorld .multiplyVector3 (n.clone ()),distance=o.distanceTo (f),!(distance<this .near )&&!(distance>this .far )&&(c={distance :distance,point :f,face :c,faceIndex :e,object :a},d.push (c))}d.sort (w);return d};b.Ray .prototype .intersectObjects =function (a,b ){for (var c=[],d=0 ,e=a.length ;d<e;d++)Array .prototype .push .apply (c,this .intersectObject (a[d],
b));c.sort (w);return c}})(THREE );
</script >
<script >
var optimized_local_ray = THREE .Ray ;
</script >
Setup JS camera = new THREE .PerspectiveCamera ( 70 , window .innerWidth / window .innerHeight , 1 , 10000 );
camera.position .set ( 0 , 300 , 50 );
scene = new THREE .Scene ();
var cubes = new THREE .Object 3D();
scene.add (cubes);
var geometry = new THREE .CubeGeometry ( 20 , 20 , 20 );
for ( var i = 0 ; i < 50 ; i ++ ) {
var object = new THREE .Mesh ( geometry, new THREE .MeshLambertMaterial ( { color : (i/50 ) * 0xffffff } ) );
object.position .x = (i/50 ) * 800 - 400 ;
object.position .y = (i/50 ) * 800 - 400 ;
object.position .z = (i/50 ) * 800 - 400 ;
object.rotation .x = ( (i/50 ) * 360 ) * Math .PI / 180 ;
object.rotation .y = ( (i/50 ) * 360 ) * Math .PI / 180 ;
object.rotation .z = ( (i/50 ) * 360 ) * Math .PI / 180 ;
object.scale .x = (i/50 ) * 2 + 1 ;
object.scale .y = (i/50 ) * 2 + 1 ;
object.scale .z = (i/50 ) * 2 + 1 ;
cubes.add ( object );
object.updateMatrixWorld ();
}
var planes = new THREE .Object 3D();
scene.add (planes);
var geometry = new THREE .PlaneGeometry ( 20 , 20 );
for ( var i = 0 ; i < 50 ; i ++ ) {
var object = new THREE .Mesh ( geometry, new THREE .MeshLambertMaterial ( { color : (i/50 ) * 0xffffff } ) );
object.position .x = (i/50 ) * 800 - 400 ;
object.position .y = (i/50 ) * 800 - 400 ;
object.position .z = (i/50 ) * 800 - 400 ;
object.rotation .x = ( (i/50 ) * 360 ) * Math .PI / 180 ;
object.rotation .y = ( (i/50 ) * 360 ) * Math .PI / 180 ;
object.rotation .z = ( (i/50 ) * 360 ) * Math .PI / 180 ;
object.scale .x = (i/50 ) * 2 + 1 ;
object.scale .y = (i/50 ) * 2 + 1 ;
object.scale .z = (i/50 ) * 2 + 1 ;
planes.add ( object );
object.updateMatrixWorld ();
}
var combined = new THREE .Object 3D();
scene.add (combined);
var geometry = new THREE .CubeGeometry ( 20 , 20 ,20 );
var combGeometry = new THREE .CubeGeometry ( 20 , 20 ,20 );
for ( var i = 0 ; i < 50 ; i ++ ) {
var object = new THREE .Mesh ( geometry, new THREE .MeshLambertMaterial ( { color : (i/50 ) * 0xffffff } ) );
object.position .x = (i/50 ) * 800 - 400 ;
object.position .y = (i/50 ) * 800 - 400 ;
object.position .z = (i/50 ) * 800 - 400 ;
object.rotation .x = ( (i/50 ) * 360 ) * Math .PI / 180 ;
object.rotation .y = ( (i/50 ) * 360 ) * Math .PI / 180 ;
object.rotation .z = ( (i/50 ) * 360 ) * Math .PI / 180 ;
object.scale .x = (i/50 ) * 2 + 1 ;
object.scale .y = (i/50 ) * 2 + 1 ;
object.scale .z = (i/50 ) * 2 + 1 ;
THREE .GeometryUtils .merge (combGeometry, object );
}
var object = new THREE .Mesh ( combGeometry, new THREE .MeshLambertMaterial ( { color : 0.5 * 0xffffff } ) );
combined.add (object);
object.updateMatrixWorld ();
var vector = new THREE .Vector 3( 0 , 0 , 1 );
projector = new THREE .Projector ();
projector.unprojectVector ( vector, camera );
var ray1= new orig_ray ( camera.position , vector.subSelf ( camera.position ).normalize () );
var ray2= new local_ray ( camera.position , vector.subSelf ( camera.position ).normalize () );
var ray3= new optimized_local_ray ( camera.position , vector.subSelf ( camera.position ).normalize () );
Teardown JS