Browse Source

Simpler GeometryUtils.triangleArea()

Surprisingly the effect on performance is minimal, despite doing quite much less operations. Yet again raw math performance doesn't seem to matter.
alteredq 12 years ago
parent
commit
f3e0205f50
3 changed files with 27 additions and 39 deletions
  1. 9 15
      build/three.js
  2. 9 9
      build/three.min.js
  3. 9 15
      src/extras/GeometryUtils.js

+ 9 - 15
build/three.js

@@ -23516,26 +23516,19 @@ THREE.GeometryUtils = {
 
 	},
 
-	// Get triangle area (by Heron's formula)
-	// 	http://en.wikipedia.org/wiki/Heron%27s_formula
+	// Get triangle area (half of parallelogram)
+	//	http://mathworld.wolfram.com/TriangleArea.html
 
 	triangleArea: function ( vectorA, vectorB, vectorC ) {
 
-		var s, a, b, c,
-			tmp = THREE.GeometryUtils.__v1;
-
-		tmp.sub( vectorA, vectorB );
-		a = tmp.length();
-
-		tmp.sub( vectorA, vectorC );
-		b = tmp.length();
-
-		tmp.sub( vectorB, vectorC );
-		c = tmp.length();
+		var tmp1 = THREE.GeometryUtils.__v1,
+			tmp2 = THREE.GeometryUtils.__v2;
 
-		s = 0.5 * ( a + b + c );
+		tmp1.sub( vectorB, vectorA );
+		tmp2.sub( vectorC, vectorA );
+		tmp1.crossSelf( tmp2 );
 
-		return Math.sqrt( s * ( s - a ) * ( s - b ) * ( s - c ) );
+		return 0.5 * tmp1.length();
 
 	},
 
@@ -24207,6 +24200,7 @@ THREE.GeometryUtils = {
 THREE.GeometryUtils.random = THREE.Math.random16;
 
 THREE.GeometryUtils.__v1 = new THREE.Vector3();
+THREE.GeometryUtils.__v2 = new THREE.Vector3();
 /**
  * @author alteredq / http://alteredqualia.com/
  * @author mrdoob / http://mrdoob.com/

+ 9 - 9
build/three.min.js

@@ -458,21 +458,21 @@ q=new THREE.Face3(r.a+e,r.b+e,r.c+e):r instanceof THREE.Face4&&(q=new THREE.Face
 h;g++)d.push(new THREE.UV(c[g].u,c[g].v));l.push(d)}},removeMaterials:function(a,b){for(var c={},d=0,e=b.length;d<e;d++)c[b[d]]=!0;for(var f,g=[],d=0,e=a.faces.length;d<e;d++)f=a.faces[d],f.materialIndex in c||g.push(f);a.faces=g},randomPointInTriangle:function(a,b,c){var d,e,f,g=new THREE.Vector3,h=THREE.GeometryUtils.__v1;d=THREE.GeometryUtils.random();e=THREE.GeometryUtils.random();1<d+e&&(d=1-d,e=1-e);f=1-d-e;g.copy(a);g.multiplyScalar(d);h.copy(b);h.multiplyScalar(e);g.addSelf(h);h.copy(c);h.multiplyScalar(f);
 g.addSelf(h);return g},randomPointInFace:function(a,b,c){var d,e,f;if(a instanceof THREE.Face3)return d=b.vertices[a.a],e=b.vertices[a.b],f=b.vertices[a.c],THREE.GeometryUtils.randomPointInTriangle(d,e,f);if(a instanceof THREE.Face4){d=b.vertices[a.a];e=b.vertices[a.b];f=b.vertices[a.c];var b=b.vertices[a.d],g;c?a._area1&&a._area2?(c=a._area1,g=a._area2):(c=THREE.GeometryUtils.triangleArea(d,e,b),g=THREE.GeometryUtils.triangleArea(e,f,b),a._area1=c,a._area2=g):(c=THREE.GeometryUtils.triangleArea(d,
 e,b),g=THREE.GeometryUtils.triangleArea(e,f,b));return THREE.GeometryUtils.random()*(c+g)<c?THREE.GeometryUtils.randomPointInTriangle(d,e,b):THREE.GeometryUtils.randomPointInTriangle(e,f,b)}},randomPointsInGeometry:function(a,b){function c(a){function b(c,d){if(d<c)return c;var e=c+Math.floor((d-c)/2);return j[e]>a?b(c,e-1):j[e]<a?b(e+1,d):e}return b(0,j.length-1)}var d,e,f=a.faces,g=a.vertices,h=f.length,i=0,j=[],l,p,n,r;for(e=0;e<h;e++)d=f[e],d instanceof THREE.Face3?(l=g[d.a],p=g[d.b],n=g[d.c],
-d._area=THREE.GeometryUtils.triangleArea(l,p,n)):d instanceof THREE.Face4&&(l=g[d.a],p=g[d.b],n=g[d.c],r=g[d.d],d._area1=THREE.GeometryUtils.triangleArea(l,p,r),d._area2=THREE.GeometryUtils.triangleArea(p,n,r),d._area=d._area1+d._area2),i+=d._area,j[e]=i;d=[];for(e=0;e<b;e++)g=THREE.GeometryUtils.random()*i,g=c(g),d[e]=THREE.GeometryUtils.randomPointInFace(f[g],a,!0);return d},triangleArea:function(a,b,c){var d,e=THREE.GeometryUtils.__v1;e.sub(a,b);d=e.length();e.sub(a,c);a=e.length();e.sub(b,c);
-c=e.length();b=0.5*(d+a+c);return Math.sqrt(b*(b-d)*(b-a)*(b-c))},center:function(a){a.computeBoundingBox();var b=a.boundingBox,c=new THREE.Vector3;c.add(b.min,b.max);c.multiplyScalar(-0.5);a.applyMatrix((new THREE.Matrix4).makeTranslation(c.x,c.y,c.z));a.computeBoundingBox();return c},normalizeUVs:function(a){for(var a=a.faceVertexUvs[0],b=0,c=a.length;b<c;b++)for(var d=a[b],e=0,f=d.length;e<f;e++)1!==d[e].u&&(d[e].u-=Math.floor(d[e].u)),1!==d[e].v&&(d[e].v-=Math.floor(d[e].v))},triangulateQuads:function(a){var b,
-c,d,e,f=[],g=[],h=[];b=0;for(c=a.faceUvs.length;b<c;b++)g[b]=[];b=0;for(c=a.faceVertexUvs.length;b<c;b++)h[b]=[];b=0;for(c=a.faces.length;b<c;b++)if(d=a.faces[b],d instanceof THREE.Face4){e=d.a;var i=d.b,j=d.c,l=d.d,p=new THREE.Face3,n=new THREE.Face3;p.color.copy(d.color);n.color.copy(d.color);p.materialIndex=d.materialIndex;n.materialIndex=d.materialIndex;p.a=e;p.b=i;p.c=l;n.a=i;n.b=j;n.c=l;4===d.vertexColors.length&&(p.vertexColors[0]=d.vertexColors[0].clone(),p.vertexColors[1]=d.vertexColors[1].clone(),
-p.vertexColors[2]=d.vertexColors[3].clone(),n.vertexColors[0]=d.vertexColors[1].clone(),n.vertexColors[1]=d.vertexColors[2].clone(),n.vertexColors[2]=d.vertexColors[3].clone());f.push(p,n);d=0;for(e=a.faceVertexUvs.length;d<e;d++)a.faceVertexUvs[d].length&&(p=a.faceVertexUvs[d][b],i=p[1],j=p[2],l=p[3],p=[p[0].clone(),i.clone(),l.clone()],i=[i.clone(),j.clone(),l.clone()],h[d].push(p,i));d=0;for(e=a.faceUvs.length;d<e;d++)a.faceUvs[d].length&&(i=a.faceUvs[d][b],g[d].push(i,i))}else{f.push(d);d=0;for(e=
-a.faceUvs.length;d<e;d++)g[d].push(a.faceUvs[d][b]);d=0;for(e=a.faceVertexUvs.length;d<e;d++)h[d].push(a.faceVertexUvs[d][b])}a.faces=f;a.faceUvs=g;a.faceVertexUvs=h;a.computeCentroids();a.computeFaceNormals();a.computeVertexNormals();a.hasTangents&&a.computeTangents()},explode:function(a){for(var b=[],c=0,d=a.faces.length;c<d;c++){var e=b.length,f=a.faces[c];if(f instanceof THREE.Face4){var g=f.a,h=f.b,i=f.c,g=a.vertices[g],h=a.vertices[h],i=a.vertices[i],j=a.vertices[f.d];b.push(g.clone());b.push(h.clone());
-b.push(i.clone());b.push(j.clone());f.a=e;f.b=e+1;f.c=e+2;f.d=e+3}else g=f.a,h=f.b,i=f.c,g=a.vertices[g],h=a.vertices[h],i=a.vertices[i],b.push(g.clone()),b.push(h.clone()),b.push(i.clone()),f.a=e,f.b=e+1,f.c=e+2}a.vertices=b;delete a.__tmpVertices},tessellate:function(a,b){var c,d,e,f,g,h,i,j,l,p,n,r,q,m,t,u,E,B,s,F=[],A=[];c=0;for(d=a.faceVertexUvs.length;c<d;c++)A[c]=[];c=0;for(d=a.faces.length;c<d;c++)if(e=a.faces[c],e instanceof THREE.Face3)if(f=e.a,g=e.b,h=e.c,j=a.vertices[f],l=a.vertices[g],
-p=a.vertices[h],r=j.distanceTo(l),q=l.distanceTo(p),n=j.distanceTo(p),r>b||q>b||n>b){i=a.vertices.length;B=e.clone();s=e.clone();r>=q&&r>=n?(j=j.clone(),j.lerpSelf(l,0.5),B.a=f,B.b=i,B.c=h,s.a=i,s.b=g,s.c=h,3===e.vertexNormals.length&&(f=e.vertexNormals[0].clone(),f.lerpSelf(e.vertexNormals[1],0.5),B.vertexNormals[1].copy(f),s.vertexNormals[0].copy(f)),3===e.vertexColors.length&&(f=e.vertexColors[0].clone(),f.lerpSelf(e.vertexColors[1],0.5),B.vertexColors[1].copy(f),s.vertexColors[0].copy(f)),e=0):
-q>=r&&q>=n?(j=l.clone(),j.lerpSelf(p,0.5),B.a=f,B.b=g,B.c=i,s.a=i,s.b=h,s.c=f,3===e.vertexNormals.length&&(f=e.vertexNormals[1].clone(),f.lerpSelf(e.vertexNormals[2],0.5),B.vertexNormals[2].copy(f),s.vertexNormals[0].copy(f),s.vertexNormals[1].copy(e.vertexNormals[2]),s.vertexNormals[2].copy(e.vertexNormals[0])),3===e.vertexColors.length&&(f=e.vertexColors[1].clone(),f.lerpSelf(e.vertexColors[2],0.5),B.vertexColors[2].copy(f),s.vertexColors[0].copy(f),s.vertexColors[1].copy(e.vertexColors[2]),s.vertexColors[2].copy(e.vertexColors[0])),
+d._area=THREE.GeometryUtils.triangleArea(l,p,n)):d instanceof THREE.Face4&&(l=g[d.a],p=g[d.b],n=g[d.c],r=g[d.d],d._area1=THREE.GeometryUtils.triangleArea(l,p,r),d._area2=THREE.GeometryUtils.triangleArea(p,n,r),d._area=d._area1+d._area2),i+=d._area,j[e]=i;d=[];for(e=0;e<b;e++)g=THREE.GeometryUtils.random()*i,g=c(g),d[e]=THREE.GeometryUtils.randomPointInFace(f[g],a,!0);return d},triangleArea:function(a,b,c){var d=THREE.GeometryUtils.__v1,e=THREE.GeometryUtils.__v2;d.sub(b,a);e.sub(c,a);d.crossSelf(e);
+return 0.5*d.length()},center:function(a){a.computeBoundingBox();var b=a.boundingBox,c=new THREE.Vector3;c.add(b.min,b.max);c.multiplyScalar(-0.5);a.applyMatrix((new THREE.Matrix4).makeTranslation(c.x,c.y,c.z));a.computeBoundingBox();return c},normalizeUVs:function(a){for(var a=a.faceVertexUvs[0],b=0,c=a.length;b<c;b++)for(var d=a[b],e=0,f=d.length;e<f;e++)1!==d[e].u&&(d[e].u-=Math.floor(d[e].u)),1!==d[e].v&&(d[e].v-=Math.floor(d[e].v))},triangulateQuads:function(a){var b,c,d,e,f=[],g=[],h=[];b=0;
+for(c=a.faceUvs.length;b<c;b++)g[b]=[];b=0;for(c=a.faceVertexUvs.length;b<c;b++)h[b]=[];b=0;for(c=a.faces.length;b<c;b++)if(d=a.faces[b],d instanceof THREE.Face4){e=d.a;var i=d.b,j=d.c,l=d.d,p=new THREE.Face3,n=new THREE.Face3;p.color.copy(d.color);n.color.copy(d.color);p.materialIndex=d.materialIndex;n.materialIndex=d.materialIndex;p.a=e;p.b=i;p.c=l;n.a=i;n.b=j;n.c=l;4===d.vertexColors.length&&(p.vertexColors[0]=d.vertexColors[0].clone(),p.vertexColors[1]=d.vertexColors[1].clone(),p.vertexColors[2]=
+d.vertexColors[3].clone(),n.vertexColors[0]=d.vertexColors[1].clone(),n.vertexColors[1]=d.vertexColors[2].clone(),n.vertexColors[2]=d.vertexColors[3].clone());f.push(p,n);d=0;for(e=a.faceVertexUvs.length;d<e;d++)a.faceVertexUvs[d].length&&(p=a.faceVertexUvs[d][b],i=p[1],j=p[2],l=p[3],p=[p[0].clone(),i.clone(),l.clone()],i=[i.clone(),j.clone(),l.clone()],h[d].push(p,i));d=0;for(e=a.faceUvs.length;d<e;d++)a.faceUvs[d].length&&(i=a.faceUvs[d][b],g[d].push(i,i))}else{f.push(d);d=0;for(e=a.faceUvs.length;d<
+e;d++)g[d].push(a.faceUvs[d][b]);d=0;for(e=a.faceVertexUvs.length;d<e;d++)h[d].push(a.faceVertexUvs[d][b])}a.faces=f;a.faceUvs=g;a.faceVertexUvs=h;a.computeCentroids();a.computeFaceNormals();a.computeVertexNormals();a.hasTangents&&a.computeTangents()},explode:function(a){for(var b=[],c=0,d=a.faces.length;c<d;c++){var e=b.length,f=a.faces[c];if(f instanceof THREE.Face4){var g=f.a,h=f.b,i=f.c,g=a.vertices[g],h=a.vertices[h],i=a.vertices[i],j=a.vertices[f.d];b.push(g.clone());b.push(h.clone());b.push(i.clone());
+b.push(j.clone());f.a=e;f.b=e+1;f.c=e+2;f.d=e+3}else g=f.a,h=f.b,i=f.c,g=a.vertices[g],h=a.vertices[h],i=a.vertices[i],b.push(g.clone()),b.push(h.clone()),b.push(i.clone()),f.a=e,f.b=e+1,f.c=e+2}a.vertices=b;delete a.__tmpVertices},tessellate:function(a,b){var c,d,e,f,g,h,i,j,l,p,n,r,q,m,t,u,E,B,s,F=[],A=[];c=0;for(d=a.faceVertexUvs.length;c<d;c++)A[c]=[];c=0;for(d=a.faces.length;c<d;c++)if(e=a.faces[c],e instanceof THREE.Face3)if(f=e.a,g=e.b,h=e.c,j=a.vertices[f],l=a.vertices[g],p=a.vertices[h],
+r=j.distanceTo(l),q=l.distanceTo(p),n=j.distanceTo(p),r>b||q>b||n>b){i=a.vertices.length;B=e.clone();s=e.clone();r>=q&&r>=n?(j=j.clone(),j.lerpSelf(l,0.5),B.a=f,B.b=i,B.c=h,s.a=i,s.b=g,s.c=h,3===e.vertexNormals.length&&(f=e.vertexNormals[0].clone(),f.lerpSelf(e.vertexNormals[1],0.5),B.vertexNormals[1].copy(f),s.vertexNormals[0].copy(f)),3===e.vertexColors.length&&(f=e.vertexColors[0].clone(),f.lerpSelf(e.vertexColors[1],0.5),B.vertexColors[1].copy(f),s.vertexColors[0].copy(f)),e=0):q>=r&&q>=n?(j=
+l.clone(),j.lerpSelf(p,0.5),B.a=f,B.b=g,B.c=i,s.a=i,s.b=h,s.c=f,3===e.vertexNormals.length&&(f=e.vertexNormals[1].clone(),f.lerpSelf(e.vertexNormals[2],0.5),B.vertexNormals[2].copy(f),s.vertexNormals[0].copy(f),s.vertexNormals[1].copy(e.vertexNormals[2]),s.vertexNormals[2].copy(e.vertexNormals[0])),3===e.vertexColors.length&&(f=e.vertexColors[1].clone(),f.lerpSelf(e.vertexColors[2],0.5),B.vertexColors[2].copy(f),s.vertexColors[0].copy(f),s.vertexColors[1].copy(e.vertexColors[2]),s.vertexColors[2].copy(e.vertexColors[0])),
 e=1):(j=j.clone(),j.lerpSelf(p,0.5),B.a=f,B.b=g,B.c=i,s.a=i,s.b=g,s.c=h,3===e.vertexNormals.length&&(f=e.vertexNormals[0].clone(),f.lerpSelf(e.vertexNormals[2],0.5),B.vertexNormals[2].copy(f),s.vertexNormals[0].copy(f)),3===e.vertexColors.length&&(f=e.vertexColors[0].clone(),f.lerpSelf(e.vertexColors[2],0.5),B.vertexColors[2].copy(f),s.vertexColors[0].copy(f)),e=2);F.push(B,s);a.vertices.push(j);f=0;for(g=a.faceVertexUvs.length;f<g;f++)a.faceVertexUvs[f].length&&(j=a.faceVertexUvs[f][c],s=j[0],h=
 j[1],B=j[2],0===e?(l=s.clone(),l.lerpSelf(h,0.5),j=[s.clone(),l.clone(),B.clone()],h=[l.clone(),h.clone(),B.clone()]):1===e?(l=h.clone(),l.lerpSelf(B,0.5),j=[s.clone(),h.clone(),l.clone()],h=[l.clone(),B.clone(),s.clone()]):(l=s.clone(),l.lerpSelf(B,0.5),j=[s.clone(),h.clone(),l.clone()],h=[l.clone(),h.clone(),B.clone()]),A[f].push(j,h))}else{F.push(e);f=0;for(g=a.faceVertexUvs.length;f<g;f++)A[f].push(a.faceVertexUvs[f][c])}else if(f=e.a,g=e.b,h=e.c,i=e.d,j=a.vertices[f],l=a.vertices[g],p=a.vertices[h],
 n=a.vertices[i],r=j.distanceTo(l),q=l.distanceTo(p),m=p.distanceTo(n),t=j.distanceTo(n),r>b||q>b||m>b||t>b){u=a.vertices.length;E=a.vertices.length+1;B=e.clone();s=e.clone();r>=q&&r>=m&&r>=t||m>=q&&m>=r&&m>=t?(r=j.clone(),r.lerpSelf(l,0.5),l=p.clone(),l.lerpSelf(n,0.5),B.a=f,B.b=u,B.c=E,B.d=i,s.a=u,s.b=g,s.c=h,s.d=E,4===e.vertexNormals.length&&(f=e.vertexNormals[0].clone(),f.lerpSelf(e.vertexNormals[1],0.5),g=e.vertexNormals[2].clone(),g.lerpSelf(e.vertexNormals[3],0.5),B.vertexNormals[1].copy(f),
 B.vertexNormals[2].copy(g),s.vertexNormals[0].copy(f),s.vertexNormals[3].copy(g)),4===e.vertexColors.length&&(f=e.vertexColors[0].clone(),f.lerpSelf(e.vertexColors[1],0.5),g=e.vertexColors[2].clone(),g.lerpSelf(e.vertexColors[3],0.5),B.vertexColors[1].copy(f),B.vertexColors[2].copy(g),s.vertexColors[0].copy(f),s.vertexColors[3].copy(g)),e=0):(r=l.clone(),r.lerpSelf(p,0.5),l=n.clone(),l.lerpSelf(j,0.5),B.a=f,B.b=g,B.c=u,B.d=E,s.a=E,s.b=u,s.c=h,s.d=i,4===e.vertexNormals.length&&(f=e.vertexNormals[1].clone(),
 f.lerpSelf(e.vertexNormals[2],0.5),g=e.vertexNormals[3].clone(),g.lerpSelf(e.vertexNormals[0],0.5),B.vertexNormals[2].copy(f),B.vertexNormals[3].copy(g),s.vertexNormals[0].copy(g),s.vertexNormals[1].copy(f)),4===e.vertexColors.length&&(f=e.vertexColors[1].clone(),f.lerpSelf(e.vertexColors[2],0.5),g=e.vertexColors[3].clone(),g.lerpSelf(e.vertexColors[0],0.5),B.vertexColors[2].copy(f),B.vertexColors[3].copy(g),s.vertexColors[0].copy(g),s.vertexColors[1].copy(f)),e=1);F.push(B,s);a.vertices.push(r,l);
 f=0;for(g=a.faceVertexUvs.length;f<g;f++)a.faceVertexUvs[f].length&&(j=a.faceVertexUvs[f][c],s=j[0],h=j[1],B=j[2],j=j[3],0===e?(l=s.clone(),l.lerpSelf(h,0.5),p=B.clone(),p.lerpSelf(j,0.5),s=[s.clone(),l.clone(),p.clone(),j.clone()],h=[l.clone(),h.clone(),B.clone(),p.clone()]):(l=h.clone(),l.lerpSelf(B,0.5),p=j.clone(),p.lerpSelf(s,0.5),s=[s.clone(),h.clone(),l.clone(),p.clone()],h=[p.clone(),l.clone(),B.clone(),j.clone()]),A[f].push(s,h))}else{F.push(e);f=0;for(g=a.faceVertexUvs.length;f<g;f++)A[f].push(a.faceVertexUvs[f][c])}a.faces=
-F;a.faceVertexUvs=A}};THREE.GeometryUtils.random=THREE.Math.random16;THREE.GeometryUtils.__v1=new THREE.Vector3;THREE.ImageUtils={crossOrigin:"anonymous",loadTexture:function(a,b,c,d){var e=new Image,f=new THREE.Texture(e,b),b=new THREE.ImageLoader;b.addEventListener("load",function(a){f.image=a.content;f.needsUpdate=!0;c&&c(f)});b.addEventListener("error",function(a){d&&d(a.message)});b.crossOrigin=this.crossOrigin;b.load(a,e);f.sourceFile=a;return f},loadCompressedTexture:function(a,b,c,d){var e=new THREE.CompressedTexture;e.mapping=b;var f=new XMLHttpRequest;f.onload=function(){var a=THREE.ImageUtils.parseDDS(f.response,
+F;a.faceVertexUvs=A}};THREE.GeometryUtils.random=THREE.Math.random16;THREE.GeometryUtils.__v1=new THREE.Vector3;THREE.GeometryUtils.__v2=new THREE.Vector3;THREE.ImageUtils={crossOrigin:"anonymous",loadTexture:function(a,b,c,d){var e=new Image,f=new THREE.Texture(e,b),b=new THREE.ImageLoader;b.addEventListener("load",function(a){f.image=a.content;f.needsUpdate=!0;c&&c(f)});b.addEventListener("error",function(a){d&&d(a.message)});b.crossOrigin=this.crossOrigin;b.load(a,e);f.sourceFile=a;return f},loadCompressedTexture:function(a,b,c,d){var e=new THREE.CompressedTexture;e.mapping=b;var f=new XMLHttpRequest;f.onload=function(){var a=THREE.ImageUtils.parseDDS(f.response,
 !0);e.format=a.format;e.mipmaps=a.mipmaps;e.image.width=a.width;e.image.height=a.height;e.generateMipmaps=!1;e.needsUpdate=!0;c&&c(e)};f.onerror=d;f.open("GET",a,!0);f.responseType="arraybuffer";f.send(null);return e},loadTextureCube:function(a,b,c,d){var e=[];e.loadCount=0;var f=new THREE.Texture;f.image=e;void 0!==b&&(f.mapping=b);f.flipY=!1;for(var b=0,g=a.length;b<g;++b){var h=new Image;e[b]=h;h.onload=function(){e.loadCount+=1;6===e.loadCount&&(f.needsUpdate=!0,c&&c(f))};h.onerror=d;h.crossOrigin=
 this.crossOrigin;h.src=a[b]}return f},loadCompressedTextureCube:function(a,b,c,d){var e=[];e.loadCount=0;var f=new THREE.CompressedTexture;f.image=e;void 0!==b&&(f.mapping=b);f.flipY=!1;f.generateMipmaps=!1;b=function(a,b){return function(){var d=THREE.ImageUtils.parseDDS(a.response,!0);b.format=d.format;b.mipmaps=d.mipmaps;b.width=d.width;b.height=d.height;e.loadCount+=1;6===e.loadCount&&(f.format=d.format,f.needsUpdate=!0,c&&c(f))}};if(a instanceof Array)for(var g=0,h=a.length;g<h;++g){var i={};
 e[g]=i;var j=new XMLHttpRequest;j.onload=b(j,i);j.onerror=d;i=a[g];j.open("GET",i,!0);j.responseType="arraybuffer";j.send(null)}else j=new XMLHttpRequest,j.onload=function(){var a=THREE.ImageUtils.parseDDS(j.response,!0);if(a.isCubemap){for(var b=a.mipmaps.length/a.mipmapCount,d=0;d<b;d++){e[d]={mipmaps:[]};for(var g=0;g<a.mipmapCount;g++)e[d].mipmaps.push(a.mipmaps[d*a.mipmapCount+g]),e[d].format=a.format,e[d].width=a.width,e[d].height=a.height}f.format=a.format;f.needsUpdate=!0;c&&c(f)}},j.onerror=

+ 9 - 15
src/extras/GeometryUtils.js

@@ -354,26 +354,19 @@ THREE.GeometryUtils = {
 
 	},
 
-	// Get triangle area (by Heron's formula)
-	// 	http://en.wikipedia.org/wiki/Heron%27s_formula
+	// Get triangle area (half of parallelogram)
+	//	http://mathworld.wolfram.com/TriangleArea.html
 
 	triangleArea: function ( vectorA, vectorB, vectorC ) {
 
-		var s, a, b, c,
-			tmp = THREE.GeometryUtils.__v1;
-
-		tmp.sub( vectorA, vectorB );
-		a = tmp.length();
-
-		tmp.sub( vectorA, vectorC );
-		b = tmp.length();
-
-		tmp.sub( vectorB, vectorC );
-		c = tmp.length();
+		var tmp1 = THREE.GeometryUtils.__v1,
+			tmp2 = THREE.GeometryUtils.__v2;
 
-		s = 0.5 * ( a + b + c );
+		tmp1.sub( vectorB, vectorA );
+		tmp2.sub( vectorC, vectorA );
+		tmp1.crossSelf( tmp2 );
 
-		return Math.sqrt( s * ( s - a ) * ( s - b ) * ( s - c ) );
+		return 0.5 * tmp1.length();
 
 	},
 
@@ -1045,3 +1038,4 @@ THREE.GeometryUtils = {
 THREE.GeometryUtils.random = THREE.Math.random16;
 
 THREE.GeometryUtils.__v1 = new THREE.Vector3();
+THREE.GeometryUtils.__v2 = new THREE.Vector3();