Przeglądaj źródła

Refactoring and optimizations in collision system and examples.

Mainly trying to avoid creation of new object per frame and also some variable names clarifications and whitespace cleanups.

Not finished yet.
alteredq 14 lat temu
rodzic
commit
f221b853b7

+ 4 - 4
build/Three.js

@@ -335,17 +335,17 @@ THREE.RenderableFace3=function(){this.v1=new THREE.RenderableVertex;this.v2=new
 THREE.RenderableFace4=function(){this.v1=new THREE.RenderableVertex;this.v2=new THREE.RenderableVertex;this.v3=new THREE.RenderableVertex;this.v4=new THREE.RenderableVertex;this.centroidWorld=new THREE.Vector3;this.centroidScreen=new THREE.Vector3;this.normalWorld=new THREE.Vector3;this.vertexNormalsWorld=[new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3];this.faceMaterials=this.meshMaterials=null;this.overdraw=!1;this.uvs=[[]];this.z=null};
 THREE.RenderableObject=function(){this.z=this.object=null};THREE.RenderableParticle=function(){this.rotation=this.z=this.y=this.x=null;this.scale=new THREE.Vector2;this.materials=null};THREE.RenderableLine=function(){this.z=null;this.v1=new THREE.RenderableVertex;this.v2=new THREE.RenderableVertex;this.materials=null};THREE.PlaneCollider=function(b,c){this.point=b;this.normal=c};THREE.SphereCollider=function(b,c){this.center=b;this.radius=c;this.radiusSq=c*c};
 THREE.BoxCollider=function(b,c){this.min=b;this.max=c;this.dynamic=!0};THREE.MeshCollider=function(b,c,d,f){this.vertices=b;this.faces=c;this.normals=d;this.box=f;this.numFaces=this.faces.length};THREE.CollisionSystem=function(){this.colliders=[];this.hits=[]};THREE.Collisions=new THREE.CollisionSystem;
-THREE.CollisionSystem.prototype.rayCastAll=function(b){b.direction.normalize();var c=0;for(var d=this.hits.length=0;d<this.colliders.length;d++){var f=this.rayCast(b,this.colliders[d]);if(f<Number.MAX_VALUE){this.colliders[d].distance=f;f>c?this.hits.push(this.colliders[d]):this.hits.unshift(this.colliders[d]);c=f}}return this.hits};
+THREE.CollisionSystem.prototype.rayCastAll=function(b){b.direction.normalize();this.hits.length=0;var c,d,f,g,h=0;c=0;for(d=this.colliders.length;c<d;c++){g=this.colliders[c];f=this.rayCast(b,g);if(f<Number.MAX_VALUE){g.distance=f;f>h?this.hits.push(g):this.hits.unshift(g);h=f}}return this.hits};
 THREE.CollisionSystem.prototype.rayCastNearest=function(b){var c=this.rayCastAll(b);if(c.length==0)return null;for(var d=0;c[d]instanceof THREE.MeshCollider;){var f=this.rayMesh(b,c[d]);if(f<Number.MAX_VALUE){c[d].distance=f;break}d++}if(d>c.length)return null;return c[d]};
 THREE.CollisionSystem.prototype.rayCast=function(b,c){if(c instanceof THREE.PlaneCollider)return this.rayPlane(b,c);else if(c instanceof THREE.SphereCollider)return this.raySphere(b,c);else if(c instanceof THREE.BoxCollider)return this.rayBox(b,c);else if(c instanceof THREE.MeshCollider&&c.box)return this.rayBox(b,c.box)};
 THREE.CollisionSystem.prototype.rayMesh=function(b,c){for(var d=this.makeRayLocal(b,c.mesh),f=Number.MAX_VALUE,g=0;g<c.numFaces/3;g++){var h=g*3;f=Math.min(f,this.rayTriangle(d,c.vertices[c.faces[h+0]],c.vertices[c.faces[h+1]],c.vertices[c.faces[h+2]],c.normals[c.faces[g]],f))}return f};
-THREE.CollisionSystem.prototype.rayTriangle=function(b,c,d,f,g,h){var j=(new THREE.Vector3).sub(d,c);g=(new THREE.Vector3).sub(f,d);g=(new THREE.Vector3).cross(j,g);var k=g.dot(b.direction);if(!(k<0))return Number.MAX_VALUE;j=g.dot(c)-g.dot(b.origin);if(!(j<=0))return Number.MAX_VALUE;if(!(j>=k*h))return Number.MAX_VALUE;j/=k;k=b.origin.clone().addSelf(b.direction.clone().multiplyScalar(j));if(Math.abs(g.x)>Math.abs(g.y))if(Math.abs(g.x)>Math.abs(g.z)){b=k.y-c.y;h=d.y-c.y;g=f.y-c.y;k=k.z-c.z;d=d.z-
-c.z;f=f.z-c.z}else{b=k.x-c.x;h=d.x-c.x;g=f.x-c.x;k=k.y-c.y;d=d.y-c.y;f=f.y-c.y}else if(Math.abs(g.y)>Math.abs(g.z)){b=k.x-c.x;h=d.x-c.x;g=f.x-c.x;k=k.z-c.z;d=d.z-c.z;f=f.z-c.z}else{b=k.x-c.x;h=d.x-c.x;g=f.x-c.x;k=k.y-c.y;d=d.y-c.y;f=f.y-c.y}c=h*f-d*g;if(c==0)return Number.MAX_VALUE;c=1/c;f=(b*f-k*g)*c;if(!(f>=0))return Number.MAX_VALUE;c*=h*k-d*b;if(!(c>=0))return Number.MAX_VALUE;if(!(1-f-c>=0))return Number.MAX_VALUE;return j};
+THREE.CollisionSystem.prototype.rayTriangle=function(b,c,d,f,g,h){var j=THREE.CollisionSystem.__v1,k=THREE.CollisionSystem.__v2;j.sub(d,c);k.sub(f,d);g.cross(j,k);k=g.dot(b.direction);if(!(k<0))return Number.MAX_VALUE;j=g.dot(c)-g.dot(b.origin);if(!(j<=0))return Number.MAX_VALUE;if(!(j>=k*h))return Number.MAX_VALUE;j/=k;k=THREE.CollisionSystem.__v3;k.copy(b.direction);k.multiplyScalar(j);k.addSelf(b.origin);if(Math.abs(g.x)>Math.abs(g.y))if(Math.abs(g.x)>Math.abs(g.z)){b=k.y-c.y;g=d.y-c.y;h=f.y-c.y;
+k=k.z-c.z;d=d.z-c.z;f=f.z-c.z}else{b=k.x-c.x;g=d.x-c.x;h=f.x-c.x;k=k.y-c.y;d=d.y-c.y;f=f.y-c.y}else if(Math.abs(g.y)>Math.abs(g.z)){b=k.x-c.x;g=d.x-c.x;h=f.x-c.x;k=k.z-c.z;d=d.z-c.z;f=f.z-c.z}else{b=k.x-c.x;g=d.x-c.x;h=f.x-c.x;k=k.y-c.y;d=d.y-c.y;f=f.y-c.y}c=g*f-d*h;if(c==0)return Number.MAX_VALUE;c=1/c;f=(b*f-k*h)*c;if(!(f>=0))return Number.MAX_VALUE;c*=g*k-d*b;if(!(c>=0))return Number.MAX_VALUE;if(!(1-f-c>=0))return Number.MAX_VALUE;return j};
 THREE.CollisionSystem.prototype.makeRayLocal=function(b,c){var d=new THREE.Ray(b.origin.clone(),b.direction.clone()),f=THREE.Matrix4.makeInvert(c.matrixWorld);f.multiplyVector3(d.origin);f.rotateAxis(d.direction);d.direction.normalize();return d};
 THREE.CollisionSystem.prototype.rayBox=function(b,c){var d;d=c.dynamic&&c.mesh&&c.mesh.matrixWorld?this.makeRayLocal(b,c.mesh):new THREE.Ray(b.origin.clone(),b.direction.clone());var f=0,g=0,h=0,j=0,k=0,n=0,p=!0;if(d.origin.x<c.min.x){f=c.min.x-d.origin.x;f/=d.direction.x;p=!1;j=-1}else if(d.origin.x>c.max.x){f=c.max.x-d.origin.x;f/=d.direction.x;p=!1;j=1}if(d.origin.y<c.min.y){g=c.min.y-d.origin.y;g/=d.direction.y;p=!1;k=-1}else if(d.origin.y>c.max.y){g=c.max.y-d.origin.y;g/=d.direction.y;p=!1;k=
 1}if(d.origin.z<c.min.z){h=c.min.z-d.origin.z;h/=d.direction.z;p=!1;n=-1}else if(d.origin.z>c.max.z){h=c.max.z-d.origin.z;h/=d.direction.z;p=!1;n=1}if(p)return-1;p=0;if(g>f){p=1;f=g}if(h>f){p=2;f=h}switch(p){case 0:k=d.origin.y+d.direction.y*f;if(k<c.min.y||k>c.max.y)return Number.MAX_VALUE;d=d.origin.z+d.direction.z*f;if(d<c.min.z||d>c.max.z)return Number.MAX_VALUE;c.normal=new THREE.Vector3(j,0,0);break;case 1:j=d.origin.x+d.direction.x*f;if(j<c.min.x||j>c.max.x)return Number.MAX_VALUE;d=d.origin.z+
 d.direction.z*f;if(d<c.min.z||d>c.max.z)return Number.MAX_VALUE;c.normal=new THREE.Vector3(0,k,0);break;case 2:j=d.origin.x+d.direction.x*f;if(j<c.min.x||j>c.max.x)return Number.MAX_VALUE;k=d.origin.y+d.direction.y*f;if(k<c.min.y||k>c.max.y)return Number.MAX_VALUE;c.normal=new THREE.Vector3(0,0,n)}return f};THREE.CollisionSystem.prototype.rayPlane=function(b,c){var d=b.direction.dot(c.normal),f=c.point.dot(c.normal);if(d<0)d=(f-b.origin.dot(c.normal))/d;else return Number.MAX_VALUE;return d>0?d:Number.MAX_VALUE};
-THREE.CollisionSystem.prototype.raySphere=function(b,c){var d=c.center.clone().subSelf(b.origin);if(d.lengthSq<c.radiusSq)return-1;var f=d.dot(b.direction.clone());if(f<=0)return Number.MAX_VALUE;d=c.radiusSq-(d.lengthSq()-f*f);if(d>=0)return Math.abs(f)-Math.sqrt(d);return Number.MAX_VALUE};THREE.CollisionUtils={};
+THREE.CollisionSystem.prototype.raySphere=function(b,c){var d=c.center.clone().subSelf(b.origin);if(d.lengthSq<c.radiusSq)return-1;var f=d.dot(b.direction.clone());if(f<=0)return Number.MAX_VALUE;d=c.radiusSq-(d.lengthSq()-f*f);if(d>=0)return Math.abs(f)-Math.sqrt(d);return Number.MAX_VALUE};THREE.CollisionSystem.__v1=new THREE.Vector3;THREE.CollisionSystem.__v2=new THREE.Vector3;THREE.CollisionSystem.__v3=new THREE.Vector3;THREE.CollisionUtils={};
 THREE.CollisionUtils.MeshOBB=function(b){b.geometry.computeBoundingBox();var c=b.geometry.boundingBox,d=new THREE.Vector3(c.x[0],c.y[0],c.z[0]);c=new THREE.Vector3(c.x[1],c.y[1],c.z[1]);d=new THREE.BoxCollider(d,c);d.mesh=b;return d};THREE.CollisionUtils.MeshAABB=function(b){var c=THREE.CollisionUtils.MeshOBB(b);c.min.addSelf(b.position);c.max.addSelf(b.position);c.dynamic=!1;return c};
 THREE.CollisionUtils.MeshColliderWBox=function(b){for(var c=b.geometry.vertices,d=c.length,f=b.geometry.faces,g=f.length,h=[],j=[],k=[],n=0;n<d;n++)h.push(new THREE.Vector3(c[n].position.x,c[n].position.y,c[n].position.z));for(n=0;n<g;n++){j.push(f[n].a,f[n].b,f[n].c);k.push(new THREE.Vector3(f[n].normal.x,f[n].normal.y,f[n].normal.z))}c=new THREE.MeshCollider(h,j,k,THREE.CollisionUtils.MeshOBB(b));c.mesh=b;return c};
 var GeometryUtils={merge:function(b,c){var d=c instanceof THREE.Mesh,f=b.vertices.length,g=d?c.geometry:c,h=b.vertices,j=g.vertices,k=b.faces,n=g.faces,p=b.faceVertexUvs[0];g=g.faceVertexUvs[0];d&&c.matrixAutoUpdate&&c.updateMatrix();for(var o=0,x=j.length;o<x;o++){var y=new THREE.Vertex(j[o].position.clone());d&&c.matrix.multiplyVector3(y.position);h.push(y)}o=0;for(x=n.length;o<x;o++){j=n[o];var v,B,F=j.vertexNormals;y=j.vertexColors;if(j instanceof THREE.Face3)v=new THREE.Face3(j.a+f,j.b+f,j.c+

+ 32 - 14
examples/webgl_collisions_box.html

@@ -16,7 +16,7 @@ body {
 
 #info {
 	position: absolute;
-	top: 30px; left: 10px; width: 800px;
+	top: 30px; left: 150px; width: 800px;
 	color: #000000;
 	padding: 5px;
 	font-family: Monospace;
@@ -40,10 +40,11 @@ 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"> 
+<script type="text/javascript">
 
-var scene, camera, renderer, info, mouse2d, sun, cube, ghostCube;
+var scene, camera, renderer, info, mouse2d, sun, cube;
 
 var bounce = 0;
 
@@ -73,6 +74,11 @@ function init() {
 	
 	createCube( 200, new THREE.Vector3( 0,0,0 ) );
 
+	stats = new Stats();
+	stats.domElement.style.position = 'absolute';
+	stats.domElement.style.top = '0px';
+	container.appendChild( stats.domElement );
+
 	container.onmousemove = onDocumentMouseMove;
 	animate();
 
@@ -90,7 +96,7 @@ function createCube( s, p ) {
 
 	THREE.Collisions.colliders.push( THREE.CollisionUtils.MeshOBB( cube ) );
 
-}
+};
 
 function onDocumentMouseMove( event ) {
 
@@ -99,27 +105,34 @@ function onDocumentMouseMove( event ) {
 	mouse2d.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
 	mouse2d.z = 1;
 
-}
+};
 
 function animate() {
+
 	requestAnimationFrame( animate );
 	
 	var r = new THREE.Ray();
-	r.origin = mouse2d.clone();
+	r.origin.copy( mouse2d );
+
 	var matrix = camera.matrixWorld.clone();
 	matrix.multiplySelf( THREE.Matrix4.makeInvert( camera.projectionMatrix ) );
 	matrix.multiplyVector3( r.origin );
-	r.direction = r.origin.clone().subSelf(camera.position);
+	r.direction = r.origin.clone().subSelf( camera.position );
 
 	info.innerHTML = "";
 
-	var c = THREE.Collisions.rayCastNearest(r);
-	if(c) {
-		info.innerHTML += "Found @ distance " + c.distance;
-		c.mesh.materials[0].color = new THREE.Color(0xaa0000);
+	var c = THREE.Collisions.rayCastNearest( r );
+
+	if( c ) {
+	
+		info.innerHTML += "Found @ distance " + c.distance.toFixed(2);
+		c.mesh.materials[ 0 ].color.setHex( 0xaa0000 );
+
 	} else {
+
 		info.innerHTML += "No intersection";
-		cube.materials[0].color = new THREE.Color(0x003300);
+		cube.materials[0].color.setHex( 0x003300 );
+
 	}
 	
 	
@@ -129,12 +142,17 @@ function animate() {
 	bounce += 0.01;
 
 	renderer.render( scene, camera );
-}
+	
+	stats.update();
+
+};
 
 function vts(v) {
+
 	if(!v) return "undefined<br>";
 	else return v.x + " , " + v.y + " , " + v.z + "<br>";
-}
+
+};
 
 </script>
 

+ 65 - 28
examples/webgl_collisions_mesh.html

@@ -41,10 +41,11 @@ 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 scene, camera, renderer, info, mouse2d, sun, loader;
+var scene, camera, renderer, info, mouse2d, sun, loader, stats;
 var meshes = [];
 
 var theta = 0;
@@ -53,7 +54,12 @@ var camdist = 1500;
 var totalFaces = 0;
 var totalColliders = 0;
 
+var ray = new THREE.Ray();
+var matrix = new THREE.Matrix4(),
+	matrix2 = new THREE.Matrix4();
+
 function init() {
+
 	container = document.createElement( 'div' );
 	document.body.appendChild( container );
 	
@@ -69,7 +75,7 @@ function init() {
 
 	renderer = new THREE.WebGLRenderer();
 	renderer.setSize( window.innerWidth, window.innerHeight );
-	container.appendChild(renderer.domElement);
+	container.appendChild( renderer.domElement );
 	
 	var ambientLight = new THREE.AmbientLight( 0x606060 );
 	scene.addLight( ambientLight );
@@ -80,12 +86,20 @@ function init() {
 	
 	loadCube();
 
+	stats = new Stats();
+	stats.domElement.style.position = 'absolute';
+	stats.domElement.style.top = '0px';
+	container.appendChild( stats.domElement );
+
 	container.onmousemove = onDocumentMouseMove;
 	animate();
+
 }
 
 function loadCube(p) {
-	var onGeometry = function( geometry ) {		
+
+	var onGeometry = function( geometry ) {	
+	
 		var sx = 300;
 		var sy = 240;
 		var sz = 300;
@@ -138,7 +152,7 @@ function loadCube(p) {
 		addCube( new THREE.Vector3(	0, -sy,	-sz*2), geometry );
 		addCube( new THREE.Vector3( sx,-sy,	-sz*2), geometry );
 		
-		info.innerHTML = "Total colliders: " + totalColliders + " (Faces: " + totalFaces + ")<br>";
+		//info.innerHTML = "Total colliders: " + totalColliders + " (Faces: " + totalFaces + ")<br>";
 	
 	};
 
@@ -146,9 +160,11 @@ function loadCube(p) {
 	loader.load( { model: "obj/suzanne/suzanneHi.js", callback: onGeometry } );
 }
 
-function addCube(p, g){
+function addCube( p, g) {
+
 	totalFaces += g.faces.length;
 	totalColliders++;
+
 	var mesh = new THREE.Mesh( g, new THREE.MeshLambertMaterial( { color: 0x003300 } ) );
 	mesh.position = p;
 	
@@ -163,57 +179,78 @@ function addCube(p, g){
 	scene.addObject( mesh );
 	var mc = THREE.CollisionUtils.MeshColliderWBox(mesh);
 	THREE.Collisions.colliders.push( mc );
-	meshes.push(mesh);
-}
+	meshes.push( mesh );
+
+};
 
 function onDocumentMouseMove( event ) {
+
 	event.preventDefault();	
 	mouse2d.x = ( event.clientX / window.innerWidth ) * 2 - 1;
 	mouse2d.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
 	mouse2d.z = 1;
-}
+
+};
+
 
 function animate() {
+
 	requestAnimationFrame( animate );
 	
-	var r = new THREE.Ray();
-	r.origin = mouse2d.clone();
-	var matrix = camera.matrixWorld.clone();
-	matrix.multiplySelf( THREE.Matrix4.makeInvert( camera.projectionMatrix ) );
-	matrix.multiplyVector3( r.origin );
-	r.direction = r.origin.clone().subSelf(camera.position);
+	ray.origin.copy( mouse2d );
+
+	matrix.copy( camera.matrixWorld );
+	matrix.multiplySelf( THREE.Matrix4.makeInvert( camera.projectionMatrix, matrix2 ) );
+	matrix.multiplyVector3( ray.origin );
+	
+	ray.direction.copy( ray.origin );
+	ray.direction.subSelf( camera.position );
 	
-	if(meshes.length == 0) return;
+	if( meshes.length == 0 ) return;
 	
-	for (var i = 0; i < meshes.length; i++) {
-		meshes[i].materials[0].color = new THREE.Color(0x003300);
-	}
+	var i, l = meshes.length;
 	
-	info.innerHTML = "";
+	for ( i = 0; i < l; i++ ) {
 
-	var c = THREE.Collisions.rayCastNearest(r);
+		meshes[ i ].materials[ 0 ].color.setHex( 0x003300 );
+
+	}
+
+
+	var c = THREE.Collisions.rayCastNearest( ray );
+	
+	if( c ) {
 	
-	if(c) {
 		//info.innerHTML += "Found @ distance " + c.distance;
-		c.mesh.materials[0].color = new THREE.Color(0xbb0000);
+		c.mesh.materials[ 0 ].color.setHex( 0xbb0000 );
+
 	} else {
+	
 		//info.innerHTML += "No intersection";
+
 	}
 
-	camera.position.x = camdist * Math.cos(theta);
-	camera.position.z = camdist * Math.sin(theta);
-	camera.position.y = camdist/2 * Math.sin(theta * 2);
-	sun.position = camera.position.clone();
+	camera.position.x = camdist * Math.cos( theta );
+	camera.position.z = camdist * Math.sin( theta );
+	camera.position.y = camdist/2 * Math.sin( theta * 2) ;
+
+	sun.position.copy( camera.position );
 	sun.position.normalize();
+
 	theta += 0.005;		
 
 	renderer.render( scene, camera );
-}
+	
+	stats.update();
+	
+};
 
 function vts(v) {
+
 	if(!v) return "undefined<br>";
 	else return v.x + " , " + v.y + " , " + v.z + "<br>";
-}
+
+};
 
 </script>
 

+ 45 - 21
examples/webgl_collisions_primitives.html

@@ -18,7 +18,7 @@
             #info {
                 position: absolute;
                 top: 30px;
-                left: 10px;
+                left: 150px;
                 width: 800px;
                 color: #000000;
                 padding: 5px;
@@ -31,7 +31,7 @@
             #options {
                 position: absolute;
                 top: 10px;
-                left: 10px;
+                left: 150px;
                 width: 800px;
                 color: #000000;
                 padding: 5px;
@@ -42,10 +42,10 @@
             }
             
         </style>
-        <script type="text/javascript" src="../build/Three.js">
-        </script>
-        <script type="text/javascript" src="js/RequestAnimationFrame.js">
-        </script>
+        <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 scene, camera, renderer, info, mouse2d, sun;
@@ -97,8 +97,14 @@
                 cplane.mesh = plane;
                 THREE.Collisions.colliders.push(cplane);
                 
+				stats = new Stats();
+				stats.domElement.style.position = 'absolute';
+				stats.domElement.style.top = '0px';
+				container.appendChild( stats.domElement );
+				
                 container.onmousemove = onDocumentMouseMove;
                 animate();
+
             }
             
             function makeWall(z){
@@ -157,33 +163,49 @@
                     geoms[i].materials[0].color = new THREE.Color(0x007700);
                 }
                 
-                if (!document.getElementById("nearest").checked) {
+                if ( !document.getElementById( "nearest" ).checked ) {
+
                     // Raycast all
+
                     ts = new Date().getTime();
-                    var cs = THREE.Collisions.rayCastAll(r);
+                    var cs = THREE.Collisions.rayCastAll( r );
                     tt = new Date().getTime() - ts;
-                    if (cs.length > 0) {
+
+                    if ( cs.length > 0 ) {
+
                         info.innerHTML = cs.length + " colliders found in " + tt;
-                        for (var i = 0; i < cs.length; i++) {
-                            cs[i].mesh.materials[0].color = new THREE.Color(0xaa0000);
+
+                        for ( var i = 0; i < cs.length; i++ ) {
+						
+                            cs[ i ].mesh.materials[ 0 ].color.setHex( 0xaa0000 );
+
                         }
-                    }
-                    else {
+
+                    } else {
+
                         info.innerHTML = "No intersection";
+
                     }
-                }
-                else {
+
+                } else {
+				
                     // Raycast nearest
+
                     ts = new Date().getTime();
-                    var c = THREE.Collisions.rayCastNearest(r);
+                    var c = THREE.Collisions.rayCastNearest( r );
                     tt = new Date().getTime() - ts;
-                    if (c) {
+
+                    if ( c ) {
+
                         info.innerHTML = "Found in " + tt + " @ distance " + c.distance;
-                        c.mesh.materials[0].color = new THREE.Color(0xaa0000);
-                    }
-                    else {
+                        c.mesh.materials[ 0 ].color.setHex( 0xaa0000 );
+
+                    } else {
+
                         info.innerHTML = "No intersection";
+
                     }
+
                 }
                 
                 camera.position.x = camdist * Math.cos(theta);
@@ -193,7 +215,9 @@
                 sun.position.normalize();
                 theta += 0.005;
                 
-                renderer.render(scene, camera);
+                renderer.render( scene, camera );
+				
+				stats.update();
             }
             
             function vts(v){

+ 1 - 1
src/objects/Mesh.js

@@ -23,7 +23,7 @@ THREE.Mesh = function ( geometry, materials ) {
 
 		if( !this.geometry.boundingSphere ) {
 
-			 this.geometry.computeBoundingSphere();
+			this.geometry.computeBoundingSphere();
 
 		}
 

+ 39 - 24
src/physics/Collisions.js

@@ -45,25 +45,29 @@ THREE.CollisionSystem = function() {
 
 THREE.Collisions = new THREE.CollisionSystem();
 
-THREE.CollisionSystem.prototype.rayCastAll = function( r ) {
+THREE.CollisionSystem.prototype.rayCastAll = function( ray ) {
 
-	r.direction.normalize();
+	ray.direction.normalize();
 
-	var ld = 0;	
 	this.hits.length = 0;
+
+	var i, l, d, collider,
+		ld = 0;	
 	
-	for ( var i = 0; i < this.colliders.length; i++ ) {
+	for ( i = 0, l = this.colliders.length; i < l; i++ ) {
 
-		var d = this.rayCast( r, this.colliders[ i ] );	
+		collider = this.colliders[ i ];
+		
+		d = this.rayCast( ray, collider );	
 		
 		if ( d < Number.MAX_VALUE ) {
 
-			this.colliders[ i ].distance = d;
+			collider.distance = d;
 
 			if ( d > ld ) 
-				this.hits.push( this.colliders[ i ] );
+				this.hits.push( collider );
 			else 
-				this.hits.unshift( this.colliders[ i ] );
+				this.hits.unshift( collider );
 
 			ld = d;
 
@@ -75,17 +79,17 @@ THREE.CollisionSystem.prototype.rayCastAll = function( r ) {
 
 };
 
-THREE.CollisionSystem.prototype.rayCastNearest = function( r ) {
+THREE.CollisionSystem.prototype.rayCastNearest = function( ray ) {
 
-	var cs = this.rayCastAll( r );
+	var cs = this.rayCastAll( ray );
 	
 	if( cs.length == 0 ) return null;
 	
 	var i = 0;
 
-	while( cs[i] instanceof THREE.MeshCollider ) {
+	while( cs[ i ] instanceof THREE.MeshCollider ) {
 
-		var d = this.rayMesh( r, cs[ i ] );
+		var d = this.rayMesh( ray, cs[ i ] );
 
 		if( d < Number.MAX_VALUE ) {
 
@@ -143,26 +147,32 @@ THREE.CollisionSystem.prototype.rayMesh = function( r, me ) {
 
 };
 
-THREE.CollisionSystem.prototype.rayTriangle = function( r, p0, p1, p2, n, mind ) {
-
-	//if (!n) {
-		var e1 = new THREE.Vector3().sub( p1, p0 );
-		var e2 = new THREE.Vector3().sub( p2, p1 );
-		n = new THREE.Vector3().cross( e1, e2 );
-	//}
+THREE.CollisionSystem.prototype.rayTriangle = function( ray, p0, p1, p2, n, mind ) {
+	
+	var e1 = THREE.CollisionSystem.__v1, 
+		e2 = THREE.CollisionSystem.__v2;
+	
+	e1.sub( p1, p0 );
+	e2.sub( p2, p1 );
+	n.cross( e1, e2 )
 	
-	var dot = n.dot( r.direction );
+	var dot = n.dot( ray.direction );
 	if ( !( dot < 0 ) ) return Number.MAX_VALUE;
 
 	var d = n.dot( p0 );
-	var t = d - n.dot( r.origin );
+	var t = d - n.dot( ray.origin );
 	
 	if ( !( t <= 0 ) ) return Number.MAX_VALUE;
 	if ( !( t >= dot * mind ) ) return Number.MAX_VALUE;
 	
 	t = t / dot;
 
-	var p = r.origin.clone().addSelf( r.direction.clone().multiplyScalar( t ) );
+	var p = THREE.CollisionSystem.__v3;
+
+	p.copy( ray.direction );
+	p.multiplyScalar( t );
+	p.addSelf( ray.origin );
+	
 	var u0, u1, u2, v0, v1, v2;
 
 	if ( Math.abs( n.x ) > Math.abs( n.y ) ) {
@@ -236,9 +246,9 @@ THREE.CollisionSystem.prototype.rayTriangle = function( r, p0, p1, p2, n, mind )
 
 };
 
-THREE.CollisionSystem.prototype.makeRayLocal = function( r, m ) {
+THREE.CollisionSystem.prototype.makeRayLocal = function( ray, m ) {
 
-	var rt = new THREE.Ray( r.origin.clone(), r.direction.clone() );
+	var rt = new THREE.Ray( ray.origin.clone(), ray.direction.clone() );
 	var mt = THREE.Matrix4.makeInvert( m.matrixWorld );
 
 	mt.multiplyVector3( rt.origin );
@@ -404,6 +414,11 @@ THREE.CollisionSystem.prototype.raySphere = function( r, s ) {
 
 };
 
+THREE.CollisionSystem.__v1 = new THREE.Vector3();
+THREE.CollisionSystem.__v2 = new THREE.Vector3();
+THREE.CollisionSystem.__v3 = new THREE.Vector3();
+
+