Browse Source

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 years ago
parent
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.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.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.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.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.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.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.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=
 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+
 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};
 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.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};
 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+
 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 {
 #info {
 	position: absolute;
 	position: absolute;
-	top: 30px; left: 10px; width: 800px;
+	top: 30px; left: 150px; width: 800px;
 	color: #000000;
 	color: #000000;
 	padding: 5px;
 	padding: 5px;
 	font-family: Monospace;
 	font-family: Monospace;
@@ -40,10 +40,11 @@ body {
 
 
 <script type="text/javascript" src="../build/Three.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/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;
 var bounce = 0;
 
 
@@ -73,6 +74,11 @@ function init() {
 	
 	
 	createCube( 200, new THREE.Vector3( 0,0,0 ) );
 	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;
 	container.onmousemove = onDocumentMouseMove;
 	animate();
 	animate();
 
 
@@ -90,7 +96,7 @@ function createCube( s, p ) {
 
 
 	THREE.Collisions.colliders.push( THREE.CollisionUtils.MeshOBB( cube ) );
 	THREE.Collisions.colliders.push( THREE.CollisionUtils.MeshOBB( cube ) );
 
 
-}
+};
 
 
 function onDocumentMouseMove( event ) {
 function onDocumentMouseMove( event ) {
 
 
@@ -99,27 +105,34 @@ function onDocumentMouseMove( event ) {
 	mouse2d.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
 	mouse2d.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
 	mouse2d.z = 1;
 	mouse2d.z = 1;
 
 
-}
+};
 
 
 function animate() {
 function animate() {
+
 	requestAnimationFrame( animate );
 	requestAnimationFrame( animate );
 	
 	
 	var r = new THREE.Ray();
 	var r = new THREE.Ray();
-	r.origin = mouse2d.clone();
+	r.origin.copy( mouse2d );
+
 	var matrix = camera.matrixWorld.clone();
 	var matrix = camera.matrixWorld.clone();
 	matrix.multiplySelf( THREE.Matrix4.makeInvert( camera.projectionMatrix ) );
 	matrix.multiplySelf( THREE.Matrix4.makeInvert( camera.projectionMatrix ) );
 	matrix.multiplyVector3( r.origin );
 	matrix.multiplyVector3( r.origin );
-	r.direction = r.origin.clone().subSelf(camera.position);
+	r.direction = r.origin.clone().subSelf( camera.position );
 
 
 	info.innerHTML = "";
 	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 {
 	} else {
+
 		info.innerHTML += "No intersection";
 		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;
 	bounce += 0.01;
 
 
 	renderer.render( scene, camera );
 	renderer.render( scene, camera );
-}
+	
+	stats.update();
+
+};
 
 
 function vts(v) {
 function vts(v) {
+
 	if(!v) return "undefined<br>";
 	if(!v) return "undefined<br>";
 	else return v.x + " , " + v.y + " , " + v.z + "<br>";
 	else return v.x + " , " + v.y + " , " + v.z + "<br>";
-}
+
+};
 
 
 </script>
 </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="../build/Three.js"></script> 
 <script type="text/javascript" src="js/RequestAnimationFrame.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, loader;
+var scene, camera, renderer, info, mouse2d, sun, loader, stats;
 var meshes = [];
 var meshes = [];
 
 
 var theta = 0;
 var theta = 0;
@@ -53,7 +54,12 @@ var camdist = 1500;
 var totalFaces = 0;
 var totalFaces = 0;
 var totalColliders = 0;
 var totalColliders = 0;
 
 
+var ray = new THREE.Ray();
+var matrix = new THREE.Matrix4(),
+	matrix2 = new THREE.Matrix4();
+
 function init() {
 function init() {
+
 	container = document.createElement( 'div' );
 	container = document.createElement( 'div' );
 	document.body.appendChild( container );
 	document.body.appendChild( container );
 	
 	
@@ -69,7 +75,7 @@ function init() {
 
 
 	renderer = new THREE.WebGLRenderer();
 	renderer = new THREE.WebGLRenderer();
 	renderer.setSize( window.innerWidth, window.innerHeight );
 	renderer.setSize( window.innerWidth, window.innerHeight );
-	container.appendChild(renderer.domElement);
+	container.appendChild( renderer.domElement );
 	
 	
 	var ambientLight = new THREE.AmbientLight( 0x606060 );
 	var ambientLight = new THREE.AmbientLight( 0x606060 );
 	scene.addLight( ambientLight );
 	scene.addLight( ambientLight );
@@ -80,12 +86,20 @@ function init() {
 	
 	
 	loadCube();
 	loadCube();
 
 
+	stats = new Stats();
+	stats.domElement.style.position = 'absolute';
+	stats.domElement.style.top = '0px';
+	container.appendChild( stats.domElement );
+
 	container.onmousemove = onDocumentMouseMove;
 	container.onmousemove = onDocumentMouseMove;
 	animate();
 	animate();
+
 }
 }
 
 
 function loadCube(p) {
 function loadCube(p) {
-	var onGeometry = function( geometry ) {		
+
+	var onGeometry = function( geometry ) {	
+	
 		var sx = 300;
 		var sx = 300;
 		var sy = 240;
 		var sy = 240;
 		var sz = 300;
 		var sz = 300;
@@ -138,7 +152,7 @@ function loadCube(p) {
 		addCube( new THREE.Vector3(	0, -sy,	-sz*2), geometry );
 		addCube( new THREE.Vector3(	0, -sy,	-sz*2), geometry );
 		addCube( new THREE.Vector3( sx,-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 } );
 	loader.load( { model: "obj/suzanne/suzanneHi.js", callback: onGeometry } );
 }
 }
 
 
-function addCube(p, g){
+function addCube( p, g) {
+
 	totalFaces += g.faces.length;
 	totalFaces += g.faces.length;
 	totalColliders++;
 	totalColliders++;
+
 	var mesh = new THREE.Mesh( g, new THREE.MeshLambertMaterial( { color: 0x003300 } ) );
 	var mesh = new THREE.Mesh( g, new THREE.MeshLambertMaterial( { color: 0x003300 } ) );
 	mesh.position = p;
 	mesh.position = p;
 	
 	
@@ -163,57 +179,78 @@ function addCube(p, g){
 	scene.addObject( mesh );
 	scene.addObject( mesh );
 	var mc = THREE.CollisionUtils.MeshColliderWBox(mesh);
 	var mc = THREE.CollisionUtils.MeshColliderWBox(mesh);
 	THREE.Collisions.colliders.push( mc );
 	THREE.Collisions.colliders.push( mc );
-	meshes.push(mesh);
-}
+	meshes.push( mesh );
+
+};
 
 
 function onDocumentMouseMove( event ) {
 function onDocumentMouseMove( event ) {
+
 	event.preventDefault();	
 	event.preventDefault();	
 	mouse2d.x = ( event.clientX / window.innerWidth ) * 2 - 1;
 	mouse2d.x = ( event.clientX / window.innerWidth ) * 2 - 1;
 	mouse2d.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
 	mouse2d.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
 	mouse2d.z = 1;
 	mouse2d.z = 1;
-}
+
+};
+
 
 
 function animate() {
 function animate() {
+
 	requestAnimationFrame( 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;
 		//info.innerHTML += "Found @ distance " + c.distance;
-		c.mesh.materials[0].color = new THREE.Color(0xbb0000);
+		c.mesh.materials[ 0 ].color.setHex( 0xbb0000 );
+
 	} else {
 	} else {
+	
 		//info.innerHTML += "No intersection";
 		//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();
 	sun.position.normalize();
+
 	theta += 0.005;		
 	theta += 0.005;		
 
 
 	renderer.render( scene, camera );
 	renderer.render( scene, camera );
-}
+	
+	stats.update();
+	
+};
 
 
 function vts(v) {
 function vts(v) {
+
 	if(!v) return "undefined<br>";
 	if(!v) return "undefined<br>";
 	else return v.x + " , " + v.y + " , " + v.z + "<br>";
 	else return v.x + " , " + v.y + " , " + v.z + "<br>";
-}
+
+};
 
 
 </script>
 </script>
 
 

+ 45 - 21
examples/webgl_collisions_primitives.html

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

+ 1 - 1
src/objects/Mesh.js

@@ -23,7 +23,7 @@ THREE.Mesh = function ( geometry, materials ) {
 
 
 		if( !this.geometry.boundingSphere ) {
 		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.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;
 	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 ) {
 		if ( d < Number.MAX_VALUE ) {
 
 
-			this.colliders[ i ].distance = d;
+			collider.distance = d;
 
 
 			if ( d > ld ) 
 			if ( d > ld ) 
-				this.hits.push( this.colliders[ i ] );
+				this.hits.push( collider );
 			else 
 			else 
-				this.hits.unshift( this.colliders[ i ] );
+				this.hits.unshift( collider );
 
 
 			ld = d;
 			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;
 	if( cs.length == 0 ) return null;
 	
 	
 	var i = 0;
 	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 ) {
 		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;
 	if ( !( dot < 0 ) ) return Number.MAX_VALUE;
 
 
 	var d = n.dot( p0 );
 	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 <= 0 ) ) return Number.MAX_VALUE;
 	if ( !( t >= dot * mind ) ) return Number.MAX_VALUE;
 	if ( !( t >= dot * mind ) ) return Number.MAX_VALUE;
 	
 	
 	t = t / dot;
 	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;
 	var u0, u1, u2, v0, v1, v2;
 
 
 	if ( Math.abs( n.x ) > Math.abs( n.y ) ) {
 	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 );
 	var mt = THREE.Matrix4.makeInvert( m.matrixWorld );
 
 
 	mt.multiplyVector3( rt.origin );
 	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();
+
+